PI-MONO
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useRef, useMemo } from 'react';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
@@ -8,12 +8,8 @@ import { ArrowLeft, Pencil, Plus, Check, X, Trash2, Search, ChevronRight } from
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog';
|
||||
import { useClient } from 'hooks/useClient';
|
||||
import { useVisibleClaudeModels, useVisibleOpenCodeModels, useVisiblePiMonoModels } from '@/state/useModels';
|
||||
import { useSettings } from '@/state/useSettings';
|
||||
import { useVisiblePiMonoModels } from '@/state/useModels';
|
||||
import { Card } from '@/components/Card';
|
||||
import type { ChatMessage } from 'apps/Chat';
|
||||
import { useClaude } from '@/Screens/Dashboard/Chat/useClaude';
|
||||
import { useOpenCode } from '@/Screens/Dashboard/Chat/useOpenCode';
|
||||
import { usePiMono } from '@/Screens/Dashboard/Chat/usePiMono';
|
||||
import { EmbeddableChat } from '@/Screens/Dashboard/Chat/EmbeddableChat';
|
||||
type CapabilitySummary = {
|
||||
@@ -60,130 +56,14 @@ type CapabilityChatProps = {
|
||||
onResponseEnd?: () => void;
|
||||
};
|
||||
|
||||
type CapabilityChatInnerProps = CapabilityChatProps & {
|
||||
onProviderChange: (p: 'claude' | 'opencode' | 'pi-mono') => void;
|
||||
};
|
||||
|
||||
const CapabilityChatClaude = ({
|
||||
kind,
|
||||
endpoint,
|
||||
dirName,
|
||||
filePath,
|
||||
resourceDir,
|
||||
chatSessionId,
|
||||
isNew,
|
||||
description,
|
||||
onResponseEnd,
|
||||
onProviderChange,
|
||||
}: CapabilityChatInnerProps) => {
|
||||
const client = useClient();
|
||||
const claudeModels = useVisibleClaudeModels();
|
||||
const seedFile = `${kind.toUpperCase()}.md`;
|
||||
const promptFrontmatter = chatSessionId
|
||||
? undefined
|
||||
: `<frontmatter>\ninput file: ${filePath}\n${seedFile}: ${filePath}\ndir: ${resourceDir}\n\nBe aware of any extra files alongside the same dir as the ${kind} file we're handling, for possible extra context. You can also, if pertinent, create scripts or other files that will help you in the future.\n</frontmatter>`;
|
||||
const defaultInput = chatSessionId
|
||||
? undefined
|
||||
: isNew
|
||||
? description ?? `Help me create the content for this new ${kind} file`
|
||||
: `Help me understand and improve this ${kind} file`;
|
||||
|
||||
const storage = useMemo(
|
||||
() => ({
|
||||
load: async () => {
|
||||
const data = await client.get<{ sessionId: string | null; messages: ChatMessage[] }>(
|
||||
`${endpoint}/${dirName}/chat`,
|
||||
);
|
||||
return { sessionId: data.sessionId, messages: data.messages ?? [] };
|
||||
},
|
||||
save: async (sessionId: string, messages: ChatMessage[]) => {
|
||||
await client.put(`${endpoint}/${dirName}/chat`, { sessionId, messages });
|
||||
},
|
||||
}),
|
||||
[endpoint, dirName],
|
||||
);
|
||||
|
||||
const claude = useClaude(chatSessionId ?? undefined, undefined, {
|
||||
replaceUrl: false,
|
||||
storage,
|
||||
resourceChatDir: resourceDir,
|
||||
});
|
||||
|
||||
const onResponseEndRef = useRef(onResponseEnd);
|
||||
onResponseEndRef.current = onResponseEnd;
|
||||
|
||||
const wasGenerating = useRef(false);
|
||||
useEffect(() => {
|
||||
if (wasGenerating.current && !claude.isGenerating) {
|
||||
onResponseEndRef.current?.();
|
||||
}
|
||||
wasGenerating.current = claude.isGenerating;
|
||||
}, [claude.isGenerating]);
|
||||
|
||||
return (
|
||||
<EmbeddableChat
|
||||
chat={claude}
|
||||
provider="claude"
|
||||
availableModels={claudeModels}
|
||||
onProviderChange={onProviderChange}
|
||||
defaultInput={defaultInput}
|
||||
promptPrefix={promptFrontmatter}
|
||||
className="h-full"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const CapabilityChatOpenCode = ({
|
||||
export const CapabilityChat = ({
|
||||
kind,
|
||||
filePath,
|
||||
resourceDir,
|
||||
isNew,
|
||||
description,
|
||||
onResponseEnd,
|
||||
onProviderChange,
|
||||
}: CapabilityChatInnerProps) => {
|
||||
const openCodeModels = useVisibleOpenCodeModels();
|
||||
const seedFile = `${kind.toUpperCase()}.md`;
|
||||
const promptFrontmatter = `<frontmatter>\ninput file: ${filePath}\n${seedFile}: ${filePath}\ndir: ${resourceDir}\n\nBe aware of any extra files alongside the same dir as the ${kind} file we're handling, for possible extra context. You can also, if pertinent, create scripts or other files that will help you in the future.\n</frontmatter>`;
|
||||
const defaultInput = isNew
|
||||
? description ?? `Help me create the content for this new ${kind} file`
|
||||
: `Help me understand and improve this ${kind} file`;
|
||||
|
||||
const opencode = useOpenCode(undefined, undefined, { replaceUrl: false });
|
||||
|
||||
const onResponseEndRef = useRef(onResponseEnd);
|
||||
onResponseEndRef.current = onResponseEnd;
|
||||
|
||||
const wasGenerating = useRef(false);
|
||||
useEffect(() => {
|
||||
if (wasGenerating.current && !opencode.isGenerating) {
|
||||
onResponseEndRef.current?.();
|
||||
}
|
||||
wasGenerating.current = opencode.isGenerating;
|
||||
}, [opencode.isGenerating]);
|
||||
|
||||
return (
|
||||
<EmbeddableChat
|
||||
chat={opencode}
|
||||
provider="opencode"
|
||||
availableModels={openCodeModels}
|
||||
onProviderChange={onProviderChange}
|
||||
defaultInput={defaultInput}
|
||||
promptPrefix={promptFrontmatter}
|
||||
className="h-full"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const CapabilityChatPiMono = ({
|
||||
kind,
|
||||
filePath,
|
||||
resourceDir,
|
||||
isNew,
|
||||
description,
|
||||
onResponseEnd,
|
||||
onProviderChange,
|
||||
}: CapabilityChatInnerProps) => {
|
||||
}: CapabilityChatProps) => {
|
||||
const piMonoModels = useVisiblePiMonoModels();
|
||||
const seedFile = `${kind.toUpperCase()}.md`;
|
||||
const promptFrontmatter = `<frontmatter>\ninput file: ${filePath}\n${seedFile}: ${filePath}\ndir: ${resourceDir}\n\nBe aware of any extra files alongside the same dir as the ${kind} file we're handling, for possible extra context. You can also, if pertinent, create scripts or other files that will help you in the future.\n</frontmatter>`;
|
||||
@@ -207,9 +87,7 @@ const CapabilityChatPiMono = ({
|
||||
return (
|
||||
<EmbeddableChat
|
||||
chat={piMono}
|
||||
provider="pi-mono"
|
||||
availableModels={piMonoModels}
|
||||
onProviderChange={onProviderChange}
|
||||
defaultInput={defaultInput}
|
||||
promptPrefix={promptFrontmatter}
|
||||
className="h-full"
|
||||
@@ -217,19 +95,6 @@ const CapabilityChatPiMono = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const CapabilityChat = (props: CapabilityChatProps) => {
|
||||
const { settings } = useSettings();
|
||||
const [provider, setProvider] = useState<'claude' | 'opencode' | 'pi-mono'>(settings.chat.defaultProvider);
|
||||
|
||||
if (provider === 'claude') {
|
||||
return <CapabilityChatClaude key="claude" {...props} onProviderChange={setProvider} />;
|
||||
}
|
||||
if (provider === 'opencode') {
|
||||
return <CapabilityChatOpenCode key="opencode" {...props} onProviderChange={setProvider} />;
|
||||
}
|
||||
return <CapabilityChatPiMono key="pi-mono" {...props} onProviderChange={setProvider} />;
|
||||
};
|
||||
|
||||
export const FrontmatterBlock = ({ yaml }: { yaml: string }) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user