Skip to content

Comments

Add json repair. And fix adjust prompts to work with Sonnet#770

Merged
elie222 merged 4 commits intomainfrom
fix/prompt-for-sonnet
Sep 12, 2025
Merged

Add json repair. And fix adjust prompts to work with Sonnet#770
elie222 merged 4 commits intomainfrom
fix/prompt-for-sonnet

Conversation

@elie222
Copy link
Owner

@elie222 elie222 commented Sep 12, 2025

Summary by CodeRabbit

  • New Features

    • Automatic repair of malformed AI JSON responses for smoother interactions.
  • Bug Fixes

    • Prompts tightened to require JSON output, reducing parsing errors and misformatted results.
  • Chores

    • Added JSON-repair utility dependency.
    • Updated development tooling versions and bumped app version.

@vercel
Copy link

vercel bot commented Sep 12, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
inbox-zero Ready Ready Preview Sep 12, 2025 0:13am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 12, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Caution

Review failed

The pull request is closed.

Walkthrough

Adds jsonrepair dependency, tightens AI system prompts to require explicit JSON output examples, and updates LLM utilities to warn when prompts lack JSON hints and to attempt repairing malformed JSON responses via an experimental repair callback; also bumps version.

Changes

Cohort / File(s) Summary of changes
Dependency & metadata
apps/web/package.json, version.txt
Added dependency jsonrepair@3.13.0; changed devDependency prisma from 6.15.06.6.0; bumped version.txt v2.9.17 → v2.9.18.
Prompt JSON format tightening
apps/web/utils/ai/choose-rule/ai-choose-rule.ts, apps/web/utils/ai/rule/prompt-to-rules.ts
System prompts updated to explicitly require JSON responses and include example JSON blocks; examples restructured to a top-level object with a rules array. Runtime parsing/validation unchanged.
LLM repair & logging
apps/web/utils/llms/index.ts
Imported jsonrepair; added a runtime warning when system/prompt lacks JSON hints; passed an experimental_repairText callback into generateObject that repairs returned text using jsonrepair and logs repair actions.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Caller
  participant Factory as createGenerateObject
  participant LLM
  participant Repair as jsonrepair

  Caller->>Factory: request generateObject(system, prompt, schema)
  Note over Factory: check system/prompt for JSON hint\nwarn if missing
  Factory->>LLM: invoke generate (with experimental_repairText callback)
  LLM-->>Factory: text (raw response)
  alt text not valid JSON
    Factory->>Repair: experimental_repairText({ text })
    Repair-->>Factory: repairedText
    Note over Factory: log original -> repaired
    Factory->>Caller: repairedText (then parse/validate)
  else text valid JSON
    Factory->>Caller: text (parse/validate)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

A rabbit nudges prompts to form,
I wrap your output safe and warm.
When JSON breaks, I mend the seam—
jsonrepair hums, a quiet gleam.
Hops of code and tiny dream 🐇✨


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0b9bba2 and fad62ce.

📒 Files selected for processing (3)
  • apps/web/utils/ai/rule/prompt-to-rules.ts (4 hunks)
  • apps/web/utils/llms/index.ts (2 hunks)
  • version.txt (1 hunks)
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/prompt-for-sonnet

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
apps/web/utils/ai/choose-rule/ai-choose-rule.ts (1)

67-74: Tell the model to return only raw JSON (no fences) to reduce repair needs.

Explicitly forbid markdown/code fences; this lowers parse/repair churn and Sonnet tends to include ```json by default.

-Respond with a valid JSON object:
+Respond with a valid JSON object. Return only the JSON without code fences, prefixes, or trailing text:
 
 Example response format:
 {
   "reason": "This email is a newsletter subscription",
   "ruleName": "Newsletter",
   "noMatchFound": false
 }
apps/web/utils/llms/index.ts (1)

138-145: Broaden the JSON guard and avoid false negatives.

Current check is case-sensitive and warns even when a schema is provided (schema already enforces structure). Make it case-insensitive and only warn when neither system nor prompt hints at JSON.

-      if (
-        !options.system?.includes("JSON") &&
-        typeof options.prompt === "string" &&
-        !options.prompt?.includes("JSON")
-      ) {
-        logger.warn("Missing JSON in prompt", { label });
-      }
+      if (typeof options.prompt === "string") {
+        const sys = options.system?.toLowerCase() ?? "";
+        const prm = options.prompt.toLowerCase();
+        if (!sys.includes("json") && !prm.includes("json")) {
+          logger.warn("Missing JSON hint in prompt/system", { label });
+        }
+      }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff3db2c and 0b9bba2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • apps/web/package.json (2 hunks)
  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts (1 hunks)
  • apps/web/utils/ai/rule/prompt-to-rules.ts (1 hunks)
  • apps/web/utils/llms/index.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
!{.cursor/rules/*.mdc}

📄 CodeRabbit inference engine (.cursor/rules/cursor-rules.mdc)

Never place rule files in the project root, in subdirectories outside .cursor/rules, or in any other location

Files:

  • apps/web/package.json
  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
  • apps/web/utils/llms/index.ts
!pages/_document.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

!pages/_document.{js,jsx,ts,tsx}: Don't import next/document outside of pages/_document.jsx in Next.js projects.
Don't import next/document outside of pages/_document.jsx in Next.js projects.

Files:

  • apps/web/package.json
  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
  • apps/web/utils/llms/index.ts
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

apps/web/**/*.{ts,tsx}: Use TypeScript with strict null checks
Path aliases: Use @/ for imports from project root
Use proper error handling with try/catch blocks
Format code with Prettier
Leverage TypeScript inference for better DX

Files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
  • apps/web/utils/llms/index.ts
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/form-handling.mdc)

**/*.ts: The same validation should be done in the server action too
Define validation schemas using Zod

Files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
  • apps/web/utils/llms/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/logging.mdc)

**/*.{ts,tsx}: Use createScopedLogger for logging in backend TypeScript files
Typically add the logger initialization at the top of the file when using createScopedLogger
Only use .with() on a logger instance within a specific function, not for a global logger

Import Prisma in the project using import prisma from "@/utils/prisma";

**/*.{ts,tsx}: Don't use TypeScript enums.
Don't use TypeScript const enum.
Don't use the TypeScript directive @ts-ignore.
Don't use primitive type aliases or misleading types.
Don't use empty type parameters in type aliases and interfaces.
Don't use any or unknown as type constraints.
Don't use implicit any type on variable declarations.
Don't let variables evolve into any type through reassignments.
Don't use non-null assertions with the ! postfix operator.
Don't misuse the non-null assertion operator (!) in TypeScript files.
Don't use user-defined types.
Use as const instead of literal types and type annotations.
Use export type for types.
Use import type for types.
Don't declare empty interfaces.
Don't merge interfaces and classes unsafely.
Don't use overload signatures that aren't next to each other.
Use the namespace keyword instead of the module keyword to declare TypeScript namespaces.
Don't use TypeScript namespaces.
Don't export imported variables.
Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions.
Don't use parameter properties in class constructors.
Use either T[] or Array consistently.
Initialize each enum member value explicitly.
Make sure all enum members are literal values.

Files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
  • apps/web/utils/llms/index.ts
apps/web/utils/**

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

Create utility functions in utils/ folder for reusable logic

Files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
  • apps/web/utils/llms/index.ts
apps/web/utils/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

apps/web/utils/**/*.ts: Use lodash utilities for common operations (arrays, objects, strings)
Import specific lodash functions to minimize bundle size

Files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
  • apps/web/utils/llms/index.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{js,jsx,ts,tsx}: Don't use elements in Next.js projects.
Don't use elements in Next.js projects.
Don't use namespace imports.
Don't access namespace imports dynamically.
Don't use global eval().
Don't use console.
Don't use debugger.
Don't use var.
Don't use with statements in non-strict contexts.
Don't use the arguments object.
Don't use consecutive spaces in regular expression literals.
Don't use the comma operator.
Don't use unnecessary boolean casts.
Don't use unnecessary callbacks with flatMap.
Use for...of statements instead of Array.forEach.
Don't create classes that only have static members (like a static namespace).
Don't use this and super in static contexts.
Don't use unnecessary catch clauses.
Don't use unnecessary constructors.
Don't use unnecessary continue statements.
Don't export empty modules that don't change anything.
Don't use unnecessary escape sequences in regular expression literals.
Don't use unnecessary labels.
Don't use unnecessary nested block statements.
Don't rename imports, exports, and destructured assignments to the same name.
Don't use unnecessary string or template literal concatenation.
Don't use String.raw in template literals when there are no escape sequences.
Don't use useless case statements in switch statements.
Don't use ternary operators when simpler alternatives exist.
Don't use useless this aliasing.
Don't initialize variables to undefined.
Don't use the void operators (they're not familiar).
Use arrow functions instead of function expressions.
Use Date.now() to get milliseconds since the Unix Epoch.
Use .flatMap() instead of map().flat() when possible.
Use literal property access instead of computed property access.
Don't use parseInt() or Number.parseInt() when binary, octal, or hexadecimal literals work.
Use concise optional chaining instead of chained logical expressions.
Use regular expression literals instead of the RegExp constructor when possible.
Don't use number literal object member names th...

Files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
  • apps/web/utils/llms/index.ts
apps/web/utils/{ai,llms}/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/llm.mdc)

apps/web/utils/{ai,llms}/**/*.ts: Place LLM-related implementation code under apps/web/utils/ai or apps/web/utils/llms
Keep system and user prompts separate; system defines role/task, user contains data/context
Always validate LLM responses with a specific Zod schema
Use descriptive scoped loggers per feature and log inputs/outputs with appropriate levels and context
Implement early returns for invalid inputs and use proper error types with logging
Add fallbacks for AI failures and include retry logic for transient errors using withRetry
Format prompts with XML-like tags; remove excessive whitespace; truncate overly long inputs; keep formatting consistent
Use TypeScript types for all parameters/returns and define interfaces for complex IO structures
Keep related AI functions co-located; extract shared logic into utilities; document complex AI logic with clear comments
Call LLMs via createGenerateObject; pass system, prompt, and a Zod schema; return the validated result.object
Derive model options using getModel(...) and pass them to createGenerateObject and the generate call

Files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
  • apps/web/utils/llms/index.ts
apps/web/utils/llms/index.ts

📄 CodeRabbit inference engine (.cursor/rules/llm.mdc)

Keep core LLM functionality centralized in apps/web/utils/llms/index.ts

Files:

  • apps/web/utils/llms/index.ts
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-08-17T16:57:25.834Z
Learning: Applies to apps/web/utils/{ai,llms}/**/*.ts : Format prompts with XML-like tags; remove excessive whitespace; truncate overly long inputs; keep formatting consistent
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-08-17T16:57:25.834Z
Learning: Applies to apps/web/utils/{ai,llms}/**/*.ts : Call LLMs via createGenerateObject; pass system, prompt, and a Zod schema; return the validated result.object
📚 Learning: 2025-06-23T12:26:53.882Z
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/prisma.mdc:0-0
Timestamp: 2025-06-23T12:26:53.882Z
Learning: In this project, Prisma should be imported using 'import prisma from "@/utils/prisma";' in TypeScript files.

Applied to files:

  • apps/web/package.json
📚 Learning: 2025-08-17T16:57:25.834Z
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-08-17T16:57:25.834Z
Learning: Applies to apps/web/utils/{ai,llms}/**/*.ts : Format prompts with XML-like tags; remove excessive whitespace; truncate overly long inputs; keep formatting consistent

Applied to files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
📚 Learning: 2025-08-17T16:57:25.834Z
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-08-17T16:57:25.834Z
Learning: Applies to apps/web/utils/{ai,llms}/**/*.ts : Call LLMs via createGenerateObject; pass system, prompt, and a Zod schema; return the validated result.object

Applied to files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/llms/index.ts
📚 Learning: 2025-08-17T16:57:25.834Z
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-08-17T16:57:25.834Z
Learning: Applies to apps/web/utils/{ai,llms}/**/*.ts : Keep system and user prompts separate; system defines role/task, user contains data/context

Applied to files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
  • apps/web/utils/ai/rule/prompt-to-rules.ts
📚 Learning: 2025-08-17T16:57:25.834Z
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-08-17T16:57:25.834Z
Learning: Applies to apps/web/utils/{ai,llms}/**/*.ts : Always validate LLM responses with a specific Zod schema

Applied to files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
📚 Learning: 2025-08-17T16:57:25.834Z
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-08-17T16:57:25.834Z
Learning: Applies to apps/web/utils/{ai,llms}/**/*.ts : Keep related AI functions co-located; extract shared logic into utilities; document complex AI logic with clear comments

Applied to files:

  • apps/web/utils/ai/choose-rule/ai-choose-rule.ts
📚 Learning: 2025-08-17T16:57:25.834Z
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-08-17T16:57:25.834Z
Learning: Applies to apps/web/utils/{ai,llms}/**/*.ts : Derive model options using getModel(...) and pass them to createGenerateObject and the generate call

Applied to files:

  • apps/web/utils/llms/index.ts
🧬 Code graph analysis (1)
apps/web/utils/llms/index.ts (1)
apps/web/app/api/outlook/webhook/logger.ts (1)
  • logger (3-3)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🔇 Additional comments (3)
apps/web/package.json (2)

114-114: jsonrepair addition looks correct (ESM named import).

Library v3.x exposes a named export; your import style { jsonrepair } in utils/llms/index.ts matches that. No action needed.


181-181: Prisma CLI aligned with @prisma/client (both 6.6.0).

Good version sync to avoid engine mismatch during generate/migrate.

apps/web/utils/llms/index.ts (1)

15-15: Import form matches jsonrepair v3.x.

{ jsonrepair } is the correct named import for v3+. Good.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 5 files

Prompt for AI agents (all 4 issues)

Understand the root cause of the following 4 issues and fix them.


<file name="apps/web/utils/llms/index.ts">

<violation number="1" location="apps/web/utils/llms/index.ts:149">
Logging potentially sensitive model output at info level; prefer trace/debug and include label for correlation. Also avoid magic number; reuse MAX_LOG_LENGTH.</violation>

<violation number="2" location="apps/web/utils/llms/index.ts:151">
jsonrepair may throw on invalid or unrepairable input; wrap this call in try/catch and return null on failure to prevent the request from crashing and allow the SDK to handle parse errors</violation>

<violation number="3" location="apps/web/utils/llms/index.ts:153">
Logging potentially sensitive repaired output at info level; prefer trace/debug and include label. Also avoid magic number; reuse MAX_LOG_LENGTH.</violation>
</file>

<file name="apps/web/utils/ai/rule/prompt-to-rules.ts">

<violation number="1" location="apps/web/utils/ai/rule/prompt-to-rules.ts:85">
Instruction to return an object with a top-level rules array conflicts with examples that show a bare array, creating ambiguity for the model.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

In most cases, you should use the "aiInstructions" and sometimes you will use other fields in addition.
If a rule can be handled fully with static conditions, do so, but this is rarely possible.

IMPORTANT: You must return JSON object in this format:
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instruction to return an object with a top-level rules array conflicts with examples that show a bare array, creating ambiguity for the model.

Prompt for AI agents
Address the following comment on apps/web/utils/ai/rule/prompt-to-rules.ts at line 85:

<comment>Instruction to return an object with a top-level rules array conflicts with examples that show a bare array, creating ambiguity for the model.</comment>

<file context>
@@ -82,6 +82,16 @@ You can use multiple conditions in a rule, but aim for simplicity.
 In most cases, you should use the &quot;aiInstructions&quot; and sometimes you will use other fields in addition.
 If a rule can be handled fully with static conditions, do so, but this is rarely possible.
 
+IMPORTANT: You must return JSON object in this format:
+
+{
</file context>

@elie222 elie222 merged commit 0865f4d into main Sep 12, 2025
11 of 12 checks passed
@elie222 elie222 deleted the fix/prompt-for-sonnet branch December 18, 2025 23:06
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