Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, { useEffect, useMemo, useState } from 'react'
import { Check, Copy } from 'lucide-react'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import { Tooltip } from '@/components/emcn'
import { Code, Tooltip } from '@/components/emcn'

/**
* Recursively extracts text content from React elements
Expand All @@ -28,56 +28,30 @@ const getTextContent = (element: React.ReactNode): string => {
return ''
}

// Fix for code block text rendering issues
// Global layout fixes for markdown content inside the copilot panel
if (typeof document !== 'undefined') {
const styleId = 'copilot-markdown-fix'
if (!document.getElementById(styleId)) {
const style = document.createElement('style')
style.id = styleId
style.textContent = `
.copilot-markdown-wrapper pre {
color: #F5F5F5 !important;
font-weight: 400 !important;
text-shadow: none !important;
filter: none !important;
opacity: 1 !important;
-webkit-font-smoothing: antialiased !important;
-moz-osx-font-smoothing: grayscale !important;
text-rendering: optimizeLegibility !important;
max-width: 100% !important;
overflow: auto !important;
}

.dark .copilot-markdown-wrapper pre {
color: #F0F0F0 !important;
}

.copilot-markdown-wrapper pre code,
.copilot-markdown-wrapper pre code *,
.copilot-markdown-wrapper pre span,
.copilot-markdown-wrapper pre div {
color: inherit !important;
opacity: 1 !important;
font-weight: 400 !important;
text-shadow: none !important;
filter: none !important;
-webkit-font-smoothing: antialiased !important;
-moz-osx-font-smoothing: grayscale !important;
text-rendering: optimizeLegibility !important;
}

/* Prevent any markdown content from expanding beyond the panel */
.copilot-markdown-wrapper, .copilot-markdown-wrapper * {
.copilot-markdown-wrapper,
.copilot-markdown-wrapper * {
max-width: 100% !important;
}
.copilot-markdown-wrapper p, .copilot-markdown-wrapper li {

.copilot-markdown-wrapper p,
.copilot-markdown-wrapper li {
overflow-wrap: anywhere !important;
word-break: break-word !important;
}

.copilot-markdown-wrapper a {
overflow-wrap: anywhere !important;
word-break: break-all !important;
}

.copilot-markdown-wrapper code:not(pre code) {
white-space: normal !important;
overflow-wrap: anywhere !important;
Expand Down Expand Up @@ -219,7 +193,7 @@ export default function CopilotMarkdownRenderer({ content }: CopilotMarkdownRend
</li>
),

// Code blocks
// Code blocks - render using shared Code.Viewer for consistent styling
pre: ({ children }: React.HTMLAttributes<HTMLPreElement>) => {
let codeContent: React.ReactNode = children
let language = 'code'
Expand Down Expand Up @@ -272,13 +246,24 @@ export default function CopilotMarkdownRenderer({ content }: CopilotMarkdownRend
}
}

// Map markdown language tag to Code.Viewer supported languages
const normalizedLanguage = (language || '').toLowerCase()
const viewerLanguage: 'javascript' | 'json' | 'python' =
normalizedLanguage === 'json'
? 'json'
: normalizedLanguage === 'python' || normalizedLanguage === 'py'
? 'python'
: 'javascript'

return (
<div className='my-6 w-0 min-w-full rounded-md bg-gray-900 text-sm dark:bg-black'>
<div className='flex items-center justify-between border-gray-700 border-b px-4 py-1.5 dark:border-gray-800'>
<span className='font-season text-gray-400 text-xs'>{language}</span>
<div className='my-6 w-0 min-w-full overflow-hidden rounded-md border border-[var(--border-strong)] bg-[#1F1F1F] text-sm'>
<div className='flex items-center justify-between border-[var(--border-strong)] border-b px-4 py-1.5'>
<span className='font-season text-[#A3A3A3] text-xs'>
{language === 'code' ? viewerLanguage : language}
</span>
<button
onClick={handleCopy}
className='text-muted-foreground transition-colors hover:text-gray-300'
className='text-[#A3A3A3] transition-colors hover:text-gray-300'
title='Copy'
>
{showCopySuccess ? (
Expand All @@ -288,11 +273,12 @@ export default function CopilotMarkdownRenderer({ content }: CopilotMarkdownRend
)}
</button>
</div>
<div className='overflow-x-auto'>
<pre className='whitespace-pre p-4 font-mono text-[#F5F5F5] text-sm leading-relaxed dark:text-[#F0F0F0]'>
{actualCodeText}
</pre>
</div>
<Code.Viewer
code={actualCodeText}
showGutter
language={viewerLanguage}
className='m-0 rounded-none border-0 bg-transparent'
/>
</div>
)
},
Expand All @@ -307,7 +293,7 @@ export default function CopilotMarkdownRenderer({ content }: CopilotMarkdownRend
if (inline) {
return (
<code
className='whitespace-normal break-all rounded bg-gray-300 px-1 py-0.5 font-mono text-[#707070] text-[0.9em] dark:bg-[var(--surface-11)] dark:text-[#E8E8E8]'
className='whitespace-normal break-all rounded border border-[var(--border-strong)] bg-[#1F1F1F] px-1 py-0.5 font-mono text-[#eeeeee] text-[0.9em]'
{...props}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,30 +463,40 @@ export function InlineToolCall({
const url = params.url || ''
const method = (params.method || '').toUpperCase()
return (
<div className='w-full overflow-hidden rounded border border-muted bg-card'>
<div className='grid grid-cols-2 gap-0 border-muted/60 border-b bg-muted/40 py-1.5'>
<div className='self-start px-2 font-medium font-season text-[#858585] text-[10px] uppercase tracking-wide dark:text-[#E0E0E0]'>
Method
</div>
<div className='self-start px-2 font-medium font-season text-[#858585] text-[10px] uppercase tracking-wide dark:text-[#E0E0E0]'>
Endpoint
</div>
</div>
<div className='grid grid-cols-[auto_1fr] gap-2 py-1.5'>
<div className='self-start px-2'>
<span className='inline-flex rounded bg-muted px-1.5 py-0.5 font-[470] font-mono text-[#707070] text-xs dark:text-[#E8E8E8]'>
{method || 'GET'}
</span>
</div>
<div className='min-w-0 self-start px-2'>
<span
className='block overflow-x-auto whitespace-nowrap font-[470] font-mono text-[#707070] text-xs dark:text-[#E8E8E8]'
title={url}
>
{url || 'URL not provided'}
</span>
</div>
</div>
<div className='w-full overflow-hidden rounded-[4px] border border-[var(--border-strong)] bg-[#1F1F1F]'>
<table className='w-full table-fixed bg-transparent'>
<thead className='bg-transparent'>
<tr className='border-[var(--border-strong)] border-b bg-transparent'>
<th className='w-[26%] border-[var(--border-strong)] border-r bg-transparent px-[10px] py-[5px] text-left font-medium text-[14px] text-[var(--text-tertiary)]'>
Method
</th>
<th className='w-[74%] bg-transparent px-[10px] py-[5px] text-left font-medium text-[14px] text-[var(--text-tertiary)]'>
Endpoint
</th>
</tr>
</thead>
<tbody className='bg-transparent'>
<tr className='group relative border-[var(--border-strong)] border-t bg-transparent'>
<td className='relative w-[26%] border-[var(--border-strong)] border-r bg-transparent p-0'>
<div className='px-[10px] py-[8px]'>
<span className='font-mono text-muted-foreground text-xs'>
{method || 'GET'}
</span>
</div>
</td>
<td className='relative w-[74%] bg-transparent p-0'>
<div className='min-w-0 px-[10px] py-[8px]'>
<span
className='block break-all font-mono text-muted-foreground text-xs'
title={url}
>
{url || 'URL not provided'}
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
)
}
Expand All @@ -499,7 +509,7 @@ export function InlineToolCall({
const normalizedEntries: Array<[string, string]> = []
Object.entries(variables).forEach(([key, value]) => {
if (typeof value === 'object' && value !== null && 'name' in value && 'value' in value) {
// Handle {name: "key", value: "val"} format
// Handle { name: "KEY", value: "VAL" } format
normalizedEntries.push([String((value as any).name), String((value as any).value)])
} else {
// Handle direct key-value format
Expand All @@ -508,35 +518,48 @@ export function InlineToolCall({
})

return (
<div className='w-full overflow-hidden rounded border border-muted bg-card'>
<div className='grid grid-cols-[160px_1fr] gap-0 border-muted/60 border-b bg-muted/40 py-1.5'>
<div className='self-start px-2 font-medium font-season text-[#858585] text-[11px] uppercase tracking-wide dark:text-[#E0E0E0]'>
Name
</div>
<div className='self-start px-2 font-medium font-season text-[#858585] text-[11px] uppercase tracking-wide dark:text-[#E0E0E0]'>
Value
</div>
</div>
{normalizedEntries.length === 0 ? (
<div className='px-2 py-1.5 font-[470] font-season text-[#707070] text-xs dark:text-[#E8E8E8]'>
No variables provided
</div>
) : (
<div className='divide-y divide-muted/60'>
{normalizedEntries.map(([name, value]) => (
<div key={name} className='grid grid-cols-[160px_1fr] gap-0 py-1.5'>
<div className='self-start px-2 font-medium font-season text-amber-800 text-xs dark:text-amber-200'>
{name}
</div>
<div className='min-w-0 self-start overflow-x-auto px-2'>
<span className='whitespace-nowrap font-[470] font-mono text-amber-700 text-xs dark:text-amber-300'>
{value}
</span>
</div>
</div>
))}
</div>
)}
<div className='w-full overflow-hidden rounded-[4px] border border-[var(--border-strong)] bg-[#1F1F1F]'>
<table className='w-full table-fixed bg-transparent'>
<thead className='bg-transparent'>
<tr className='border-[var(--border-strong)] border-b bg-transparent'>
<th className='w-[36%] border-[var(--border-strong)] border-r bg-transparent px-[10px] py-[5px] text-left font-medium text-[14px] text-[var(--text-tertiary)]'>
Name
</th>
<th className='w-[64%] bg-transparent px-[10px] py-[5px] text-left font-medium text-[14px] text-[var(--text-tertiary)]'>
Value
</th>
</tr>
</thead>
<tbody className='bg-transparent'>
{normalizedEntries.length === 0 ? (
<tr className='border-[var(--border-strong)] border-t bg-transparent'>
<td colSpan={2} className='px-[10px] py-[8px] text-muted-foreground text-xs'>
No variables provided
</td>
</tr>
) : (
normalizedEntries.map(([name, value]) => (
<tr
key={name}
className='group relative border-[var(--border-strong)] border-t bg-transparent'
>
<td className='relative w-[36%] border-[var(--border-strong)] border-r bg-transparent p-0'>
<div className='px-[10px] py-[8px]'>
<span className='truncate font-medium text-foreground text-xs'>{name}</span>
</div>
</td>
<td className='relative w-[64%] bg-transparent p-0'>
<div className='min-w-0 px-[10px] py-[8px]'>
<span className='block overflow-x-auto whitespace-nowrap font-mono text-muted-foreground text-xs'>
{value}
</span>
</div>
</td>
</tr>
))
)}
</tbody>
</table>
</div>
)
}
Expand Down