diff --git a/chainforge/react-server/src/CodeEvaluatorNode.tsx b/chainforge/react-server/src/CodeEvaluatorNode.tsx index c5409ee..f11a5ea 100644 --- a/chainforge/react-server/src/CodeEvaluatorNode.tsx +++ b/chainforge/react-server/src/CodeEvaluatorNode.tsx @@ -449,7 +449,9 @@ The Python interpeter in the browser is Pyodide. You may not be able to run some setLastResponses(stripLLMDetailsFromResponses(resps)); setStatus(Status.READY); }) - .catch(handleError); + .catch(() => { + // soft fail + }); }, []); // On upstream changes @@ -701,7 +703,7 @@ The Python interpeter in the browser is Pyodide. You may not be able to run some // Custom buttons for the node label const customButtons = useMemo(() => { - const btns = []; + const btns: React.ReactNode[] = []; // If this is Python and we are running locally, the user has // two options ---whether to run code in sandbox with pyodide, or from Flask (unsafe): diff --git a/chainforge/react-server/src/GlobalSettingsModal.tsx b/chainforge/react-server/src/GlobalSettingsModal.tsx index f539b06..cae5922 100644 --- a/chainforge/react-server/src/GlobalSettingsModal.tsx +++ b/chainforge/react-server/src/GlobalSettingsModal.tsx @@ -333,7 +333,7 @@ const GlobalSettingsModal = forwardRef( API Keys AI Support (BETA) Custom Providers - Advanced Settings + Advanced diff --git a/chainforge/react-server/src/ModelSettingSchemas.tsx b/chainforge/react-server/src/ModelSettingSchemas.tsx index c6e98c5..62ee2d5 100644 --- a/chainforge/react-server/src/ModelSettingSchemas.tsx +++ b/chainforge/react-server/src/ModelSettingSchemas.tsx @@ -2045,7 +2045,9 @@ export function getSettingsSchemaForLLM( ): ModelSettingsDict | undefined { const llm_provider = getProvider(llm_name); - const provider_to_settings_schema: { [K in LLMProvider]?: ModelSettingsDict } = { + const provider_to_settings_schema: { + [K in LLMProvider]?: ModelSettingsDict; + } = { [LLMProvider.OpenAI]: GPT4Settings, [LLMProvider.Anthropic]: ClaudeSettings, [LLMProvider.Google]: PaLM2Settings, diff --git a/chainforge/react-server/src/NodeLabelComponent.tsx b/chainforge/react-server/src/NodeLabelComponent.tsx index 04a4cd7..83fbfff 100644 --- a/chainforge/react-server/src/NodeLabelComponent.tsx +++ b/chainforge/react-server/src/NodeLabelComponent.tsx @@ -21,7 +21,7 @@ export interface NodeLabelProps { editable?: boolean; status?: Status; isRunning?: boolean; - customButtons?: React.ReactElement[]; + customButtons?: React.ReactNode[]; handleRunClick?: () => void; handleStopClick?: (nodeId: string) => void; handleRunHover?: () => void; diff --git a/chainforge/react-server/src/PromptNode.tsx b/chainforge/react-server/src/PromptNode.tsx index 0a62555..7de8690 100644 --- a/chainforge/react-server/src/PromptNode.tsx +++ b/chainforge/react-server/src/PromptNode.tsx @@ -20,7 +20,7 @@ import { Tooltip, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; -import { IconList } from "@tabler/icons-react"; +import { IconEraser, IconList } from "@tabler/icons-react"; import useStore from "./store"; import BaseNode from "./BaseNode"; import NodeLabel from "./NodeLabelComponent"; @@ -56,6 +56,7 @@ import { import { AlertModalContext } from "./AlertModal"; import { Status } from "./StatusIndicatorComponent"; import { + clearCachedResponses, countQueries, generatePrompts, grabResponses, @@ -1073,8 +1074,28 @@ Soft failing by replacing undefined with empty strings.`, [textAreaRef], ); + // Add custom context menu options on right-click. + // 1. Convert TextFields to Items Node, for convenience. + const customContextMenuItems = useMemo( + () => [ + { + key: "clear_cache", + icon: , + text: "Clear cached responses", + onClick: () => { + // Clear responses associated with this node + clearCachedResponses(id); + // Remove items and reset status + setStatus(Status.NONE); + setJSONResponses(null); + }, + }, + ], + [id], + ); + return ( - + {same_resp_text_counts[r].length > 1 ? ( - {same_resp_text_counts[r]} times + {same_resp_text_counts[r].length} times ) : ( <> diff --git a/chainforge/react-server/src/VisNode.tsx b/chainforge/react-server/src/VisNode.tsx index a581427..699f774 100644 --- a/chainforge/react-server/src/VisNode.tsx +++ b/chainforge/react-server/src/VisNode.tsx @@ -873,8 +873,8 @@ const VisNode: React.FC = ({ data, id }) => { .then(function (resps) { if (resps && resps.length > 0) { // Store responses and extract + store vars - // @ts-expect-error toReversed exists, but TypeScript does not see it. - setResponses(resps.toReversed()); + // toReversed exists, but TypeScript does not see it. + setResponses((resps as any).toReversed()); // Find all vars in responses let varnames: string[] | Set = new Set(); diff --git a/chainforge/react-server/src/backend/backend.ts b/chainforge/react-server/src/backend/backend.ts index b6e24cc..6b2a048 100644 --- a/chainforge/react-server/src/backend/backend.ts +++ b/chainforge/react-server/src/backend/backend.ts @@ -1369,6 +1369,23 @@ export async function grabResponses( return grabbed_resps; } +/** + * Deletes cache data for the responses indexed by 'id'. + * @param id The id of the cached responses to clear. + */ +export async function clearCachedResponses(id: string): Promise { + if (!StorageCache.has(`${id}.json`)) { + console.error(`Did not find cache data for id ${id}`); + return false; + } + + // Clear all cache items related to 'id' + for (const k of get_cache_keys_related_to_id(id, true)) + StorageCache.clear(k); + + return true; +} + /** * Exports the cache'd data relevant to the given node id(s). * diff --git a/chainforge/react-server/src/backend/cache.ts b/chainforge/react-server/src/backend/cache.ts index 3700b54..2f1d965 100644 --- a/chainforge/react-server/src/backend/cache.ts +++ b/chainforge/react-server/src/backend/cache.ts @@ -61,12 +61,19 @@ export default class StorageCache { StorageCache.getInstance().storeCacheData(key, data); } - private clearCache(): void { - this.data = {}; + private clearCache(key?: string): void { + if (key === undefined) + this.data = {}; + else if (key in this.data) + delete this.data[key]; } - public static clear(): void { - StorageCache.getInstance().clearCache(); + /** + * Clears data in the cache. + * @param key Optional. A specific key to clear in the storage dict. If undefined, clears all data. + */ + public static clear(key?: string): void { + StorageCache.getInstance().clearCache(key); } /** diff --git a/chainforge/react-server/src/backend/utils.ts b/chainforge/react-server/src/backend/utils.ts index c30f727..e19257b 100644 --- a/chainforge/react-server/src/backend/utils.ts +++ b/chainforge/react-server/src/backend/utils.ts @@ -1232,7 +1232,6 @@ export async function call_ollama_provider( function to_bedrock_chat_history( chat_history: ChatHistory, ): BedrockChatMessage[] { - const role_map: Dict = { assistant: "ai", user: "human",