diff --git a/app/src/pages/prompt/PromptIndexPage.tsx b/app/src/pages/prompt/PromptIndexPage.tsx index c342d82d89..b083c769f7 100644 --- a/app/src/pages/prompt/PromptIndexPage.tsx +++ b/app/src/pages/prompt/PromptIndexPage.tsx @@ -2,7 +2,13 @@ import React, { useState } from "react"; import { Heading } from "react-aria-components"; import { graphql, useFragment } from "react-relay"; -import { Card, Flex, View } from "@arizeai/components"; +import { + Accordion, + AccordionItem, + Card, + Flex, + View, +} from "@arizeai/components"; import { CodeLanguage, @@ -13,6 +19,7 @@ import { import { PromptIndexPage__aside$key } from "./__generated__/PromptIndexPage__aside.graphql"; import { PromptIndexPage__main$key } from "./__generated__/PromptIndexPage__main.graphql"; import { ChatTemplateMessage } from "./ChatTemplateMessage"; +import { PromptInvocationParameters } from "./PromptInvocationParameters"; import { usePromptIdLoader } from "./usePromptIdLoader"; export function PromptIndexPage() { @@ -26,46 +33,72 @@ export function PromptIndexPageContent({ prompt: PromptIndexPage__main$key; }) { const [language, setLanguage] = useState("Python"); - const data = useFragment( + const data = useFragment( graphql` fragment PromptIndexPage__main on Prompt { + promptVersions { + edges { + node { + ...PromptInvocationParameters__main + } + } + } ...PromptIndexPage__aside } `, prompt ); + + const latestVersion = data?.promptVersions?.edges?.[0]?.node; + return ( - - - - - - - - - - model configuration - - - } + + + - - - + + + + + + + + + + + + + No Tools Specified + + + + + } + > + + + + diff --git a/app/src/pages/prompt/PromptInvocationParameters.tsx b/app/src/pages/prompt/PromptInvocationParameters.tsx new file mode 100644 index 0000000000..59edef6e67 --- /dev/null +++ b/app/src/pages/prompt/PromptInvocationParameters.tsx @@ -0,0 +1,71 @@ +import React, { useMemo } from "react"; +import { graphql, useFragment } from "react-relay"; +import isObject from "lodash/isObject"; + +import { Flex, List, ListItem, Text, View } from "@arizeai/components"; + +import { PromptInvocationParameters__main$key } from "./__generated__/PromptInvocationParameters__main.graphql"; + +function PromptInvocationParameterItem({ + keyName, + value, +}: { + keyName: string; + value: unknown; +}) { + return ( + + + {keyName} + {String(value)} + + + ); +} + +type PromptInvocationParametersProps = { + promptVersion: PromptInvocationParameters__main$key; +}; + +export function PromptInvocationParameters({ + promptVersion, +}: PromptInvocationParametersProps) { + const { invocationParameters } = + useFragment( + graphql` + fragment PromptInvocationParameters__main on PromptVersion { + invocationParameters + } + `, + promptVersion + ); + const parameters = useMemo(() => { + if (!isObject(invocationParameters)) { + return []; + } + return Object.entries(invocationParameters).map(([key, value]) => ({ + key, + value, + })); + }, [invocationParameters]); + + if (parameters.length === 0) { + return ( + + + No parameters saved for this prompt + + + ); + } + + return ( + + {parameters.map(({ key, value }) => ( + + + + ))} + + ); +} diff --git a/app/src/pages/prompt/PromptVersionDetailsPage.tsx b/app/src/pages/prompt/PromptVersionDetailsPage.tsx index d6dd6771a7..921ea18f21 100644 --- a/app/src/pages/prompt/PromptVersionDetailsPage.tsx +++ b/app/src/pages/prompt/PromptVersionDetailsPage.tsx @@ -1,9 +1,16 @@ import React from "react"; import { useLoaderData } from "react-router"; -import { Flex, Text, View } from "@arizeai/components"; +import { + Accordion, + AccordionItem, + Card, + Flex, + View, +} from "@arizeai/components"; import { promptVersionLoaderQuery$data } from "./__generated__/promptVersionLoaderQuery.graphql"; +import { PromptInvocationParameters } from "./PromptInvocationParameters"; export function PromptVersionDetailsPage() { const { promptVersion } = useLoaderData() as promptVersionLoaderQuery$data; @@ -16,10 +23,28 @@ function PromptVersionDetailsPageContent({ promptVersion: promptVersionLoaderQuery$data["promptVersion"]; }) { return ( - - - {promptVersion.id} - {promptVersion.description} + + + + + + + + + ); diff --git a/app/src/pages/prompt/PromptVersionsList.tsx b/app/src/pages/prompt/PromptVersionsList.tsx index 3de56c2efa..133ddb6785 100644 --- a/app/src/pages/prompt/PromptVersionsList.tsx +++ b/app/src/pages/prompt/PromptVersionsList.tsx @@ -58,6 +58,8 @@ type PromptVersionsListProps = { prompt: PromptVersionsList__main$key; }; +const PROMPT_VERSIONS_LIST_WIDTH = 300; + /** * Full height, scrollable, list of prompt versions */ @@ -81,8 +83,13 @@ export const PromptVersionsList = ({ prompt }: PromptVersionsListProps) => { prompt ); return ( - - + + {promptVersions.edges.map(({ version }) => ( ))} diff --git a/app/src/pages/prompt/__generated__/PromptIndexPage__main.graphql.ts b/app/src/pages/prompt/__generated__/PromptIndexPage__main.graphql.ts index 675ab3acde..226c5840ab 100644 --- a/app/src/pages/prompt/__generated__/PromptIndexPage__main.graphql.ts +++ b/app/src/pages/prompt/__generated__/PromptIndexPage__main.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -11,6 +11,13 @@ import { Fragment, ReaderFragment } from 'relay-runtime'; import { FragmentRefs } from "relay-runtime"; export type PromptIndexPage__main$data = { + readonly promptVersions: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly " $fragmentSpreads": FragmentRefs<"PromptInvocationParameters__main">; + }; + }>; + }; readonly " $fragmentSpreads": FragmentRefs<"PromptIndexPage__aside">; readonly " $fragmentType": "PromptIndexPage__main"; }; @@ -25,6 +32,44 @@ const node: ReaderFragment = { "metadata": null, "name": "PromptIndexPage__main", "selections": [ + { + "alias": null, + "args": null, + "concreteType": "PromptVersionConnection", + "kind": "LinkedField", + "name": "promptVersions", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "PromptVersionEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "PromptVersion", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "PromptInvocationParameters__main" + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + }, { "args": null, "kind": "FragmentSpread", @@ -35,6 +80,6 @@ const node: ReaderFragment = { "abstractKey": null }; -(node as any).hash = "25a4ebead60b4112b552a38954277093"; +(node as any).hash = "31cc58fdb7f4d754a6a7fee9f4429846"; export default node; diff --git a/app/src/pages/prompt/__generated__/PromptInvocationParameters__main.graphql.ts b/app/src/pages/prompt/__generated__/PromptInvocationParameters__main.graphql.ts new file mode 100644 index 0000000000..de09cdda78 --- /dev/null +++ b/app/src/pages/prompt/__generated__/PromptInvocationParameters__main.graphql.ts @@ -0,0 +1,42 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { Fragment, ReaderFragment } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type PromptInvocationParameters__main$data = { + readonly invocationParameters: any | null; + readonly " $fragmentType": "PromptInvocationParameters__main"; +}; +export type PromptInvocationParameters__main$key = { + readonly " $data"?: PromptInvocationParameters__main$data; + readonly " $fragmentSpreads": FragmentRefs<"PromptInvocationParameters__main">; +}; + +const node: ReaderFragment = { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "PromptInvocationParameters__main", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "invocationParameters", + "storageKey": null + } + ], + "type": "PromptVersion", + "abstractKey": null +}; + +(node as any).hash = "4f00ab4f0396fffb81a1b068e544cfcf"; + +export default node; diff --git a/app/src/pages/prompt/__generated__/promptLoaderQuery.graphql.ts b/app/src/pages/prompt/__generated__/promptLoaderQuery.graphql.ts index 82f60d5e09..fec0a9ccee 100644 --- a/app/src/pages/prompt/__generated__/promptLoaderQuery.graphql.ts +++ b/app/src/pages/prompt/__generated__/promptLoaderQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<707bc96a0fe2c47c86398c05cf6394cc>> * @lightSyntaxTransform * @nogrep */ @@ -136,7 +136,6 @@ return { "kind": "InlineFragment", "selections": [ (v4/*: any*/), - (v5/*: any*/), { "alias": null, "args": null, @@ -154,27 +153,34 @@ return { "plural": true, "selections": [ { - "alias": "version", + "alias": null, "args": null, "concreteType": "PromptVersion", "kind": "LinkedField", "name": "node", "plural": false, "selections": [ - (v3/*: any*/), - (v5/*: any*/) + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "invocationParameters", + "storageKey": null + }, + (v3/*: any*/) ], "storageKey": null }, { - "alias": null, + "alias": "version", "args": null, "concreteType": "PromptVersion", "kind": "LinkedField", "name": "node", "plural": false, "selections": [ - (v3/*: any*/) + (v3/*: any*/), + (v5/*: any*/) ], "storageKey": null } @@ -183,7 +189,8 @@ return { } ], "storageKey": null - } + }, + (v5/*: any*/) ], "type": "Prompt", "abstractKey": null @@ -194,12 +201,12 @@ return { ] }, "params": { - "cacheID": "1ef3f5e1a5129f8ff263db17d9937da0", + "cacheID": "c75f5c234fcf302f4e4a93447f8daa70", "id": null, "metadata": {}, "name": "promptLoaderQuery", "operationKind": "query", - "text": "query promptLoaderQuery(\n $id: GlobalID!\n) {\n prompt: node(id: $id) {\n __typename\n id\n ... on Prompt {\n name\n ...PromptIndexPage__main\n ...PromptVersionsPageContent__main\n ...PromptLayout__main\n }\n }\n}\n\nfragment PromptIndexPage__aside on Prompt {\n description\n}\n\nfragment PromptIndexPage__main on Prompt {\n ...PromptIndexPage__aside\n}\n\nfragment PromptLayout__main on Prompt {\n promptVersions {\n edges {\n node {\n id\n }\n }\n }\n}\n\nfragment PromptVersionsList__main on Prompt {\n promptVersions {\n edges {\n version: node {\n id\n description\n }\n }\n }\n}\n\nfragment PromptVersionsPageContent__main on Prompt {\n ...PromptVersionsList__main\n}\n" + "text": "query promptLoaderQuery(\n $id: GlobalID!\n) {\n prompt: node(id: $id) {\n __typename\n id\n ... on Prompt {\n name\n ...PromptIndexPage__main\n ...PromptVersionsPageContent__main\n ...PromptLayout__main\n }\n }\n}\n\nfragment PromptIndexPage__aside on Prompt {\n description\n}\n\nfragment PromptIndexPage__main on Prompt {\n promptVersions {\n edges {\n node {\n ...PromptInvocationParameters__main\n }\n }\n }\n ...PromptIndexPage__aside\n}\n\nfragment PromptInvocationParameters__main on PromptVersion {\n invocationParameters\n}\n\nfragment PromptLayout__main on Prompt {\n promptVersions {\n edges {\n node {\n id\n }\n }\n }\n}\n\nfragment PromptVersionsList__main on Prompt {\n promptVersions {\n edges {\n version: node {\n id\n description\n }\n }\n }\n}\n\nfragment PromptVersionsPageContent__main on Prompt {\n ...PromptVersionsList__main\n}\n" } }; })(); diff --git a/app/src/pages/prompt/__generated__/promptVersionLoaderQuery.graphql.ts b/app/src/pages/prompt/__generated__/promptVersionLoaderQuery.graphql.ts index a46242190d..39e3cddeff 100644 --- a/app/src/pages/prompt/__generated__/promptVersionLoaderQuery.graphql.ts +++ b/app/src/pages/prompt/__generated__/promptVersionLoaderQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<795c93bbceb0e58bc52a97442607a8f5>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -9,6 +9,7 @@ // @ts-nocheck import { ConcreteRequest, Query } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; export type PromptTemplateFormat = "FSTRING" | "MUSTACHE" | "NONE"; export type PromptTemplateType = "CHAT" | "STRING"; export type promptVersionLoaderQuery$variables = { @@ -28,6 +29,7 @@ export type promptVersionLoaderQuery$data = { readonly templateType?: PromptTemplateType; readonly tools?: any | null; readonly user?: string | null; + readonly " $fragmentSpreads": FragmentRefs<"PromptInvocationParameters__main">; }; }; export type promptVersionLoaderQuery = { @@ -45,121 +47,138 @@ var v0 = [ ], v1 = [ { - "alias": "promptVersion", - "args": [ - { - "kind": "Variable", - "name": "id", - "variableName": "id" - } - ], - "concreteType": null, - "kind": "LinkedField", - "name": "node", - "plural": false, + "kind": "Variable", + "name": "id", + "variableName": "id" + } +], +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null +}, +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v4 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "description", + "storageKey": null +}, +v5 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "invocationParameters", + "storageKey": null +}, +v6 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "modelName", + "storageKey": null +}, +v7 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "modelProvider", + "storageKey": null +}, +v8 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "outputSchema", + "storageKey": null +}, +v9 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "template", + "storageKey": null +}, +v10 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "templateFormat", + "storageKey": null +}, +v11 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "templateType", + "storageKey": null +}, +v12 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "tools", + "storageKey": null +}, +v13 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "user", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "promptVersionLoaderQuery", "selections": [ { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "__typename", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "id", - "storageKey": null - }, - { - "kind": "InlineFragment", + "alias": "promptVersion", + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, "selections": [ + (v2/*: any*/), + (v3/*: any*/), { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "description", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "invocationParameters", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "modelName", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "modelProvider", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "outputSchema", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "template", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "templateFormat", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "templateType", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "tools", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "user", - "storageKey": null + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "PromptInvocationParameters__main" + }, + (v4/*: any*/), + (v5/*: any*/), + (v6/*: any*/), + (v7/*: any*/), + (v8/*: any*/), + (v9/*: any*/), + (v10/*: any*/), + (v11/*: any*/), + (v12/*: any*/), + (v13/*: any*/) + ], + "type": "PromptVersion", + "abstractKey": null } ], - "type": "PromptVersion", - "abstractKey": null + "storageKey": null } ], - "storageKey": null - } -]; -return { - "fragment": { - "argumentDefinitions": (v0/*: any*/), - "kind": "Fragment", - "metadata": null, - "name": "promptVersionLoaderQuery", - "selections": (v1/*: any*/), "type": "Query", "abstractKey": null }, @@ -168,19 +187,50 @@ return { "argumentDefinitions": (v0/*: any*/), "kind": "Operation", "name": "promptVersionLoaderQuery", - "selections": (v1/*: any*/) + "selections": [ + { + "alias": "promptVersion", + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v2/*: any*/), + (v3/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + (v5/*: any*/), + (v4/*: any*/), + (v6/*: any*/), + (v7/*: any*/), + (v8/*: any*/), + (v9/*: any*/), + (v10/*: any*/), + (v11/*: any*/), + (v12/*: any*/), + (v13/*: any*/) + ], + "type": "PromptVersion", + "abstractKey": null + } + ], + "storageKey": null + } + ] }, "params": { - "cacheID": "593cd30b91779d0021d6beae17d7e0a6", + "cacheID": "5db17759daf5cde3019b5287785e71bb", "id": null, "metadata": {}, "name": "promptVersionLoaderQuery", "operationKind": "query", - "text": "query promptVersionLoaderQuery(\n $id: GlobalID!\n) {\n promptVersion: node(id: $id) {\n __typename\n id\n ... on PromptVersion {\n description\n invocationParameters\n modelName\n modelProvider\n outputSchema\n template\n templateFormat\n templateType\n tools\n user\n }\n }\n}\n" + "text": "query promptVersionLoaderQuery(\n $id: GlobalID!\n) {\n promptVersion: node(id: $id) {\n __typename\n id\n ... on PromptVersion {\n ...PromptInvocationParameters__main\n description\n invocationParameters\n modelName\n modelProvider\n outputSchema\n template\n templateFormat\n templateType\n tools\n user\n }\n }\n}\n\nfragment PromptInvocationParameters__main on PromptVersion {\n invocationParameters\n}\n" } }; })(); -(node as any).hash = "e1972bbad5d6c0ae81e4407d7765627d"; +(node as any).hash = "566873faa060ebafbabe1b5e8996674e"; export default node; diff --git a/app/src/pages/prompt/promptVersionLoader.tsx b/app/src/pages/prompt/promptVersionLoader.tsx index daac3211fa..e0689d208f 100644 --- a/app/src/pages/prompt/promptVersionLoader.tsx +++ b/app/src/pages/prompt/promptVersionLoader.tsx @@ -18,6 +18,7 @@ export async function promptVersionLoader(args: LoaderFunctionArgs) { __typename id ... on PromptVersion { + ...PromptInvocationParameters__main description invocationParameters modelName diff --git a/src/phoenix/server/api/queries.py b/src/phoenix/server/api/queries.py index bd8849fd53..f2eda0b776 100644 --- a/src/phoenix/server/api/queries.py +++ b/src/phoenix/server/api/queries.py @@ -555,7 +555,11 @@ async def node(self, id: GlobalID, info: Info[Context, None]) -> Node: } ], }, - invocation_parameters={"temperature": 0.5}, + invocation_parameters={ + "temperature": 0.5, + "model": "gpt-4o", + "max_tokens": 100, + }, tools={ "_version": "tools-v1", "tools": [ diff --git a/src/phoenix/server/api/types/Prompt.py b/src/phoenix/server/api/types/Prompt.py index 5ee691584a..554e663dfc 100644 --- a/src/phoenix/server/api/types/Prompt.py +++ b/src/phoenix/server/api/types/Prompt.py @@ -9,17 +9,9 @@ from strawberry.types import Info from phoenix.server.api.context import Context -from phoenix.server.api.types.pagination import ( - ConnectionArgs, - CursorString, - connection_from_list, -) +from phoenix.server.api.types.pagination import ConnectionArgs, CursorString, connection_from_list -from .PromptVersion import ( - PromptTemplateFormat, - PromptTemplateType, - PromptVersion, -) +from .PromptVersion import PromptTemplateFormat, PromptTemplateType, PromptVersion @strawberry.type @@ -58,7 +50,11 @@ async def prompt_versions( {"role": "user", "content": "Hello what's the weather in Antarctica like?"} ], }, - invocation_parameters={"temperature": 0.5}, + invocation_parameters={ + "temperature": 0.5, + "model": "gpt-4o", + "max_tokens": 100, + }, tools={ "_version": "tools-v1", "tools": [ diff --git a/src/phoenix/server/api/types/PromptVersion.py b/src/phoenix/server/api/types/PromptVersion.py index 00ad26c3ff..2c0f07ab2a 100644 --- a/src/phoenix/server/api/types/PromptVersion.py +++ b/src/phoenix/server/api/types/PromptVersion.py @@ -4,7 +4,6 @@ from typing import Optional import strawberry -from strawberry import UNSET from strawberry.relay import Node, NodeID from strawberry.scalars import JSON @@ -30,8 +29,8 @@ class PromptVersion(Node): template_type: PromptTemplateType template_format: PromptTemplateFormat template: JSON - invocation_parameters: Optional[JSON] = UNSET - tools: Optional[JSON] = UNSET - output_schema: Optional[JSON] = UNSET + invocation_parameters: Optional[JSON] = None + tools: Optional[JSON] = None + output_schema: Optional[JSON] = None model_name: str model_provider: str