From 0c0f78da65aa3e36ad9a00cd146f366845d7eced Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Sat, 16 Mar 2024 21:02:23 -0400 Subject: [PATCH 1/6] Feat: Add in ability to delete a single output by prompt name in editor --- .gitignore | 2 +- .../editor/client/src/LocalEditor.tsx | 7 ++++ .../client/src/components/AIConfigEditor.tsx | 32 +++++++++++++++++++ .../src/components/prompt/PromptContainer.tsx | 29 ++++++++++++++++- .../components/prompt/PromptsContainer.tsx | 4 +++ .../editor/client/src/reducers/actions.ts | 6 ++++ .../client/src/reducers/aiconfigReducer.ts | 19 +++++++++++ .../editor/client/src/shared/types.ts | 1 + .../aiconfig/editor/client/src/utils/api.ts | 1 + python/src/aiconfig/editor/server/server.py | 26 ++++++++++++++- 10 files changed, 124 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 0e4052c2a..91c0adfc5 100644 --- a/.gitignore +++ b/.gitignore @@ -141,4 +141,4 @@ dist __pycache__/ models *.egg-info -.hypothesis \ No newline at end of file +.hypothesis diff --git a/python/src/aiconfig/editor/client/src/LocalEditor.tsx b/python/src/aiconfig/editor/client/src/LocalEditor.tsx index bbd66bc46..1e47426b0 100644 --- a/python/src/aiconfig/editor/client/src/LocalEditor.tsx +++ b/python/src/aiconfig/editor/client/src/LocalEditor.tsx @@ -132,6 +132,12 @@ export default function LocalEditor() { return await ufetch.post(ROUTE_TABLE.CLEAR_OUTPUTS, {}); }, []); + const deleteOutput = useCallback(async (promptName: string) => { + return await ufetch.post(ROUTE_TABLE.DELETE_OUTPUT, { + prompt_name: promptName, + }); + }, []); + const runPrompt = useCallback( async ( promptName: string, @@ -249,6 +255,7 @@ export default function LocalEditor() { addPrompt, cancel, clearOutputs, + deleteOutput, deleteModelSettings, deletePrompt, getModels, diff --git a/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx b/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx index 653759114..91252356b 100644 --- a/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx +++ b/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx @@ -122,6 +122,7 @@ export type AIConfigCallbacks = { ) => Promise<{ aiconfig: AIConfig }>; cancel: (cancellationToken: string) => Promise; clearOutputs: () => Promise<{ aiconfig: AIConfig }>; + deleteOutput: (promptName: string) => Promise<{ aiconfig: AIConfig }>; deleteModelSettings?: (modelName: string) => Promise; deletePrompt: (promptName: string) => Promise; download?: () => Promise; @@ -811,6 +812,35 @@ function AIConfigEditorBase({ [deletePromptCallback, dispatch, logEventHandler, showNotification] ); + const deleteOutputCallback = callbacks?.deleteOutput; + const onDeleteOutput = useCallback( + async (promptName: string) => { + if (!deleteOutputCallback) { + // Just no-op if no callback specified. We could technically perform + // client-side updates but that might be confusing + return; + } + + dispatch({ + type: "DELETE_OUTPUT", + id: promptName, + }); + logEventHandler?.("DELETE_OUTPUT"); + + try { + await deleteOutputCallback(promptName); + } catch (err: unknown) { + const message = (err as RequestCallbackError).message ?? null; + showNotification({ + title: "Error deleting output for prompt", + message, + type: "error", + }); + } + }, + [deleteOutputCallback, dispatch, logEventHandler, showNotification] + ); + const clearOutputsCallback = callbacks?.clearOutputs; const onClearOutputs = useCallback(async () => { if (!clearOutputsCallback) { @@ -1229,6 +1259,7 @@ function AIConfigEditorBase({ onUpdateParameters={onUpdateGlobalParameters} /> void; onChangePromptName: (promptId: string, newName: string) => void; onRunPrompt(promptId: string): Promise; + onDeleteOutput: (promptId: string) => void; onUpdateModel: (promptId: string, newModel?: string) => void; onUpdateModelSettings: ( promptId: string, @@ -34,6 +35,7 @@ type Props = { onUpdatePromptMetadata: (promptId: string, newMetadata: JSONObject) => void; defaultConfigModelName?: string; isRunButtonDisabled?: boolean; + readOnly?: boolean; }; export const PROMPT_CONTAINER_HEIGHT_MAP = new Map(); @@ -55,14 +57,20 @@ const useStyles = createStyles((theme) => ({ borderLeft: "none", borderTopRightRadius: "4px", }, + deleteOutput: { + marginBottom: "8px", + marginTop: "8px", + } })); export default memo(function PromptContainer({ + readOnly, prompt, cancel, getModels, onChangePromptInput, onChangePromptName, + onDeleteOutput, defaultConfigModelName, onRunPrompt, onUpdateModel, @@ -104,6 +112,11 @@ export default memo(function PromptContainer({ [promptId, onRunPrompt] ); + const deleteOutput = useCallback( + async () => await onDeleteOutput(promptId), + [promptId, onDeleteOutput] + ); + const onCancelRun = useCallback(async () => { if (!cancel) { return; @@ -190,7 +203,21 @@ export default memo(function PromptContainer({ {prompt.outputs && prompt.outputs.length > 0 && ( <> + + {!readOnly && prompt.outputs?.length && deleteOutput ? ( +
+ +
+ ) : null} +
)} diff --git a/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx b/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx index 4ddc3b49a..00beb84ff 100644 --- a/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx +++ b/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx @@ -18,6 +18,7 @@ type Props = { ) => Promise; onChangePromptName: (promptId: string, newName: string) => Promise; onDeletePrompt: (promptId: string) => Promise; + onDeleteOutput: (promptId: string) => Promise; onRunPrompt: (promptId: string) => Promise; onUpdatePromptMetadata: ( promptId: string, @@ -34,6 +35,7 @@ type Props = { ) => Promise; prompts: ClientPrompt[]; runningPromptId?: string; + readOnly?: boolean; }; const useStyles = createStyles((theme) => ({ @@ -71,10 +73,12 @@ export default memo(function PromptsContainer(props: Props) { /> )} { + if (prompt._ui.id === action.id) { + return { + ...prompt, + outputs: undefined, + }; + } else { + return prompt; + } + }); + + return { + ...dirtyState, + prompts, + }; + } + case "DELETE_GLOBAL_MODEL_SETTINGS": { const newModels = { ...state.metadata.models }; delete newModels[action.modelName]; diff --git a/python/src/aiconfig/editor/client/src/shared/types.ts b/python/src/aiconfig/editor/client/src/shared/types.ts index 4d9eddf91..f1575e306 100644 --- a/python/src/aiconfig/editor/client/src/shared/types.ts +++ b/python/src/aiconfig/editor/client/src/shared/types.ts @@ -66,6 +66,7 @@ export function aiConfigToClientConfig(aiconfig: AIConfig): ClientAIConfig { export type LogEvent = | "ADD_PROMPT" | "CLEAR_OUTPUTS" + | "DELETE_OUTPUT" | "DELETE_GLOBAL_MODEL_SETTINGS" | "DELETE_PROMPT" | "DOWNLOAD_BUTTON_CLICKED" diff --git a/python/src/aiconfig/editor/client/src/utils/api.ts b/python/src/aiconfig/editor/client/src/utils/api.ts index fe07b9b5a..d8495ef09 100644 --- a/python/src/aiconfig/editor/client/src/utils/api.ts +++ b/python/src/aiconfig/editor/client/src/utils/api.ts @@ -12,6 +12,7 @@ export const ROUTE_TABLE = { ADD_PROMPT: urlJoin(API_ENDPOINT, "/add_prompt"), CANCEL: urlJoin(API_ENDPOINT, "/cancel"), CLEAR_OUTPUTS: urlJoin(API_ENDPOINT, "/clear_outputs"), + DELETE_OUTPUT: urlJoin(API_ENDPOINT, "/delete_output"), DELETE_MODEL: urlJoin(API_ENDPOINT, "/delete_model"), DELETE_PROMPT: urlJoin(API_ENDPOINT, "/delete_prompt"), GET_AICONFIGRC: urlJoin(API_ENDPOINT, "/get_aiconfigrc"), diff --git a/python/src/aiconfig/editor/server/server.py b/python/src/aiconfig/editor/server/server.py index 2c7918157..a48916b76 100644 --- a/python/src/aiconfig/editor/server/server.py +++ b/python/src/aiconfig/editor/server/server.py @@ -788,6 +788,7 @@ def clear_outputs() -> FlaskResponse: """ Clears all outputs in the server state's AIConfig. """ + method_name = MethodName("clear_outputs") state = get_server_state(app) aiconfig = state.aiconfig request_json = request.get_json() @@ -811,9 +812,32 @@ def _op( signature: dict[str, Type[Any]] = {} return run_aiconfig_operation_with_request_json( - aiconfig, request_json, f"method_", _op, signature + aiconfig, request_json, f"method_{method_name}", _op, signature ) +@app.route("/api/delete_output", methods=["POST"]) +def delete_output() -> FlaskResponse: + """ + Clears a single outputs in the server state's AIConfig based on prompt name. + """ + method_name = MethodName("delete_output") + state = get_server_state(app) + aiconfig = state.aiconfig + request_json = request.get_json() + + if aiconfig is None: + LOGGER.info("No AIConfig in memory, can't run clear outputs.") + return HttpResponseWithAIConfig( + message="No AIConfig in memory, can't run clear outputs.", + code=400, + aiconfig=None, + ).to_flask_format() + + signature: dict[str, Type[Any]] = { "prompt_name": str } + operation = make_op_run_method(method_name) + return run_aiconfig_operation_with_request_json( + aiconfig, request_json, f"method_{method_name}", operation, signature + ) @app.route("/api/get_aiconfigrc", methods=["GET"]) def get_aiconfigrc() -> FlaskResponse: From c7c2d17ab3ade215e9b5bf184074a71d7a4de8e5 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Sun, 17 Mar 2024 14:25:48 -0400 Subject: [PATCH 2/6] Update to move delete output button to context menu --- .../src/components/prompt/PromptContainer.tsx | 27 +---------------- .../components/prompt/PromptMenuButton.tsx | 30 +++++++++++++++++-- .../components/prompt/PromptsContainer.tsx | 4 +-- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/python/src/aiconfig/editor/client/src/components/prompt/PromptContainer.tsx b/python/src/aiconfig/editor/client/src/components/prompt/PromptContainer.tsx index e1341cfa2..0822b7283 100644 --- a/python/src/aiconfig/editor/client/src/components/prompt/PromptContainer.tsx +++ b/python/src/aiconfig/editor/client/src/components/prompt/PromptContainer.tsx @@ -3,7 +3,7 @@ import PromptInputRenderer from "./prompt_input/PromptInputRenderer"; import PromptOutputsRenderer from "./prompt_outputs/PromptOutputsRenderer"; import { ClientPrompt } from "../../shared/types"; import { getPromptSchema } from "../../utils/promptUtils"; -import { Flex, Card, createStyles, Button } from "@mantine/core"; +import { Flex, Card, createStyles } from "@mantine/core"; import { PromptInput as AIConfigPromptInput, JSONObject } from "aiconfig"; import { memo, useCallback, useEffect, useMemo, useRef } from "react"; import PromptOutputBar from "./PromptOutputBar"; @@ -22,7 +22,6 @@ type Props = { ) => void; onChangePromptName: (promptId: string, newName: string) => void; onRunPrompt(promptId: string): Promise; - onDeleteOutput: (promptId: string) => void; onUpdateModel: (promptId: string, newModel?: string) => void; onUpdateModelSettings: ( promptId: string, @@ -35,7 +34,6 @@ type Props = { onUpdatePromptMetadata: (promptId: string, newMetadata: JSONObject) => void; defaultConfigModelName?: string; isRunButtonDisabled?: boolean; - readOnly?: boolean; }; export const PROMPT_CONTAINER_HEIGHT_MAP = new Map(); @@ -57,20 +55,14 @@ const useStyles = createStyles((theme) => ({ borderLeft: "none", borderTopRightRadius: "4px", }, - deleteOutput: { - marginBottom: "8px", - marginTop: "8px", - } })); export default memo(function PromptContainer({ - readOnly, prompt, cancel, getModels, onChangePromptInput, onChangePromptName, - onDeleteOutput, defaultConfigModelName, onRunPrompt, onUpdateModel, @@ -112,11 +104,6 @@ export default memo(function PromptContainer({ [promptId, onRunPrompt] ); - const deleteOutput = useCallback( - async () => await onDeleteOutput(promptId), - [promptId, onDeleteOutput] - ); - const onCancelRun = useCallback(async () => { if (!cancel) { return; @@ -205,18 +192,6 @@ export default memo(function PromptContainer({ <> - {!readOnly && prompt.outputs?.length && deleteOutput ? ( -
- -
- ) : null}
diff --git a/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx b/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx index 23e2e41b5..118904c94 100644 --- a/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx +++ b/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx @@ -1,6 +1,7 @@ import { Button, Menu, createStyles } from "@mantine/core"; -import { IconDotsVertical, IconTrash } from "@tabler/icons-react"; -import { memo } from "react"; +import { IconDotsVertical, IconEraser, IconTrash } from "@tabler/icons-react"; +import { memo, useCallback } from "react"; +import { ClientPrompt } from "../../shared/types"; const useStyles = createStyles(() => ({ promptMenuButton: { @@ -10,13 +11,27 @@ const useStyles = createStyles(() => ({ export default memo(function PromptMenuButton({ promptId, + prompt, + onDeleteOutput, onDeletePrompt, }: { promptId: string; + prompt: ClientPrompt; onDeletePrompt: (id: string) => void; + onDeleteOutput: (promptId: string) => void; }) { const { classes } = useStyles(); + const deleteOutput = useCallback( + async () => await onDeleteOutput(promptId), + [promptId, onDeleteOutput] + ); + + const deletePrompt = useCallback( + async () => await onDeletePrompt(promptId), + [promptId, onDeletePrompt] + ); + return ( @@ -34,10 +49,19 @@ export default memo(function PromptMenuButton({ } color="red" - onClick={() => onDeletePrompt(promptId)} + onClick={deletePrompt} > Delete Prompt + {prompt.outputs?.length ? ( + } + color="red" + onClick={deleteOutput} + > + Clear Output + + ) : null} ); diff --git a/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx b/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx index 00beb84ff..73f2cd938 100644 --- a/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx +++ b/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx @@ -68,17 +68,17 @@ export default memo(function PromptsContainer(props: Props) { {!readOnly && ( props.onDeletePrompt(prompt._ui.id)} + onDeleteOutput={props.onDeleteOutput} /> )} Date: Sun, 17 Mar 2024 15:47:33 -0400 Subject: [PATCH 3/6] Fix client to pass in prompt name --- .../editor/client/src/components/AIConfigEditor.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx b/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx index 91252356b..ddca85d72 100644 --- a/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx +++ b/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx @@ -814,7 +814,7 @@ function AIConfigEditorBase({ const deleteOutputCallback = callbacks?.deleteOutput; const onDeleteOutput = useCallback( - async (promptName: string) => { + async (promptId: string) => { if (!deleteOutputCallback) { // Just no-op if no callback specified. We could technically perform // client-side updates but that might be confusing @@ -823,12 +823,16 @@ function AIConfigEditorBase({ dispatch({ type: "DELETE_OUTPUT", - id: promptName, + id: promptId, }); logEventHandler?.("DELETE_OUTPUT"); try { - await deleteOutputCallback(promptName); + const prompt = getPrompt(stateRef.current, promptId); + if (!prompt) { + throw new Error(`Could not find prompt with id ${promptId}`); + } + await deleteOutputCallback(prompt.name); } catch (err: unknown) { const message = (err as RequestCallbackError).message ?? null; showNotification({ From 8b4b55994a63737534142c2d30b34788fcc95cc4 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Sun, 17 Mar 2024 16:41:58 -0400 Subject: [PATCH 4/6] Update styling --- .../src/components/prompt/PromptMenuButton.tsx | 16 ++++++++-------- python/src/aiconfig/editor/server/server.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx b/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx index 118904c94..4847121e1 100644 --- a/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx +++ b/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx @@ -46,22 +46,22 @@ export default memo(function PromptMenuButton({ - } - color="red" - onClick={deletePrompt} - > - Delete Prompt - {prompt.outputs?.length ? ( } - color="red" + color="white" onClick={deleteOutput} > Clear Output ) : null} + } + color="red" + onClick={deletePrompt} + > + Delete Prompt + ); diff --git a/python/src/aiconfig/editor/server/server.py b/python/src/aiconfig/editor/server/server.py index a48916b76..76c9d4d66 100644 --- a/python/src/aiconfig/editor/server/server.py +++ b/python/src/aiconfig/editor/server/server.py @@ -833,7 +833,7 @@ def delete_output() -> FlaskResponse: aiconfig=None, ).to_flask_format() - signature: dict[str, Type[Any]] = { "prompt_name": str } + signature: dict[str, Type[Any]] = {"prompt_name": str} operation = make_op_run_method(method_name) return run_aiconfig_operation_with_request_json( aiconfig, request_json, f"method_{method_name}", operation, signature From cf0cf992cc072a7d94ab13976469ea6695da5a69 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Tue, 19 Mar 2024 00:03:19 -0400 Subject: [PATCH 5/6] Update client changes and server code changes based on PR comments for cleanliness and reusability --- .../client/src/components/AIConfigEditor.tsx | 1 - .../src/components/prompt/PromptContainer.tsx | 128 +++++++++++------- .../components/prompt/PromptMenuButton.tsx | 30 ++-- .../components/prompt/PromptsContainer.tsx | 22 ++- .../client/src/reducers/aiconfigReducer.ts | 25 ++-- python/src/aiconfig/editor/server/server.py | 16 +-- 6 files changed, 112 insertions(+), 110 deletions(-) diff --git a/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx b/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx index ddca85d72..04e2b78b2 100644 --- a/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx +++ b/python/src/aiconfig/editor/client/src/components/AIConfigEditor.tsx @@ -1263,7 +1263,6 @@ function AIConfigEditorBase({ onUpdateParameters={onUpdateGlobalParameters} /> void; onChangePromptName: (promptId: string, newName: string) => void; onRunPrompt(promptId: string): Promise; + onDeletePrompt(promptId: string): void; + onDeleteOutput(promptId: string): void; onUpdateModel: (promptId: string, newModel?: string) => void; onUpdateModelSettings: ( promptId: string, @@ -65,6 +69,8 @@ export default memo(function PromptContainer({ onChangePromptName, defaultConfigModelName, onRunPrompt, + onDeletePrompt, + onDeleteOutput, onUpdateModel, onUpdateModelSettings, onUpdateParameters, @@ -72,6 +78,7 @@ export default memo(function PromptContainer({ isRunButtonDisabled = false, }: Props) { const { classes } = useStyles(); + const { readOnly } = useContext(AIConfigContext); const promptId = prompt._ui.id; const onChangeInput = useCallback( (newInput: AIConfigPromptInput) => onChangePromptInput(promptId, newInput), @@ -104,6 +111,16 @@ export default memo(function PromptContainer({ [promptId, onRunPrompt] ); + const deletePrompt = useCallback( + async () => await onDeletePrompt(promptId), + [promptId, onDeletePrompt] + ); + + const deleteOutput = useCallback( + async () => await onDeleteOutput(promptId), + [promptId, onDeleteOutput] + ); + const onCancelRun = useCallback(async () => { if (!cancel) { return; @@ -158,56 +175,65 @@ export default memo(function PromptContainer({ const inputSchema = promptSchema?.input; return ( - - - - - - - - - - {prompt.outputs && prompt.outputs.length > 0 && ( - <> - - - - - - )} - - -
- + {!readOnly && ( + -
-
+ )} + + + + + + + + + + {prompt.outputs && prompt.outputs.length > 0 && ( + <> + + + + + + )} + + +
+ +
+
+ ); }); diff --git a/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx b/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx index 4847121e1..b5f963783 100644 --- a/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx +++ b/python/src/aiconfig/editor/client/src/components/prompt/PromptMenuButton.tsx @@ -1,7 +1,6 @@ import { Button, Menu, createStyles } from "@mantine/core"; import { IconDotsVertical, IconEraser, IconTrash } from "@tabler/icons-react"; -import { memo, useCallback } from "react"; -import { ClientPrompt } from "../../shared/types"; +import { memo } from "react"; const useStyles = createStyles(() => ({ promptMenuButton: { @@ -10,28 +9,16 @@ const useStyles = createStyles(() => ({ })); export default memo(function PromptMenuButton({ - promptId, - prompt, + showDeleteOutput, onDeleteOutput, onDeletePrompt, }: { - promptId: string; - prompt: ClientPrompt; - onDeletePrompt: (id: string) => void; - onDeleteOutput: (promptId: string) => void; + showDeleteOutput: boolean; + onDeletePrompt: () => void; + onDeleteOutput: () => void; }) { const { classes } = useStyles(); - const deleteOutput = useCallback( - async () => await onDeleteOutput(promptId), - [promptId, onDeleteOutput] - ); - - const deletePrompt = useCallback( - async () => await onDeletePrompt(promptId), - [promptId, onDeletePrompt] - ); - return ( @@ -46,11 +33,10 @@ export default memo(function PromptMenuButton({ - {prompt.outputs?.length ? ( + {showDeleteOutput ? ( } - color="white" - onClick={deleteOutput} + onClick={onDeleteOutput} > Clear Output @@ -58,7 +44,7 @@ export default memo(function PromptMenuButton({ } color="red" - onClick={deletePrompt} + onClick={onDeletePrompt} > Delete Prompt diff --git a/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx b/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx index 73f2cd938..32dc8dc03 100644 --- a/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx +++ b/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx @@ -3,7 +3,6 @@ import { memo, useContext } from "react"; import AIConfigContext from "../../contexts/AIConfigContext"; import AddPromptButton from "./AddPromptButton"; import { ClientPrompt } from "../../shared/types"; -import PromptMenuButton from "./PromptMenuButton"; import PromptContainer from "./PromptContainer"; import { JSONObject, PromptInput } from "aiconfig"; @@ -35,7 +34,6 @@ type Props = { ) => Promise; prompts: ClientPrompt[]; runningPromptId?: string; - readOnly?: boolean; }; const useStyles = createStyles((theme) => ({ @@ -55,25 +53,19 @@ export default memo(function PromptsContainer(props: Props) {
{!readOnly && ( props.onAddPrompt(0, model)} + getModels={props.getModels} + addPrompt={(model: string) => props.onAddPrompt(0, model)} /> - )} + )} {props.prompts.map((prompt: ClientPrompt, i: number) => { + const promptId = prompt._ui.id; const isAnotherPromptRunning = props.runningPromptId !== undefined && - props.runningPromptId !== prompt._ui.id; + props.runningPromptId !== promptId; + return ( - {!readOnly && ( - props.onDeletePrompt(prompt._ui.id)} - onDeleteOutput={props.onDeleteOutput} - /> - )} { - if (prompt._ui.id === action.id) { - return { - ...prompt, - outputs: undefined, - }; - } else { - return prompt; - } - }); + const clearOutput = (statePrompt: ClientPrompt) => { + return { + ...statePrompt, + outputs: undefined, + }; + } - return { - ...dirtyState, - prompts, - }; + return reduceReplacePrompt( + dirtyState, + action.id, + clearOutput + ); } case "DELETE_GLOBAL_MODEL_SETTINGS": { diff --git a/python/src/aiconfig/editor/server/server.py b/python/src/aiconfig/editor/server/server.py index 76c9d4d66..9374cf284 100644 --- a/python/src/aiconfig/editor/server/server.py +++ b/python/src/aiconfig/editor/server/server.py @@ -1,18 +1,22 @@ import asyncio import copy import ctypes -import dotenv import json import logging +import os import threading import time import uuid import webbrowser -import os from typing import Any, Dict, Literal, Type, Union +import dotenv import lastmile_utils.lib.core.api as core_utils import result +from flask import Flask, Response, request, stream_with_context +from flask_cors import CORS +from result import Err, Ok, Result + from aiconfig.Config import AIConfigRuntime from aiconfig.editor.server.queue_iterator import ( STOP_STREAMING_SIGNAL, @@ -42,10 +46,6 @@ ) from aiconfig.model_parser import InferenceOptions from aiconfig.registry import ModelParserRegistry -from flask import Flask, Response, request, stream_with_context -from flask_cors import CORS -from result import Err, Ok, Result - from aiconfig.schema import ExecuteResult, Output, Prompt, PromptMetadata logging.getLogger("werkzeug").disabled = True @@ -812,7 +812,7 @@ def _op( signature: dict[str, Type[Any]] = {} return run_aiconfig_operation_with_request_json( - aiconfig, request_json, f"method_{method_name}", _op, signature + aiconfig, request_json, method_name, _op, signature ) @app.route("/api/delete_output", methods=["POST"]) @@ -836,7 +836,7 @@ def delete_output() -> FlaskResponse: signature: dict[str, Type[Any]] = {"prompt_name": str} operation = make_op_run_method(method_name) return run_aiconfig_operation_with_request_json( - aiconfig, request_json, f"method_{method_name}", operation, signature + aiconfig, request_json, method_name, operation, signature ) @app.route("/api/get_aiconfigrc", methods=["GET"]) From c299c4b659be262706a8bf845b0f30c15a517b7f Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Tue, 19 Mar 2024 00:37:32 -0400 Subject: [PATCH 6/6] Style tweaks --- .../client/src/components/prompt/PromptsContainer.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx b/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx index 32dc8dc03..56f711f06 100644 --- a/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx +++ b/python/src/aiconfig/editor/client/src/components/prompt/PromptsContainer.tsx @@ -53,10 +53,10 @@ export default memo(function PromptsContainer(props: Props) {
{!readOnly && ( props.onAddPrompt(0, model)} + getModels={props.getModels} + addPrompt={(model: string) => props.onAddPrompt(0, model)} /> - )} + )} {props.prompts.map((prompt: ClientPrompt, i: number) => { const promptId = prompt._ui.id; const isAnotherPromptRunning =