diff --git a/agenta-web/src/code_snippets/endpoints/fetch_config/curl.ts b/agenta-web/src/code_snippets/endpoints/fetch_config/curl.ts new file mode 100644 index 0000000000..d7d09260b3 --- /dev/null +++ b/agenta-web/src/code_snippets/endpoints/fetch_config/curl.ts @@ -0,0 +1,8 @@ +export default function cURLCode(baseId: string, env_name: string): string { + return ` + curl -X GET "https://cloud.agenta.ai/api/configs?base_id=${baseId}&environment_name=${env_name}" \\ + -H "Authorization: Bearer YOUR_API_KEY" \\ + -H "Content-Type: application/json" \\ + --connect-timeout 60 + ` +} diff --git a/agenta-web/src/code_snippets/endpoints/fetch_config/python.ts b/agenta-web/src/code_snippets/endpoints/fetch_config/python.ts new file mode 100644 index 0000000000..48a6d5ef9a --- /dev/null +++ b/agenta-web/src/code_snippets/endpoints/fetch_config/python.ts @@ -0,0 +1,12 @@ +export default function pythonCode(baseId: string, env_name: string): string { + return ` + # os.environ["AGENTA_API_KEY"] = "your_api_key" # Only when using cloud + # os.environ["HOST"] = "https://cloud.agenta.ai" + + from agenta import Agenta + ag = Agenta() + ag.get_config(base_id="${baseId}", + environment="${env_name}", + cache_timeout=600) # timeout 300 per default + ` +} diff --git a/agenta-web/src/code_snippets/endpoints/fetch_config/typescript.ts b/agenta-web/src/code_snippets/endpoints/fetch_config/typescript.ts new file mode 100644 index 0000000000..ae1b27b885 --- /dev/null +++ b/agenta-web/src/code_snippets/endpoints/fetch_config/typescript.ts @@ -0,0 +1,46 @@ +import {js as beautify} from "js-beautify" + +export default function tsCode(baseId: string, env_name: string): string { + const codeString = ` + import axios from 'axios'; + + const getConfig = async (baseId: string, environmentName: string) => { + try { + const baseUrl = 'https://cloud.agenta.ai/api'; + const params = { + base_id: baseId, + environment_name: environmentName + }; + + const response = await axios.get(baseUrl + "/configs", { + params: params, + headers: { + 'Authorization': "Bearer YOUR_API_KEY", + 'Content-Type': 'application/json' + }, + timeout: 60000 + }); + + if (response.status >= 200 && response.status < 300) { + return response.data; + } else if (response.status === 422) { + throw new Error(JSON.stringify(response.data)); + } + } catch (error: any) { + if (error.response) { + console.error("API Error: " + error.response.status, error.response.data); + } else if (error.request) { + console.error('API Error: No response received', error.request); + } else { + console.error('Error', error.message); + } + throw error; + } + }; + + getConfig('${baseId}', '${env_name}').then(console.log).catch(console.error); + ` + + const formattedCodeString = beautify(codeString) + return formattedCodeString +} diff --git a/agenta-web/src/code_snippets/endpoints/curl.ts b/agenta-web/src/code_snippets/endpoints/invoke_llm_app/curl.ts similarity index 55% rename from agenta-web/src/code_snippets/endpoints/curl.ts rename to agenta-web/src/code_snippets/endpoints/invoke_llm_app/curl.ts index 617530e86c..2fa845e9c5 100644 --- a/agenta-web/src/code_snippets/endpoints/curl.ts +++ b/agenta-web/src/code_snippets/endpoints/invoke_llm_app/curl.ts @@ -1,6 +1,6 @@ export default function cURLCode(uri: string, params: string): string { - return `curl -X POST ${uri} \ --H "Content-Type: application/json" \ + return `curl -X POST ${uri} \\ +-H "Content-Type: application/json" \\ -d '${params}' ` } diff --git a/agenta-web/src/code_snippets/endpoints/python.ts b/agenta-web/src/code_snippets/endpoints/invoke_llm_app/python.ts similarity index 100% rename from agenta-web/src/code_snippets/endpoints/python.ts rename to agenta-web/src/code_snippets/endpoints/invoke_llm_app/python.ts diff --git a/agenta-web/src/code_snippets/endpoints/typescript.ts b/agenta-web/src/code_snippets/endpoints/invoke_llm_app/typescript.ts similarity index 100% rename from agenta-web/src/code_snippets/endpoints/typescript.ts rename to agenta-web/src/code_snippets/endpoints/invoke_llm_app/typescript.ts diff --git a/agenta-web/src/pages/apps/[app_id]/endpoints/index.tsx b/agenta-web/src/pages/apps/[app_id]/endpoints/index.tsx index 69d8709aeb..6c1b2aba85 100644 --- a/agenta-web/src/pages/apps/[app_id]/endpoints/index.tsx +++ b/agenta-web/src/pages/apps/[app_id]/endpoints/index.tsx @@ -1,15 +1,18 @@ -import cURLCode from "@/code_snippets/endpoints/curl" -import pythonCode from "@/code_snippets/endpoints/python" -import tsCode from "@/code_snippets/endpoints/typescript" +import invokeLlmAppcURLCode from "@/code_snippets/endpoints/invoke_llm_app/curl" +import invokeLlmApppythonCode from "@/code_snippets/endpoints/invoke_llm_app/python" +import invokeLlmApptsCode from "@/code_snippets/endpoints/invoke_llm_app/typescript" +import fetchConfigcURLCode from "@/code_snippets/endpoints/fetch_config/curl" +import fetchConfigpythonCode from "@/code_snippets/endpoints/fetch_config/python" +import fetchConfigtsCode from "@/code_snippets/endpoints/fetch_config/typescript" import DynamicCodeBlock from "@/components/DynamicCodeBlock/DynamicCodeBlock" import ResultComponent from "@/components/ResultComponent/ResultComponent" -import {Environment, GenericObject, Parameter, Variant} from "@/lib/Types" +import {Environment, GenericObject, JSSTheme, Parameter, Variant} from "@/lib/Types" import {isDemo} from "@/lib/helpers/utils" import {dynamicComponent} from "@/lib/helpers/dynamic" import {useVariant} from "@/lib/hooks/useVariant" import {fetchEnvironments, fetchVariants, getAppContainerURL} from "@/lib/services/api" -import {ApiOutlined, AppstoreOutlined, DownOutlined, HistoryOutlined} from "@ant-design/icons" -import {Alert, Button, Dropdown, Empty, Space, Tabs, Typography} from "antd" +import {ApiOutlined, AppstoreOutlined, HistoryOutlined} from "@ant-design/icons" +import {Alert, Collapse, CollapseProps, Empty, Radio, Tabs, Tooltip, Typography} from "antd" import {useRouter} from "next/router" import {useEffect, useState} from "react" import {createUseStyles} from "react-jss" @@ -19,19 +22,29 @@ const DeploymentHistory: any = dynamicComponent("DeploymentHistory/DeploymentHis const {Text, Title} = Typography -const useStyles = createUseStyles({ +const useStyles = createUseStyles((theme: JSSTheme) => ({ container: { display: "flex", flexDirection: "column", rowGap: 20, }, -}) + envButtons: { + "& .ant-radio-button-wrapper-checked": { + backgroundColor: theme.colorPrimary, + color: theme.colorWhite, + "&:hover": { + color: theme.colorWhite, + }, + }, + }, +})) export default function VariantEndpoint() { const classes = useStyles() const router = useRouter() const appId = router.query.app_id as string const [tab, setTab] = useQueryParam("tab", "overview") + const isOss = !isDemo() // Load URL for the given environment const [uri, setURI] = useState(null) @@ -48,9 +61,14 @@ export default function VariantEndpoint() { const loadEnvironments = async () => { const response: Environment[] = await fetchEnvironments(appId) setEnvironments(response) - setSelectedEnvironment(response[0]) - - await loadURL(response[0]) + const loadProductionEnv = response.find((env) => env.name === "production") + if (loadProductionEnv) { + setSelectedEnvironment(loadProductionEnv) + await loadURL(loadProductionEnv) + } else { + setSelectedEnvironment(response[0]) + await loadURL(response[0]) + } } useEffect(() => { if (!appId) return @@ -68,6 +86,7 @@ export default function VariantEndpoint() { const [variants, setVariants] = useState([]) const [isVariantsLoading, setIsVariantsLoading] = useState(false) const [isVariantsError, setIsVariantsError] = useState(false) + useEffect(() => { const fetchData = async () => { setIsVariantsLoading(true) @@ -154,11 +173,31 @@ export default function VariantEndpoint() { } const params = createParams(inputParams, selectedEnvironment?.name || "none", "add_a_value") - const codeSnippets: Record = { - Python: pythonCode(uri!, params), - cURL: cURLCode(uri!, params), - TypeScript: tsCode(uri!, params), + const invokeLlmAppCodeSnippet: Record = { + Python: invokeLlmApppythonCode(uri!, params), + cURL: invokeLlmAppcURLCode(uri!, params), + TypeScript: invokeLlmApptsCode(uri!, params), } + + const fetchConfigCodeSnippet: Record = { + Python: fetchConfigpythonCode(variant.baseId, selectedEnvironment?.name!), + cURL: fetchConfigcURLCode(variant.baseId, selectedEnvironment?.name!), + TypeScript: fetchConfigtsCode(variant.baseId, selectedEnvironment?.name!), + } + + const items: CollapseProps["items"] = [ + { + key: "1", + label: "Invoke LLM App", + children: , + }, + { + key: "2", + label: "Fetch Prompt/Config", + children: , + }, + ] + return (
@@ -171,51 +210,61 @@ export default function VariantEndpoint() { <div> <Text>Environment: </Text> - <Dropdown - menu={{ - items: environments.map((env) => ({label: env.name, key: env.name})), - onClick: handleEnvironmentClick, - }} + <Radio.Group + value={selectedEnvironment?.name} + onChange={(e) => handleEnvironmentClick({key: e.target.value})} + className={classes.envButtons} > - <Button size="small"> - <Space> - {selectedEnvironment?.name || "Select a variant"} - <DownOutlined /> - </Space> - </Button> - </Dropdown> + {environments + .map((env) => ( + <Radio.Button + disabled={!env.deployed_app_variant_id} + key={env.name} + value={env.name} + > + {env.name} + </Radio.Button> + )) + .reverse()} + </Radio.Group> </div> {selectedEnvironment?.deployed_app_variant_id ? ( - isDemo() ? ( - <> - <Tabs - destroyInactiveTabPane - defaultActiveKey={tab} - items={[ - { - key: "overview", - label: "Overview", - icon: <AppstoreOutlined />, - children: <DynamicCodeBlock codeSnippets={codeSnippets} />, - }, - { - key: "history", - label: "History", - icon: <HistoryOutlined />, - children: ( - <DeploymentHistory - selectedEnvironment={selectedEnvironment} - /> - ), - }, - ]} - onChange={setTab} - /> - </> - ) : ( - <DynamicCodeBlock codeSnippets={codeSnippets} /> - ) + <> + <Tabs + destroyInactiveTabPane + defaultActiveKey={tab} + items={[ + { + key: "overview", + label: "Overview", + icon: <AppstoreOutlined />, + children: ( + <Collapse accordion defaultActiveKey={["1"]} items={items} /> + ), + }, + { + key: "history", + label: !isOss ? ( + "History" + ) : ( + <Tooltip + placement="right" + title="Deployment History available in Cloud/Enterprise editions only" + > + History + </Tooltip> + ), + icon: <HistoryOutlined />, + children: ( + <DeploymentHistory selectedEnvironment={selectedEnvironment} /> + ), + disabled: isOss, + }, + ]} + onChange={setTab} + /> + </> ) : ( <Alert message="Publish Required"