feat(ollama): enhance model pull with improved error handling, persistence, and UI

- Add catalog metadata lookup for better error messages with hints (e.g., for missing manifests or tags)
- Persist downloaded model references in saved remote models for future reuse
- Replace searchRemoteModels import with getSavedRemoteModels in search route
- Enhance pull progress UI to display download bytes, digest, and fallback message when data is unavailable
- Improve error payload with model details, URL, and tags count to guide users toward valid tags or models
This commit is contained in:
Evandro Fonseca Junior committed 2025-10-29 19:42:24 -03:00
1 parent 1545020afe
commit a8bb7cc22d
33 files changed
+1298 -235

No files matched your search

+8 -4
View File
@@ -24,7 +24,10 @@ export function MarkdownRenderer({ content }: MarkdownRendererProps) {
rehypePlugins={[rehypeRaw, rehypeHighlight]}
components={{
code({ inline, className, children, ...props }: any) {
const text = String(children || "");
// Garantir extração correta do texto do bloco, mesmo com quebras/indentação
const node: any = (props as any).node;
const rawChild = node?.children?.[0]?.value ?? children;
const text = String(rawChild ?? "");
if (inline) {
return (
@@ -34,19 +37,20 @@ export function MarkdownRenderer({ content }: MarkdownRendererProps) {
);
}
const cleaned = text.replace(/^\n+|\n+$/g, "");
return (
<div className="relative my-4 rounded-lg border border-[var(--border)] bg-[var(--background)]">
<button
type="button"
className="absolute right-2 top-2 rounded px-2 py-1 text-xs bg-[var(--surface)]/70 hover:bg-[var(--surface)] transition-colors"
onClick={() => navigator.clipboard.writeText(text)}
onClick={() => navigator.clipboard.writeText(cleaned)}
aria-label="Copiar código"
>
<Copy className="h-3 w-3" />
</button>
<pre className="overflow-auto p-3">
<code className={className} {...props}>
{children}
<code className={`${className || ""} font-mono text-[var(--foreground)] whitespace-pre`} {...props}>
{cleaned}
</code>
</pre>
</div>
+7 -1
View File
@@ -42,8 +42,9 @@ export function MessageActions({
};
return (
<div className="flex items-center gap-1 opacity-70">
<div className="flex items-center gap-1 opacity-70 pointer-events-auto">
<button
type="button"
className="rounded px-2 py-1 text-xs hover:bg-[var(--surface)]"
onClick={handleCopyDefault}
disabled={disabled}
@@ -54,6 +55,7 @@ export function MessageActions({
<div className="relative">
<button
type="button"
className="rounded px-1 py-1 text-xs hover:bg-[var(--surface)]"
onClick={() => setDropdownOpen(!dropdownOpen)}
disabled={disabled}
@@ -65,12 +67,14 @@ export function MessageActions({
{dropdownOpen && (
<div className="absolute right-0 z-10 mt-1 rounded border border-[var(--border)] bg-[var(--background)] shadow-lg">
<button
type="button"
className="block w-full px-3 py-2 text-left text-xs hover:bg-[var(--surface)]"
onClick={() => handleModeSelect("markdown")}
>
Markdown
</button>
<button
type="button"
className="block w-full px-3 py-2 text-left text-xs hover:bg-[var(--surface)]"
onClick={() => handleModeSelect("text")}
>
@@ -82,6 +86,7 @@ export function MessageActions({
{onEdit && (
<button
type="button"
className="rounded px-2 py-1 text-xs hover:bg-[var(--surface)]"
onClick={onEdit}
disabled={disabled}
@@ -92,6 +97,7 @@ export function MessageActions({
)}
{onRegenerate && (
<button
type="button"
className="rounded px-2 py-1 text-xs hover:bg-[var(--surface)]"
onClick={onRegenerate}
disabled={disabled}