-
Notifications
You must be signed in to change notification settings - Fork 1
Updated biomeJS formatter and linter and fix lint issues #269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughStandardizes formatting/quoting and migrates lint/format tooling to Biome across the repo; introduces several type-only imports and prompt expansions. Functional edits include a CopyPageDropdown refactor, TypingAnimation start-on-view behavior, source transformer change, and expanded doc‑QA prompts/fallbacks. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant UI as CopyPageDropdown
participant Store as localStorage
participant API as /api/page-content
participant Clipboard as navigator.clipboard
Note over UI: Initialization reads preferred action
User->>UI: Click primary action
UI->>Store: Read preferredAction
alt View Markdown
UI->>API: fetchPageContent(path)
API-->>UI: {content,...}
alt open new tab OK
UI->>User: opens blob URL
else blocked
UI->>User: triggers download fallback
end
else Copy Markdown
UI->>API: fetchPageContent(path)
API-->>UI: {content,...}
UI->>Clipboard: writeText(markdown)
end
UI->>Store: Save preferredAction (if changed)
sequenceDiagram
autonumber
actor User
participant UI as Search UI
participant API as /api/rag-search
participant Agent as doc‑qa service
participant VS as Vector Store
participant LLM as Model (gpt-4o-mini)
User->>UI: Enter query
UI->>API: GET ?q=...
API->>Agent: answerQuestion(prompt)
Agent->>Agent: rephraseVaguePrompt(prompt)
Agent->>VS: vector search
VS-->>Agent: relevant chunks
Agent->>LLM: generateObject(systemPrompt + <DOCS>...)
LLM-->>Agent: answer + docs
Agent-->>API: {aiAnswer, documents}
API-->>UI: results
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
Deploying with
|
Status | Name | Latest Commit | Preview URL | Updated (UTC) |
---|---|---|---|---|
✅ Deployment successful! View logs |
docs | a71da1a | Commit Preview URL Branch Preview URL |
Aug 25 2025, 08:32 PM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 16
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
components/NavButton.tsx (1)
21-24
: Security: default rel for target="_blank"Opening in a new tab without
rel="noopener noreferrer"
can exposewindow.opener
and enable reverse tabnabbing. Provide a safe default when target is_blank
.export function NavButton({ href, children, className, noBorder = false, target, rel, }: NavButtonProps) { return ( <a href={href} - target={target} - rel={rel} + target={target} + rel={target === '_blank' ? (rel ?? 'noopener noreferrer') : rel} className={cn(components/XButton.tsx (1)
14-23
: Ensure accessible names and proper prop forwarding inNavButton
The X button link currently:
- Renders an
<svg>
with botharia-hidden="true"
andaria-label="X"
. When hidden, its label is ignored—so remove thearia-label
(and<title>
) from the SVG to keep it purely decorative.- When
follow
isfalse
, there’s no visible text in the link, so screen readers won’t announce its purpose.Since
NavButton
already accepts and forwardstarget
andrel
to the underlying<a>
(as seen incomponents/NavButton.tsx
, lines 5–13), but does not accept arbitraryaria-*
props, we should:
- Add an
ariaLabel?: string
(or'aria-label'?: string
) prop toNavButtonProps
and forward it to the<a>
element.- Use that prop in
XButton
to give the link an explicit accessible name.- Add
target="_blank"
andrel="noopener noreferrer"
for safety when linking externally.Example changes:
--- a/components/NavButton.tsx +++ b/components/NavButton.tsx @@ export interface NavButtonProps { rel?: string; + 'aria-label'?: string; } export function NavButton({ href, children, className, noBorder = false, target, rel, + 'aria-label': ariaLabel, }: NavButtonProps) { return ( <a href={href} target={target} rel={rel} + aria-label={ariaLabel} className={cn( 'inline-flex flex-row items-center gap-2 w-auto no-underline', noBorder ? 'border-none' : 'hover:border-cyan-700 hover:dark:border-cyan-900 border rounded-full border-gray-200 dark:border-gray-800 px-2.5 h-9', className )} > {children} </a> ); }--- a/components/XButton.tsx +++ b/components/XButton.tsx @@ <NavButton href="https://x.com/agentuity" noBorder={noBorder} - className={cn('align-bottom', className)} + className={cn('align-bottom', className)} + aria-label={follow ? 'Follow us on X' : 'Agentuity on X'} + target="_blank" + rel="noopener noreferrer" > - {follow && <span>Follow us on</span>} - <svg - aria-hidden="true" - aria-label="X" + {follow && <span>Follow us on</span>} + <svg + aria-hidden="true" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" className="underline" > - <title>X</title> + {/* decorative icon */} <path d="M 18.242188 2.25 L 21.554688 2.25 L 14.324219 10.507812 ... Z" /> </svg> </NavButton>Also apply the same
aria-label
,target
,rel
, and SVG cleanup at lines 29–31.components/TypingAnimation.tsx (1)
41-51
: Prevent setState on unmounted component: clear the timeout created inside IntersectionObserverWhen
startOnView
is true, thesetTimeout
created in the observer callback isn’t cleared on unmount. If the component unmounts before the timeout fires, React may warn about state updates on an unmounted component. Capture and clear the timeout in the effect cleanup.useEffect(() => { if (!startOnView) { const startTimeout = setTimeout(() => { setStarted(true); }, delay); return () => clearTimeout(startTimeout); } - const observer = new IntersectionObserver( + let viewStartTimeout: ReturnType<typeof setTimeout> | null = null; + const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { - setTimeout(() => { - setStarted(true); - }, delay); + viewStartTimeout = setTimeout(() => { + setStarted(true); + }, delay); observer.disconnect(); } }, { threshold: 0.1 } ); @@ - return () => observer.disconnect(); + return () => { + if (viewStartTimeout) clearTimeout(viewStartTimeout); + observer.disconnect(); + }; }, [delay, startOnView]);Also applies to: 57-58
agent-docs/src/agents/doc-processing/keyword-extraction.ts (1)
37-50
: Harden the prompt: explicitly forbid code fences and extra text in the response.LLMs frequently wrap JSON in ```json fences or prepend explanations, which breaks strict parsers. Make the constraint explicit to reduce parse failures.
-Return the keywords as a JSON array in the following format: +Return the keywords as a JSON array in the following format. +Important: Return only the JSON object, with no surrounding code fences, no leading/trailing text, and no explanations: { "keywords": ["keyword1", "keyword2", ...] }
id: crypto.randomUUID(), | ||
chunkIndex: idx, | ||
totalChunks: chunks.length, | ||
contentType: chunk.metadata.contentType, | ||
heading: currentHeading, | ||
text: chunk.pageContent, | ||
title: frontmatter.title, | ||
description: frontmatter.description, | ||
createdAt: new Date().toISOString(), | ||
}; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid relying on global crypto
; import Node’s randomUUID
for portability and correct typings.
crypto
may not be available as a global depending on the TS lib config (no DOM) and runtime. Importing from crypto
avoids compile/runtime surprises.
@@
-import type { Document } from 'langchain/document';
+import type { Document } from 'langchain/document';
+import { randomUUID } from 'crypto';
@@
- id: crypto.randomUUID(),
+ id: randomUUID(),
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
id: crypto.randomUUID(), | |
chunkIndex: idx, | |
totalChunks: chunks.length, | |
contentType: chunk.metadata.contentType, | |
heading: currentHeading, | |
text: chunk.pageContent, | |
title: frontmatter.title, | |
description: frontmatter.description, | |
createdAt: new Date().toISOString(), | |
}; | |
}); | |
// at top of agent-docs/src/agents/doc-processing/chunk-mdx.ts | |
import type { Document } from 'langchain/document'; | |
import { randomUUID } from 'crypto'; | |
// …later, in the mapping over chunks: | |
const processed = chunks.map((chunk, idx) => { | |
return { | |
id: randomUUID(), | |
chunkIndex: idx, | |
totalChunks: chunks.length, | |
contentType: chunk.metadata.contentType, | |
heading: currentHeading, | |
text: chunk.pageContent, | |
title: frontmatter.title, | |
description: frontmatter.description, | |
createdAt: new Date().toISOString(), | |
}; | |
}); |
🤖 Prompt for AI Agents
In agent-docs/src/agents/doc-processing/chunk-mdx.ts around lines 155-165, the
code uses the global crypto.randomUUID(); replace this with an explicit import
from Node's crypto module: add "import { randomUUID } from 'crypto';" at the top
of the file (or combined into existing imports) and change crypto.randomUUID()
to randomUUID(); ensure TypeScript types compile by having the Node lib
available (or adjust tsconfig if necessary) so the module import is used
consistently instead of the global.
export async function processDoc( | ||
docContent: string | ||
): Promise<VectorUpsertParams[]> { | ||
const chunks = await chunkAndEnrichDoc(docContent); | ||
const vectors = await createVectorEmbedding(chunks); | ||
return vectors; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add structured error handling and logging per agent-docs guidelines
Wrap the top-level orchestration in a try/catch to log contextual errors before rethrowing. This aligns with the coding guidelines for agent-docs/src/agents/**
.
-export async function processDoc(
- docContent: string
-): Promise<VectorUpsertParams[]> {
- const chunks = await chunkAndEnrichDoc(docContent);
- const vectors = await createVectorEmbedding(chunks);
- return vectors;
-}
+export async function processDoc(
+ docContent: string
+): Promise<VectorUpsertParams[]> {
+ try {
+ const chunks = await chunkAndEnrichDoc(docContent);
+ const vectors = await createVectorEmbedding(chunks);
+ return vectors;
+ } catch (err) {
+ // TODO: replace console with the project logger
+ // logger.error({ err }, 'processDoc failed');
+ console.error('processDoc failed:', err);
+ throw err;
+ }
+}
If you point me to the logger you use in this package, I can wire it in and open a follow-up PR.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export async function processDoc( | |
docContent: string | |
): Promise<VectorUpsertParams[]> { | |
const chunks = await chunkAndEnrichDoc(docContent); | |
const vectors = await createVectorEmbedding(chunks); | |
return vectors; | |
} | |
export async function processDoc( | |
docContent: string | |
): Promise<VectorUpsertParams[]> { | |
try { | |
const chunks = await chunkAndEnrichDoc(docContent); | |
const vectors = await createVectorEmbedding(chunks); | |
return vectors; | |
} catch (err) { | |
// TODO: replace console with the project logger | |
// logger.error({ err }, 'processDoc failed'); | |
console.error('processDoc failed:', err); | |
throw err; | |
} | |
} |
🤖 Prompt for AI Agents
In agent-docs/src/agents/doc-processing/docs-processor.ts around lines 12 to 18,
the top-level orchestration lacks structured error handling and logging; wrap
the body of processDoc in a try/catch, import and use the package logger (or
accept the logger instance you use in this package) to log a contextual error
message including the doc metadata or a concise context string and the caught
error, then rethrow the error so callers can handle it upstream; ensure the
catch only logs and rethrows (no swallowing) and keep the function return type
unchanged.
const result = await generateText({ | ||
model: openai(model), | ||
prompt, | ||
maxTokens: 150, | ||
temperature: 0.2, | ||
}); | ||
const raw = result.text || ''; | ||
let keywords: string[] = []; | ||
const parsed = JSON.parse(raw); | ||
if (Array.isArray(parsed.keywords)) { | ||
keywords = parsed.keywords | ||
.map((k: string) => k.trim()) | ||
.filter((k: string) => Boolean(k)) | ||
.filter((k: string, i: number, arr: string[]) => arr.indexOf(k) === i) | ||
.slice(0, maxKeywords); | ||
} | ||
logger.info('Extracted keywords: %o', keywords); | ||
return { | ||
keywords, | ||
source: 'llm', | ||
chunkPreview: chunkContent.slice(0, 100), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add robust parsing and fallbacks (code-fence stripping, array/object support, CSV fallback, safe dedupe).
Right now a non-object JSON (e.g., a raw array) or a fenced JSON payload will either throw or silently return an empty list. The JSDoc mentions a CSV fallback, but it isn’t implemented.
- const result = await generateText({
+ const result = await generateText({
model: openai(model),
prompt,
maxTokens: 150,
temperature: 0.2,
});
- const raw = result.text || '';
- let keywords: string[] = [];
- const parsed = JSON.parse(raw);
- if (Array.isArray(parsed.keywords)) {
- keywords = parsed.keywords
- .map((k: string) => k.trim())
- .filter((k: string) => Boolean(k))
- .filter((k: string, i: number, arr: string[]) => arr.indexOf(k) === i)
- .slice(0, maxKeywords);
- }
+ let raw = (result.text || '').trim();
+ // Strip common code fences if present
+ raw = raw.replace(/^\s*```(?:json)?\s*/i, '').replace(/\s*```$/i, '').trim();
+
+ let keywords: string[] = [];
+ try {
+ const parsed = JSON.parse(raw);
+ if (Array.isArray(parsed)) {
+ // Model returned a bare array: ["a","b",...]
+ keywords = parsed as string[];
+ } else if (parsed && Array.isArray((parsed as any).keywords)) {
+ keywords = (parsed as any).keywords as string[];
+ }
+ } catch {
+ // Fallback: parse comma/newline separated values
+ keywords = raw
+ .split(/[\n,]+/g)
+ .map((k) => k.trim())
+ .filter(Boolean);
+ }
+
+ // Normalize, dedupe case-insensitively, and cap
+ const seen = new Set<string>();
+ keywords = keywords
+ .map((k) => k.trim())
+ .filter(Boolean)
+ .filter((k) => {
+ const key = k.toLowerCase();
+ if (seen.has(key)) return false;
+ seen.add(key);
+ return true;
+ })
+ .slice(0, maxKeywords);
+
+ if (keywords.length === 0) {
+ throw new Error('Failed to extract keywords from LLM response');
+ }
logger.info('Extracted keywords: %o', keywords);
return {
keywords,
source: 'llm',
chunkPreview: chunkContent.slice(0, 100),
};
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const result = await generateText({ | |
model: openai(model), | |
prompt, | |
maxTokens: 150, | |
temperature: 0.2, | |
}); | |
const raw = result.text || ''; | |
let keywords: string[] = []; | |
const parsed = JSON.parse(raw); | |
if (Array.isArray(parsed.keywords)) { | |
keywords = parsed.keywords | |
.map((k: string) => k.trim()) | |
.filter((k: string) => Boolean(k)) | |
.filter((k: string, i: number, arr: string[]) => arr.indexOf(k) === i) | |
.slice(0, maxKeywords); | |
} | |
logger.info('Extracted keywords: %o', keywords); | |
return { | |
keywords, | |
source: 'llm', | |
chunkPreview: chunkContent.slice(0, 100), | |
}; | |
const result = await generateText({ | |
model: openai(model), | |
prompt, | |
maxTokens: 150, | |
temperature: 0.2, | |
}); | |
let raw = (result.text || '').trim(); | |
// Strip common code fences if present | |
raw = raw | |
.replace(/^\s* |
🤖 Prompt for AI Agents
In agent-docs/src/agents/doc-processing/keyword-extraction.ts around lines
56–77, the current parsing assumes a JSON object with a keywords array and will
fail or return empty for fenced JSON, bare arrays, or CSV-style responses;
implement robust parsing by first stripping Markdown code fences/backticks from
raw, then try JSON.parse inside a try/catch and accept either a bare array or an
object with a keywords property, and on parse failure fall back to splitting raw
by commas/newlines to extract tokens; afterwards normalize tokens (trim),
perform case-insensitive dedupe using a Set, limit to maxKeywords, and if the
final list is empty throw a clear error; ensure you log the resulting keywords
as before.
const rephrasedQuery = result.text?.trim() || input; | ||
console.log(rephrasedQuery); | ||
// Log if we actually rephrased it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove console.log to avoid PII leakage; use the provided logger instead.
Raw console logging can leak user input outside your structured logging pipeline. Replace or drop it.
- console.log(rephrasedQuery);
🤖 Prompt for AI Agents
In agent-docs/src/agents/doc-qa/prompt.ts around lines 57 to 59, remove the raw
console.log(rephrasedQuery) to avoid PII leakage and instead use the module's
provided logger (e.g., logger.debug or logger.info) or drop the log entirely; if
you must record the event, log a non-sensitive message such as "query rephrased"
and only include a hashed/trimmed token or boolean flag indicating rephrasing,
ensuring no raw user input is written to stdout/stderr.
const rephrasedQuery = result.text?.trim() || input; | ||
console.log(rephrasedQuery); | ||
// Log if we actually rephrased it | ||
if (rephrasedQuery !== input) { | ||
ctx.logger.info( | ||
'Rephrased query from "%s" to "%s"', | ||
input, | ||
rephrasedQuery | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Repo-wide sanity check for stray console logging.
To prevent future leaks, scan the repo for other console.log
/console.error
etc., and replace them with ctx.logger
equivalents where appropriate.
🏁 Script executed:
#!/bin/bash
# Find raw console logging across the repo (excluding node_modules and build artifacts)
rg -nP --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' '\bconsole\.(log|error|warn|info|debug)\s*\(' -C2
Length of output: 22566
Replace raw console statements with ctx.logger across source files
I ran a repo-wide search and identified the following non-documentation files that still use raw console.*
calls. Please replace these with ctx.logger.<level>
(e.g., ctx.logger.debug
, ctx.logger.info
, ctx.logger.warn
, ctx.logger.error
) to ensure consistent, configurable logging:
• scripts/generate-docs-json.js
• lib/env.ts
• components/Mermaid.tsx
• app/layout.tsx
• components/CopyPageDropdown.tsx
• components/CustomSearchDialog/hooks/useMessages.tsx
• app/api/rag-search/route.ts
• app/api/page-content/route.ts
• app/llms.txt/route.ts
• app/llms-full.txt/route.ts
• agent-docs/index.ts
• agent-docs/src/agents/doc-qa/prompt.ts
Exclude MDX guide files under content/
(these are user-facing examples). Once updated, double-check that logging levels align with intent (debug vs. info vs. warn vs. error).
🤖 Prompt for AI Agents
In agent-docs/src/agents/doc-qa/prompt.ts around lines 57 to 66, replace the raw
console.log(rephrasedQuery) with the contextual logger (e.g., ctx.logger.debug)
and use a descriptive message; keep the existing ctx.logger.info call for when
the query actually changed. Ensure ctx.logger is available in scope and that the
logging level matches intent (debug for routine values, info for meaningful
state changes). Also scan the repo for other console.* usages noted in the
review and replace them with the appropriate ctx.logger.<level> calls.
const [currentInput, setCurrentInput] = useState(''); | ||
const inputRef = useRef<HTMLTextAreaElement>(null); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Unwired inputRef
and focus effect: either remove or forward a ref to SearchInput
.
inputRef
is never attached to an element, so the open-focus effect is a no-op. Since SearchInput
already focuses on mount, you can drop this altogether, or forward the ref if parent-controlled focus is desired.
- const [currentInput, setCurrentInput] = useState('');
- const inputRef = useRef<HTMLTextAreaElement>(null);
+ const [currentInput, setCurrentInput] = useState('');
@@
- // Focus input when dialog opens
- useEffect(() => {
- if (open) {
- setTimeout(() => inputRef.current?.focus(), 100);
- }
- }, [open]);
+ // SearchInput focuses itself on mount; parent-level focusing not required here.
If you prefer parent-controlled focus, expose a ref from SearchInput
:
// in SearchInput.tsx
export const SearchInput = forwardRef<HTMLTextAreaElement, SearchInputProps>(function SearchInput(props, ref) {
const textareaRef = useRef<HTMLTextAreaElement>(null);
useImperativeHandle(ref, () => textareaRef.current as HTMLTextAreaElement | null);
// ...use textareaRef on the <textarea />
});
Also applies to: 26-31
🤖 Prompt for AI Agents
In components/CustomSearchDialog/index.tsx around lines 14-16 (and related
effect at 26-31), the inputRef is created but never attached so the focus effect
is a no-op; either remove the unused inputRef and the open-focus effect
entirely, or forward the ref into SearchInput and attach it to the actual
<textarea>. To forward: change SearchInput to use
forwardRef<HTMLTextAreaElement,...>, keep an internal textarea ref and expose it
via useImperativeHandle, attach that internal ref to the textarea, and then pass
the inputRef down to <SearchInput ref={inputRef}/> from CustomSearchDialog;
ensure the focus effect uses the forwarded ref or is removed if SearchInput
already focuses on mount.
// Extract string content from children | ||
const code = | ||
typeof codeElement?.props?.children === 'string' | ||
? codeElement.props.children | ||
: String(codeElement?.props?.children || ''); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix code extraction: arrays become comma-joined via String()
. Join children without commas.
react-markdown
often passes children
as an array of strings/nodes. String([])
inserts commas, corrupting code. Join explicitly.
- // Extract string content from children
- const code =
- typeof codeElement?.props?.children === 'string'
- ? codeElement.props.children
- : String(codeElement?.props?.children || '');
+ // Extract string content from children
+ const rawChildren = codeElement?.props?.children;
+ const code = Array.isArray(rawChildren)
+ ? rawChildren.join('')
+ : typeof rawChildren === 'string'
+ ? rawChildren
+ : String(rawChildren ?? '');
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// Extract string content from children | |
const code = | |
typeof codeElement?.props?.children === 'string' | |
? codeElement.props.children | |
: String(codeElement?.props?.children || ''); | |
// Extract string content from children | |
const rawChildren = codeElement?.props?.children; | |
const code = Array.isArray(rawChildren) | |
? rawChildren.join('') | |
: typeof rawChildren === 'string' | |
? rawChildren | |
: String(rawChildren ?? ''); |
🤖 Prompt for AI Agents
In components/CustomSearchDialog/MessageList.tsx around lines 120-125, the code
uses String(codeElement?.props?.children) which will comma-join array children
and corrupt code blocks; instead detect if children is an array and join its
items without commas (e.g., map/flatMap to strings and join('') or join('')
after filtering null/undefined), otherwise keep the string branch, and fall back
to String(...) only for non-array, non-string values so code content is
preserved without extra commas.
<div className="flex gap-2 h-10"> | ||
{/* Textarea Container */} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Auto-resize is capped by a fixed parent height (h-10
) — textarea cannot grow
The wrapper’s h-10
locks the row height to 40px, negating the auto-resize effect (up to 150px). Remove the fixed height so the textarea can expand.
- <div className="flex gap-2 h-10">
+ <div className="flex gap-2 items-end">
🤖 Prompt for AI Agents
In components/CustomSearchDialog/SearchInput.tsx around lines 53-54 the wrapper
div uses a fixed height class "h-10" which prevents the textarea from
auto-resizing; remove the "h-10" class from the container (or replace it with a
min-height if a baseline height is needed) so the textarea can expand up to its
max height (150px) and ensure any layout CSS (flex alignment or gap) still
behaves as intended.
securityLevel: 'loose', | ||
fontFamily: 'inherit', | ||
themeCSS: 'margin: 1.5rem auto 0;', | ||
theme: _theme, | ||
darkMode: _theme === "dark", | ||
darkMode: _theme === 'dark', | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security: securityLevel 'loose' + dangerouslySetInnerHTML enables XSS if chart content is untrusted.
Mermaid’s “loose” mode permits raw HTML. Combined with dangerouslySetInnerHTML
, this is a high-risk vector if user-supplied charts are ever rendered. Use securityLevel: 'strict'
(default) and only relax if inputs are fully trusted and sanitized.
mermaid.initialize({
startOnLoad: false,
- securityLevel: 'loose',
+ securityLevel: 'strict',
fontFamily: 'inherit',
themeCSS: 'margin: 1.5rem auto 0;',
theme: _theme,
darkMode: _theme === 'dark',
});
If you truly need HTML labels, sanitize upstream and consider restricting allowed directives; document the trust boundary.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
securityLevel: 'loose', | |
fontFamily: 'inherit', | |
themeCSS: 'margin: 1.5rem auto 0;', | |
theme: _theme, | |
darkMode: _theme === "dark", | |
darkMode: _theme === 'dark', | |
}); | |
mermaid.initialize({ | |
startOnLoad: false, | |
securityLevel: 'strict', | |
fontFamily: 'inherit', | |
themeCSS: 'margin: 1.5rem auto 0;', | |
theme: _theme, | |
darkMode: _theme === 'dark', | |
}); |
🤖 Prompt for AI Agents
In components/Mermaid.tsx around lines 28 to 33, the code sets mermaid config
securityLevel: 'loose' while rendering with dangerouslySetInnerHTML which
enables raw HTML and is an XSS risk for untrusted chart content; change
securityLevel to 'strict' (the safe default) and remove or avoid passing
unsanitized HTML to dangerouslySetInnerHTML, or if HTML labels are required,
ensure upstream sanitization of chart input (whitelist allowed tags/attributes
and strip scripts) and document the trust boundary; if you must permit limited
HTML, implement and call a sanitizer here before assigning to
dangerouslySetInnerHTML and add a comment explaining why the relaxation is safe.
theme: _theme, | ||
darkMode: _theme === "dark", | ||
darkMode: _theme === 'dark', | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify darkMode
option is valid for current Mermaid version.
Upstream Mermaid config has evolved; confirm that darkMode
is a supported option (vs. relying solely on theme
/themeVariables
).
🌐 Web query:
Is `darkMode` a valid configuration option in Mermaid v11, or should we rely only on `theme` and `themeVariables`?
💡 Result:
I cannot find any documented darkMode
option in Mermaid v11. Configure dark appearance with theme: 'dark'
(and override colors via themeVariables
or themeCSS
) instead [1][2].
References:
- Mermaid configuration (theme & themeVariables) — https://mermaid.js.org/configuration/configuration.html
- mermaidAPI.initialize options (theme, themeVariables) — https://mermaid.js.org/mermaidAPI.html#initialize
Replace unsupported darkMode
option with theme: 'dark'
Mermaid v11 does not recognize a darkMode
setting. You should remove the darkMode
entry from your configuration and instead use:
theme: 'dark'
(or conditional logic to toggle between'dark'
and'default'
)themeVariables
orthemeCSS
to customize any specific colors
Please update the call in components/Mermaid.tsx (around line 33) accordingly:
- Remove the
darkMode
property. - Add or adjust:
mermaid.initialize({ - darkMode: isDark, theme: isDark ? 'dark' : 'default', themeVariables: { /* your overrides here */ }, });
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In components/Mermaid.tsx around line 33, the mermaid config uses an unsupported
darkMode option; remove the darkMode property and replace it with theme: 'dark'
(or add conditional logic to set theme to 'dark' or 'default' based on app
theme), and if you need custom colors move those settings into themeVariables or
themeCSS so the mermaid.initialize call uses recognized keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
components/Mermaid.tsx (1)
14-19
: Prevent stale renders and state updates after unmount.renderChart is async; rapid prop/theme changes can cause out-of-order updates or setState on unmounted component. You already have currentChartRef; use it and add cleanup.
const container = containerRef.current; if (!container) return; - currentChartRef.current = chart; + // Snapshot the chart for this render to prevent out-of-order updates + currentChartRef.current = chart; async function renderChart() { - const { default: mermaid } = await import('mermaid'); + const { default: mermaid } = await import('mermaid'); + const snapshot = currentChartRef.current; const _theme = theme === 'dark' || (theme === 'system' && resolvedTheme === 'dark') ? 'dark' : 'neutral'; try { mermaid.initialize({ startOnLoad: false, securityLevel: 'strict', fontFamily: 'inherit', themeCSS: 'margin: 1.5rem auto 0;', theme: _theme, }); - const { svg, bindFunctions } = await mermaid.render( - id, - chart.replaceAll('\\n', '\n') - ); + const normalized = chart.replace(/\r\n/g, '\n').replaceAll('\\n', '\n'); + // Optional: validate before render to fail fast on bad diagrams + await mermaid.parse(normalized); + const { svg, bindFunctions } = await mermaid.render(id, normalized); // biome-ignore lint/style/noNonNullAssertion: <explanation> bindFunctions?.(container!); - setSvg(svg); + // Abort if a newer render started or component unmounted + if (snapshot !== currentChartRef.current || canceled) return; + setSvg(svg); } catch (error) { console.error('Error while rendering mermaid', error); } } - void renderChart(); + let canceled = false; + void renderChart(); + return () => { + canceled = true; + }; -}, [chart, id, resolvedTheme, theme]); +}, [chart, id, resolvedTheme, theme]);API references for async render and bindFunctions. (github.com, fossies.org)
Also applies to: 41-48
♻️ Duplicate comments (4)
agent-docs/src/agents/doc-qa/prompt.ts (1)
57-66
: Remove raw console.log and avoid logging full user text; use sanitized structured logging via ctx.logger.Direct console logging risks PII leakage and bypasses your logging pipeline. Also, logging the entire before/after query at info level exposes raw user input. Replace with sanitized metadata (changed flag and lengths).
Apply this diff:
- const rephrasedQuery = result.text?.trim() || input; - console.log(rephrasedQuery); - // Log if we actually rephrased it - if (rephrasedQuery !== input) { - ctx.logger.info( - 'Rephrased query from "%s" to "%s"', - input, - rephrasedQuery - ); - } + let rephrasedQuery = result.text?.trim() || input; + // Strip enclosing quotes if the model echoed them + if ( + (rephrasedQuery.startsWith('"') && rephrasedQuery.endsWith('"')) || + (rephrasedQuery.startsWith("'") && rephrasedQuery.endsWith("'")) + ) { + rephrasedQuery = rephrasedQuery.slice(1, -1).trim(); + } + + // Structured + sanitized logging (no raw user text) + ctx.logger.debug( + 'Rephrase result: changed=%s, inLen=%d, outLen=%d', + rephrasedQuery !== input, + input.length, + rephrasedQuery.length + ); + if (rephrasedQuery !== input) { + ctx.logger.info( + 'Rephrased query (sanitized): changed=%s, inLen=%d, outLen=%d', + true, + input.length, + rephrasedQuery.length + ); + }components/Mermaid.tsx (2)
28-33
: Security: switch securityLevel to 'strict' and justify/mitigate dangerouslySetInnerHTML.Using securityLevel: 'loose' together with dangerouslySetInnerHTML exposes you to XSS if chart content is ever untrusted. Mermaid’s default is 'strict' (encodes HTML, disables clicks). If you truly need HTML labels, sanitize upstream and document the trust boundary; otherwise prefer 'strict'. Also replace the placeholder "" in the biome-ignore with a concrete justification.
Apply this minimal hardening:
mermaid.initialize({ startOnLoad: false, - securityLevel: 'loose', + securityLevel: 'strict', fontFamily: 'inherit', themeCSS: 'margin: 1.5rem auto 0;', theme: _theme, - darkMode: _theme === 'dark', });Optionally, add a sanitizer (e.g., DOMPurify) before setting innerHTML if you must stay in a relaxed mode.
References: Mermaid config schema (securityLevel default = "strict"; 'loose' allows HTML), and options overview. (mermaid.js.org)
Also applies to: 53-55
31-33
: Replace unsupported top-level darkMode with theme or themeVariables.darkMode.Mermaid v10/v11 does not support a top-level darkMode key in initialize(). Use theme: 'dark' or themeVariables: { darkMode: true } alongside a compatible theme. Since you already compute _theme, removing darkMode is sufficient.
mermaid.initialize({ startOnLoad: false, securityLevel: 'strict', fontFamily: 'inherit', themeCSS: 'margin: 1.5rem auto 0;', theme: _theme, - darkMode: _theme === 'dark', });
Docs: themes and themeVariables (darkMode lives under themeVariables). (mermaid.js.org)
components/CustomSearchDialog/MessageList.tsx (1)
109-138
: Fix code extraction: String(array) comma-joins children; add guards and robust language detectionCurrent logic uses String(codeElement.props.children) which inserts commas when children is an array, corrupting code blocks. Also add a null-safe guard for non-element children and a more robust language extractor. Trim CLI commands to avoid trailing blank lines.
Apply this diff:
- pre: ({ children }) => { - // Extract code content and language - const codeElement = React.Children.toArray( - children - )[0] as React.ReactElement<{ - className?: string; - children?: React.ReactNode; - }>; - const className = codeElement?.props?.className || ''; - const language = className.replace('language-', ''); - - // Extract string content from children - const code = - typeof codeElement?.props?.children === 'string' - ? codeElement.props.children - : String(codeElement?.props?.children || ''); - - // Use CLICommand for bash/shell commands - if ( - language === 'bash' || - language === 'sh' || - language === 'shell' - ) { - return <CLICommand command={code} />; - } - - return ( - <DynamicCodeBlock code={code} lang={language || 'text'} /> - ); - }, + pre: ({ children }) => { + // Extract code content and language safely + const [firstChild] = React.Children.toArray(children); + const codeElement = React.isValidElement(firstChild) + ? (firstChild as React.ReactElement<{ + className?: string; + children?: React.ReactNode; + }>) + : undefined; + + const className = codeElement?.props?.className ?? ''; + const language = + className.match(/\blanguage-([^\s]+)/)?.[1] ?? ''; + + // Extract string content from children — avoid comma-joining arrays + const rawChildren = codeElement?.props?.children; + const code = Array.isArray(rawChildren) + ? rawChildren + .map((c) => + typeof c === 'string' || typeof c === 'number' + ? String(c) + : '' + ) + .join('') + : typeof rawChildren === 'string' || typeof rawChildren === 'number' + ? String(rawChildren) + : String(rawChildren ?? ''); + + // Use CLICommand for bash/shell commands + if (language === 'bash' || language === 'sh' || language === 'shell') { + return <CLICommand command={code.trim()} />; + } + + return ( + <DynamicCodeBlock code={code} lang={language || 'text'} /> + ); + },
🧹 Nitpick comments (13)
agent-docs/src/agents/doc-qa/prompt.ts (2)
57-58
: Harden output normalization: strip enclosing quotes from LLM output.The model can occasionally return the query wrapped in quotes due to the prompt formatting. Normalize by removing symmetrical leading/trailing quotes. This also enables switching from const to let for reassignment.
The change above in the prior diff already implements this normalization.
122-127
: Lower verbosity of classification logs to debug (or sanitize).Classification reasoning is useful for debugging but noisy at info level. Consider logging at debug, or remove reasoning from info to reduce log volume.
- ctx.logger.info( + ctx.logger.debug( 'Prompt classified as %s (confidence: %f): %s', result.object.type, result.object.confidence, result.object.reasoning );agent-docs/src/agents/doc-qa/rag.ts (2)
9-12
: Annotate return type for stronger typing and API stability.Explicitly return Promise to lock the contract and improve IDE help.
-export default async function answerQuestion( +export default async function answerQuestion( ctx: AgentContext, prompt: string -) { +): Promise<Answer> {
19-96
: Optional: route by prompt type to balance cost/latency vs. quality.You already have getPromptType; consider using it to select model/parameters (e.g., gpt-4o-mini for Normal, gpt-4o for Thinking) and adjust maxTokens/temperature accordingly. This keeps simple queries fast and cheap without sacrificing complex ones.
Example insertion after retrieval:
+ // Optionally classify prompt complexity to choose model/params + // const promptType = await getPromptType(ctx, rephrasedPrompt); + // const isThinking = promptType === 'Thinking'; + // const model = openai(isThinking ? 'gpt-4o' : 'gpt-4o-mini'); + // const maxTokens = isThinking ? 2048 : 1024;app/(docs)/[[...slug]]/page.tsx (4)
19-21
: Prefer path aliases over deep relative paths for consistencyElsewhere in this file you already use the
@/*
alias. Using it here improves readability and reduces churn on future file moves.-import { CommunityButton } from '../../../components/Community'; -import CopyPageDropdown from '../../../components/CopyPageDropdown'; -import { NavButton } from '../../../components/NavButton'; +import { CommunityButton } from '@/components/Community'; +import CopyPageDropdown from '@/components/CopyPageDropdown'; +import { NavButton } from '@/components/NavButton';
23-27
: Avoid Promise-wrappingparams
; Next.js passes route params synchronously
params
is provided synchronously to App Router page components. Keeping it non-Promise aligns with Next types and removes an unnecessaryawait
.-export default async function Page(props: { - params: Promise<{ slug?: string[] }>; -}) { - const params = await props.params; +export default async function Page(props: { params: { slug?: string[] } }) { + const { params } = props;
77-79
: Copy nit: “Sign up” (verb) vs “Signup” (noun)Slight wording tweak for consistency with common UI copy.
- <a href="mailto:hi@agentuity.com">hi@agentuity.com</a> if you'd + <a href="mailto:hi@agentuity.com">hi@agentuity.com</a> if you’dAnd for the CTA below (Line 86):
- <a href="https://app.agentuity.com/sign-up">Signup</a> + <a href="https://app.agentuity.com/sign-up">Sign up</a>
99-103
: Same as Page: remove Promise fromgenerateMetadata
paramsKeep
params
synchronous and drop theawait
for type clarity.-export async function generateMetadata(props: { - params: Promise<{ slug?: string[] }>; -}) { - const params = await props.params; +export async function generateMetadata(props: { params: { slug?: string[] } }) { + const { params } = props;components/Mermaid.tsx (3)
21-23
: Confirm theme choice 'neutral' for light mode.neutral is intended for black-and-white/print; many UIs prefer default for light mode. If this was unintentional, switch to 'default'. Otherwise, keep as-is.
Reference: available themes include default, neutral, dark, forest, base. (mermaid.js.org, github.com)
36-36
: Normalize both escaped and real Windows newlines.If incoming chart strings sometimes contain actual CRLFs or literal "\r\n" and "\n", normalize both before render.
- chart.replaceAll('\\n', '\n') + chart.replace(/\r\n/g, '\n').replaceAll('\\n', '\n')
43-43
: Improve error telemetry and UX fallback.Augment the log with id and theme; optionally clear SVG or show a small fallback UI to avoid stale diagrams when a render fails.
- console.error('Error while rendering mermaid', error); + console.error('Error while rendering mermaid', { id, theme: _theme, error }); + // Optionally: setSvg('<svg aria-hidden="true"></svg>');components/CustomSearchDialog/MessageList.tsx (2)
126-133
: Recognize more shell aliases for CLI command blocksSmall UX win: treat zsh/console/shell-session variants as CLI commands too.
- if ( - language === 'bash' || - language === 'sh' || - language === 'shell' - ) { - return <CLICommand command={code.trim()} />; - } + if ( + ['bash', 'sh', 'shell', 'zsh', 'console', 'shell-session', 'sh-session'].includes( + language + ) + ) { + return <CLICommand command={code.trim()} />; + }
63-65
: Hide decorative avatars from screen readersThese avatar icons are purely presentational; hide them to reduce verbosity for assistive tech.
- <div className="w-6 h-6 bg-gray-50 dark:bg-gray-800 rounded-full flex items-center justify-center flex-shrink-0"> + <div aria-hidden="true" className="w-6 h-6 bg-gray-50 dark:bg-gray-800 rounded-full flex items-center justify-center flex-shrink-0"> <AgentuityLogo className="w-3 h-3 text-gray-500 dark:text-gray-400" /> </div>- <div className="w-6 h-6 bg-gray-50 dark:bg-gray-800 rounded-full flex items-center justify-center flex-shrink-0 mt-0.5"> + <div aria-hidden="true" className="w-6 h-6 bg-gray-50 dark:bg-gray-800 rounded-full flex items-center justify-center flex-shrink-0 mt-0.5"> <AgentuityLogo className="w-3 h-3 text-gray-500 dark:text-gray-400" /> </div>- <div className="w-6 h-6 bg-gray-100 dark:bg-gray-700 rounded-full flex items-center justify-center flex-shrink-0 mt-0.5"> + <div aria-hidden="true" className="w-6 h-6 bg-gray-100 dark:bg-gray-700 rounded-full flex items-center justify-center flex-shrink-0 mt-0.5"> <User className="w-3 h-3 text-gray-500 dark:text-gray-400" /> </div>Also applies to: 89-92, 199-201
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (24)
agent-docs/src/agents/doc-processing/chunk-mdx.ts
(2 hunks)agent-docs/src/agents/doc-processing/docs-orchestrator.ts
(1 hunks)agent-docs/src/agents/doc-processing/docs-processor.ts
(1 hunks)agent-docs/src/agents/doc-processing/embed-chunks.ts
(1 hunks)agent-docs/src/agents/doc-processing/test/chunk-mdx.test.ts
(1 hunks)agent-docs/src/agents/doc-qa/prompt.ts
(4 hunks)agent-docs/src/agents/doc-qa/rag.ts
(3 hunks)app/(docs)/[[...slug]]/page.tsx
(4 hunks)app/(docs)/layout.tsx
(2 hunks)app/api/rag-search/route.ts
(1 hunks)app/api/search/route.ts
(1 hunks)app/layout.tsx
(3 hunks)components/AISearchToggle.tsx
(1 hunks)components/CodeExample.tsx
(2 hunks)components/CopyPageDropdown.tsx
(1 hunks)components/CustomSearchDialog/MessageList.tsx
(1 hunks)components/CustomSearchDialog/SearchInput.tsx
(1 hunks)components/CustomSearchDialog/hooks/useMessages.tsx
(1 hunks)components/CustomSearchDialog/index.tsx
(1 hunks)components/Mermaid.tsx
(2 hunks)components/TypingAnimation.tsx
(4 hunks)lib/source.ts
(1 hunks)middleware.ts
(1 hunks)package.json
(2 hunks)
✅ Files skipped from review due to trivial changes (3)
- app/api/search/route.ts
- agent-docs/src/agents/doc-processing/docs-orchestrator.ts
- app/layout.tsx
🚧 Files skipped from review as they are similar to previous changes (16)
- lib/source.ts
- components/CodeExample.tsx
- components/CopyPageDropdown.tsx
- agent-docs/src/agents/doc-processing/chunk-mdx.ts
- components/TypingAnimation.tsx
- components/AISearchToggle.tsx
- app/api/rag-search/route.ts
- components/CustomSearchDialog/index.tsx
- app/(docs)/layout.tsx
- package.json
- agent-docs/src/agents/doc-processing/embed-chunks.ts
- components/CustomSearchDialog/hooks/useMessages.tsx
- agent-docs/src/agents/doc-processing/docs-processor.ts
- components/CustomSearchDialog/SearchInput.tsx
- middleware.ts
- agent-docs/src/agents/doc-processing/test/chunk-mdx.test.ts
🧰 Additional context used
📓 Path-based instructions (1)
agent-docs/src/agents/**/*.ts
📄 CodeRabbit inference engine (agent-docs/.cursor/rules/sdk.mdc)
agent-docs/src/agents/**/*.ts
: Use TypeScript for better type safety and IDE support
Import types from '@agentuity/sdk'
Use structured error handling with try/catch blocks
Leverage the provided logger for consistent logging
Use the storage APIs for persisting data
Consider agent communication for complex workflows
Files:
agent-docs/src/agents/doc-qa/prompt.ts
agent-docs/src/agents/doc-qa/rag.ts
🧠 Learnings (5)
📚 Learning: 2025-07-23T12:40:13.980Z
Learnt from: CR
PR: agentuity/docs#0
File: .cursor/rules/mdx.mdc:0-0
Timestamp: 2025-07-23T12:40:13.980Z
Learning: This is MDX so some react components can be used
Applied to files:
app/(docs)/[[...slug]]/page.tsx
📚 Learning: 2025-07-23T12:40:34.834Z
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-23T12:40:34.834Z
Learning: Applies to agent-docs/src/agents/**/*.ts : Leverage the provided logger for consistent logging
Applied to files:
agent-docs/src/agents/doc-qa/prompt.ts
📚 Learning: 2025-07-23T12:40:22.412Z
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-23T12:40:22.412Z
Learning: Applies to agent-docs/**/src/agents/**/index.ts : Use the provided logger from the `AgentContext` interface such as `ctx.logger.info("my message: %s", "hello")`
Applied to files:
agent-docs/src/agents/doc-qa/prompt.ts
📚 Learning: 2025-06-28T18:06:02.340Z
Learnt from: afterrburn
PR: agentuity/docs#208
File: agent-docs/src/agents/doc-qa/index.ts:27-28
Timestamp: 2025-06-28T18:06:02.340Z
Learning: The answerQuestion function in agent-docs/src/agents/doc-qa/rag.ts handles errors internally by logging them and returning a fallback JSON answer, so it doesn't require external try-catch blocks at the call site.
Applied to files:
agent-docs/src/agents/doc-qa/rag.ts
📚 Learning: 2025-07-23T12:40:34.834Z
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-23T12:40:34.834Z
Learning: Applies to agent-docs/src/agents/**/*.ts : Use structured error handling with try/catch blocks
Applied to files:
agent-docs/src/agents/doc-qa/rag.ts
🧬 Code graph analysis (4)
app/(docs)/[[...slug]]/page.tsx (1)
components/XButton.tsx (1)
XButton
(4-34)
agent-docs/src/agents/doc-qa/prompt.ts (1)
agent-docs/src/agents/doc-qa/types.ts (2)
PromptType
(27-27)PromptClassificationSchema
(18-22)
components/CustomSearchDialog/MessageList.tsx (3)
components/CustomSearchDialog/types.ts (2)
MessageListProps
(26-30)Message
(3-14)components/icons/AgentuityLogo.tsx (1)
AgentuityLogo
(6-33)components/CLICommand.tsx (1)
CLICommand
(8-26)
agent-docs/src/agents/doc-qa/rag.ts (3)
agent-docs/src/agents/doc-qa/prompt.ts (1)
rephraseVaguePrompt
(8-73)agent-docs/src/agents/doc-qa/retriever.ts (1)
retrieveRelevantDocs
(121-226)agent-docs/src/agents/doc-qa/types.ts (2)
AnswerSchema
(11-14)Answer
(26-26)
⏰ 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: Workers Builds: docs
🔇 Additional comments (13)
agent-docs/src/agents/doc-qa/prompt.ts (1)
48-55
: Good: fail-safe error handling returns original input on failure.The try/catch with a safe fallback aligns with the agent guidelines for structured error handling.
Also applies to: 69-72
agent-docs/src/agents/doc-qa/rag.ts (1)
98-107
: Solid fallback behavior with structured JSON and MDX guidance.The catch block logs the error and returns a schema-compliant Answer with an MDX-formatted message. This maintains the function’s “never throw” contract for callers.
Also applies to: 110-126
app/(docs)/[[...slug]]/page.tsx (5)
1-3
: LGTM on formatting/import style changesThe switch to single quotes and consistent import specifiers looks good and keeps Biome happy.
Also applies to: 10-18
41-41
: Verify thecontent/
prefix matchespage.file.path
shapeIf
page.file.path
already includescontent/
, this would duplicate the segment in the rendered URL.Quick check: log one example during local dev or inspect
source
’sfile.path
contract to ensure no doublecontent/
occurs.
52-69
: Client components inside MDX mapping: ensure they’re marked correctlyComponents like
TypingAnimation
,Popup*
, andMermaid
likely run client-side logic. Ensure those files areuse client
(where appropriate) to avoid hydration warnings when rendered via MDX.
109-112
: LGTM on title fallback logicThe conditional nicely handles the “Agentuity” root title vs. specific page titles.
37-43
: Could you share the relevant FumaDocs documentation or yourDocsPage
/editOnGithub
configuration snippet (e.g. the docs link or code example) so we can confirm whethersha
must be a full commit SHA or if a branch name like"main"
is supported?components/Mermaid.tsx (2)
1-1
: LGTM: client-only component directive is correct.Mermaid rendering is browser-only; 'use client' is appropriate here.
3-4
: LGTM: dynamic import + next-themes usage fit SSR constraints.Importing mermaid inside useEffect avoids SSR issues and keeps the bundle lean.
components/CustomSearchDialog/MessageList.tsx (4)
10-16
: LGTM on type-only import and props signature formattingType-only import reduces bundle size and clarifies intent. Multiline destructuring of MessageList props reads well and is non-breaking.
20-23
: Auto-scroll dependency exception is acceptableIgnoring exhaustive-deps here is intentional and scoped; scrolling only on message changes avoids jumpiness during transient loading updates.
139-151
: Inline code rendering is sensibleFallback class adds wrapping and preserves whitespace. Keeping language-specific classes for inline code when provided is fine.
190-195
: Timestamp runtime type confirmed
All messages always carry aDate
at render time:
components/CustomSearchDialog/types.ts
declarestimestamp: Date
.- New messages are instantiated with
new Date()
(user, AI, error, and fallback flows).- Persisted history is
JSON.stringify
-ed (yielding ISO strings) then on load mapped back vianew Date(msg.timestamp)
in theuseMessages
hook.- The dialog and its hooks live in a client component (
'use client'
), so there’s no SSR/rehydration risk.Calling
message.timestamp.toLocaleTimeString(...)
is safe—no further changes needed.
const [svg, setSvg] = useState(""); | ||
const [svg, setSvg] = useState(''); | ||
const containerRef = useRef<HTMLDivElement>(null); | ||
const currentChartRef = useRef<string>(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Type correctness: fix ref nullability.
useRef(null) is a type error under strict TS. Update to include null in the ref type.
- const currentChartRef = useRef<string>(null);
+ const currentChartRef = useRef<string | null>(null);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const currentChartRef = useRef<string>(null); | |
const currentChartRef = useRef<string | null>(null); |
🤖 Prompt for AI Agents
In components/Mermaid.tsx around line 10, the ref is created with
useRef<string>(null) which fails under strict TypeScript because null isn’t
allowed; change the ref type to include null (e.g. useRef<string | null>(null))
so the initial null value is type-safe, and update any downstream usages to
handle the possible null value (guard or non-null assertion where appropriate).
Summary by CodeRabbit
New Features
Bug Fixes
Style
Chores