Skip to content

Commit

Permalink
[editor] Run Prompt (non-streaming)
Browse files Browse the repository at this point in the history
# [editor] Run Prompt (non-streaming)

With non-streaming /run endpoint properly returning the response now, we can update the client config with the resulting output. We can also leverage the client-side `_ui` state for maintaining 'isRunning' state to show a spinner / disable the execute button for now (TODO: we may need to handle canceling execution as well).


https://github.com/lastmile-ai/aiconfig/assets/5060851/67fa793a-9a60-4285-a7d1-69fff633d6a6
  • Loading branch information
Ryan Holinshead committed Dec 29, 2023
1 parent 6367402 commit 4a1b8ab
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export type AIConfigCallbacks = {
) => Promise<{ aiconfig: AIConfig }>;
deletePrompt: (promptName: string) => Promise<void>;
getModels: (search: string) => Promise<string[]>;
runPrompt: (promptName: string) => Promise<void>;
runPrompt: (promptName: string) => Promise<{ aiconfig: AIConfig }>;
save: (aiconfig: AIConfig) => Promise<void>;
updateModel: (
promptName?: string,
Expand Down Expand Up @@ -307,9 +307,22 @@ export default function EditorContainer({

const onRunPrompt = useCallback(
async (promptId: string) => {
const promptName = getPrompt(stateRef.current, promptId)!.name;
const action: AIConfigReducerAction = {
type: "RUN_PROMPT",
id: promptId,
};

dispatch(action);

try {
await callbacks.runPrompt(promptName);
const promptName = getPrompt(stateRef.current, promptId)!.name;
const serverConfigRes = await callbacks.runPrompt(promptName);

dispatch({
type: "CONSOLIDATE_AICONFIG",
action,
config: serverConfigRes.aiconfig,
});
} catch (err: any) {
showNotification({
title: "Error running prompt",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type AIConfigReducerAction =
export type MutateAIConfigAction =
| AddPromptAction
| DeletePromptAction
| RunPromptAction
| UpdatePromptInputAction
| UpdatePromptNameAction
| UpdatePromptModelAction
Expand All @@ -32,6 +33,11 @@ export type DeletePromptAction = {
id: string;
};

export type RunPromptAction = {
type: "RUN_PROMPT";
id: string;
};

export type UpdatePromptInputAction = {
type: "UPDATE_PROMPT_INPUT";
id: string;
Expand Down Expand Up @@ -131,6 +137,22 @@ function reduceConsolidateAIConfig(
consolidatePrompt
);
}
case "RUN_PROMPT": {
return reduceReplacePrompt(state, action.id, (prompt) => {
const responsePrompt = responseConfig.prompts.find(
(resPrompt) => resPrompt.name === prompt.name
);

return {
...prompt,
_ui: {
...prompt._ui,
isRunning: false,
},
outputs: responsePrompt!.outputs,
};
});
}
case "UPDATE_PROMPT_INPUT": {
return reduceReplacePrompt(state, action.id, consolidatePrompt);
}
Expand All @@ -154,6 +176,15 @@ export default function aiconfigReducer(
prompts: state.prompts.filter((prompt) => prompt._ui.id !== action.id),
};
}
case "RUN_PROMPT": {
return reduceReplacePrompt(state, action.id, (prompt) => ({
...prompt,
_ui: {
...prompt._ui,
isRunning: true,
},
}));
}
case "UPDATE_PROMPT_INPUT": {
return reduceReplaceInput(state, action.id, () => action.input);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ export default memo(function PromptActionBar({
<IconClearAll />
</ActionIcon>
</Flex>
<RunPromptButton runPrompt={onRunPrompt} size="compact" />
<RunPromptButton
runPrompt={onRunPrompt}
isRunning={prompt._ui.isRunning}
size="compact"
/>
</Flex>
)}
</Flex>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Button, createStyles, Flex, Text } from "@mantine/core";
import { IconPlayerPlayFilled } from "@tabler/icons-react";
import { Button, createStyles, Flex, Loader, Text } from "@mantine/core";
import { IconPlayerPlayFilled, IconPlayerStop } from "@tabler/icons-react";
import { memo } from "react";

type Props = {
isRunning?: boolean;
runPrompt: () => Promise<void>;
size: "compact" | "full";
};
Expand All @@ -15,18 +16,36 @@ const useStyles = createStyles(() => ({
},
}));

export default memo(function RunPromptButton({ runPrompt, size }: Props) {
export default memo(function RunPromptButton({
runPrompt,
size,
isRunning = false,
}: Props) {
const { classes } = useStyles();
return (
<Button
onClick={runPrompt}
disabled={isRunning}
p="xs"
size="xs"
fullWidth={size === "full"}
className={classes.executeButton}
>
<IconPlayerPlayFilled size="16" />
{size === "full" && <Text ml="0.5em">Run</Text>}
{isRunning ? (
<div>
<Loader
style={{ position: "absolute", top: 5, left: 8 }}
size="xs"
color="white"
/>
<IconPlayerStop fill="white" size={14} />
</div>
) : (
<>
<IconPlayerPlayFilled size="16" />
{size === "full" && <Text ml="0.5em">Run</Text>}
</>
)}
</Button>
);
});
1 change: 1 addition & 0 deletions python/src/aiconfig/editor/client/src/shared/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type EditorFile = {
export type ClientPrompt = Prompt & {
_ui: {
id: string;
isRunning?: boolean;
};
};

Expand Down

0 comments on commit 4a1b8ab

Please sign in to comment.