Add json repair. And fix adjust prompts to work with Sonnet#770
Add json repair. And fix adjust prompts to work with Sonnet#770
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Other AI code review bot(s) detectedCodeRabbit 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 failedThe pull request is closed. WalkthroughAdds Changes
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis 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.jsonapps/web/utils/ai/choose-rule/ai-choose-rule.tsapps/web/utils/ai/rule/prompt-to-rules.tsapps/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.jsonapps/web/utils/ai/choose-rule/ai-choose-rule.tsapps/web/utils/ai/rule/prompt-to-rules.tsapps/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.tsapps/web/utils/ai/rule/prompt-to-rules.tsapps/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.tsapps/web/utils/ai/rule/prompt-to-rules.tsapps/web/utils/llms/index.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/logging.mdc)
**/*.{ts,tsx}: UsecreateScopedLoggerfor logging in backend TypeScript files
Typically add the logger initialization at the top of the file when usingcreateScopedLogger
Only use.with()on a logger instance within a specific function, not for a global loggerImport 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.tsapps/web/utils/ai/rule/prompt-to-rules.tsapps/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.tsapps/web/utils/ai/rule/prompt-to-rules.tsapps/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.tsapps/web/utils/ai/rule/prompt-to-rules.tsapps/web/utils/llms/index.ts
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
**/*.{js,jsx,ts,tsx}: Don't useelements 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.tsapps/web/utils/ai/rule/prompt-to-rules.tsapps/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.tsapps/web/utils/ai/rule/prompt-to-rules.tsapps/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.tsapps/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.tsapps/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.tsapps/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.
There was a problem hiding this comment.
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: |
There was a problem hiding this 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.
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 "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:
+
+{
</file context>
Summary by CodeRabbit
New Features
Bug Fixes
Chores