diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..1bbe09a32 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,491 @@ +version: 2.1 + +orbs: + gradle: smartnews/gradle@3 + terraform: smartnews/terraform@1 + kubernetes: smartnews/kubernetes@3 + +orb_dockers: + gradle: &orb_docker_gradle 165463520094.dkr.ecr.ap-northeast-1.amazonaws.com/circleci-orbs/gradle:8.0-3 + terraform: &orb_docker_terraform 165463520094.dkr.ecr.ap-northeast-1.amazonaws.com/circleci-orbs/terraform:1.3-2 + kubernetes: &orb_docker_kubernetes 165463520094.dkr.ecr.ap-northeast-1.amazonaws.com/circleci-orbs/kubernetes:3 + +executors: + maven: + docker: + - image: *orb_docker_gradle + +workflow_filters: + branch-filter: &branch-filter + filters: + branches: + ignore: + - master + - dev + master-filter: &master-filter + filters: + branches: + only: master + dev-filter: &dev-filter + filters: + branches: + only: dev + +commands: + skaffold-build: + parameters: + env: + type: string + region: + type: string + cluster: + type: string + component: + type: string + steps: + - setup_remote_docker: + docker_layer_caching: true + - run: + name: Run Skaffold + command: | + export TAG=<< parameters.env >>-$(echo $CIRCLE_SHA1 | cut -c -7) + echo $TAG + export PIPELINE_OIDC_TOKEN_VAR=CIRCLE_OIDC_TOKEN + export PIPELINE_SK_CHECK_CONFIG_FILES=false + export PIPELINE_SK_USE_CLUSTER_PROFILE=true + export PIPELINE_SK_SKIP_VERSION_CONFIG=true + spaas skaffold build --aws-account << parameters.env >> --region << parameters.region >> --cluster << parameters.cluster >> --system realtime-streaming --component << parameters.component >> --target '' --path '' + + skaffold-run: + parameters: + env: + type: string + region: + type: string + cluster: + type: string + component: + type: string + steps: + - checkout + - attach_workspace: + at: /home/circleci/.aws + - setup_remote_docker: + docker_layer_caching: true + - run: aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 165463520094.dkr.ecr.ap-northeast-1.amazonaws.com + - run: + name: Run Skaffold + command: | + export env=<< parameters.env >> + export TAG=<< parameters.env >>-$(echo $CIRCLE_SHA1 | cut -c -7) + echo "TAG=$TAG" + export PIPELINE_OIDC_TOKEN_VAR=CIRCLE_OIDC_TOKEN + export PIPELINE_SK_CHECK_CONFIG_FILES=false + export PIPELINE_SK_USE_CLUSTER_PROFILE=true + export PIPELINE_SK_SKIP_VERSION_CONFIG=true + spaas skaffold build --aws-account << parameters.env >> --env '' --region << parameters.region >> --cluster << parameters.cluster >> --namespace '' --system realtime-streaming --component '' --target << parameters.component >> + spaas skaffold run --aws-account << parameters.env >> --env '' --region << parameters.region >> --cluster << parameters.cluster >> --namespace '' --system realtime-streaming --component '' --target << parameters.component >> + +jobs: + deploy: + executor: maven + parameters: + env: + type: string + region: + type: string + cluster: + type: string + component: + type: string + build-only: + type: boolean + default: false + steps: + - when: + condition: << parameters.build-only >> + steps: + - skaffold-build: + env: << parameters.env >> + region: << parameters.region >> + cluster: << parameters.cluster >> + component: << parameters.component >> + - unless: + condition: << parameters.build-only >> + steps: + - skaffold-run: + env: << parameters.env >> + region: << parameters.region >> + cluster: << parameters.cluster >> + component: << parameters.component >> + +workflows: + deliver-dev: + jobs: + - approve: + <<: *dev-filter + name: approve/postgres + type: approval + - gradle/deliver: + <<: *dev-filter + name: deliver/dev/postgres + docker: *orb_docker_gradle + aws_account: dev + env: "" + region: tokyo + cluster: common-0 + system: realtime-streaming + target: postgres + skaffold_use_cluster_profile: true + requires: + - approve/postgres + - approve: + <<: *dev-filter + name: approve/clickhouse + type: approval + - gradle/deliver: + <<: *dev-filter + name: deliver/dev/clickhouse + docker: *orb_docker_gradle + aws_account: dev + env: "" + region: tokyo + cluster: common-0 + system: realtime-streaming + target: clickhouse + skaffold_use_cluster_profile: true + requires: + - approve/clickhouse + - approve: + <<: *dev-filter + name: approve/supertokens + type: approval + - gradle/deliver: + <<: *dev-filter + name: deliver/dev/supertokens + docker: *orb_docker_gradle + aws_account: dev + env: "" + region: tokyo + cluster: common-0 + system: realtime-streaming + target: supertokens + skaffold_use_cluster_profile: true + requires: + - approve/supertokens + - approve: + <<: *dev-filter + name: approve/redis + type: approval + - gradle/deliver: + <<: *dev-filter + name: deliver/dev/redis + docker: *orb_docker_gradle + aws_account: dev + env: "" + region: tokyo + cluster: common-0 + system: realtime-streaming + target: redis +# resourceClass: large + skaffold_use_cluster_profile: true + requires: + - approve/redis + - approve: + <<: *dev-filter + name: approve/local-kms + type: approval + - gradle/deliver: + <<: *dev-filter + name: deliver/dev/local-kms + docker: *orb_docker_gradle + aws_account: dev + env: "" + region: tokyo + cluster: common-0 + system: realtime-streaming + target: local-kms + skaffold_use_cluster_profile: true + requires: + - approve/local-kms + - approve: + <<: *dev-filter + name: approve/server + type: approval + - gradle/deliver: + <<: *dev-filter + name: deliver/dev/server + docker: *orb_docker_gradle + aws_account: dev + env: "" + region: tokyo + cluster: common-0 + system: realtime-streaming + target: server + skaffold_use_cluster_profile: true + requires: + - approve/server + - approve: + <<: *dev-filter + name: approve/console + type: approval + - gradle/deliver: + <<: *dev-filter + name: deliver/dev/console + docker: *orb_docker_gradle + aws_account: dev + env: "" + region: tokyo + cluster: common-0 + system: realtime-streaming + target: console + skaffold_use_cluster_profile: true + requires: + - approve/console + - approve: + <<: *dev-filter + name: approve/proxy + type: approval + - gradle/deliver: + <<: *dev-filter + name: deliver/dev/proxy + docker: *orb_docker_gradle + aws_account: dev + env: "" + region: tokyo + cluster: common-0 + system: realtime-streaming + target: proxy + skaffold_use_cluster_profile: true + requires: + - approve/proxy + - approve: + <<: *dev-filter + name: approve/prisma-migrate + type: approval + - gradle/deliver: + <<: *dev-filter + name: deliver/dev/prisma-migrate + docker: *orb_docker_gradle + aws_account: dev + env: "" + region: tokyo + cluster: common-0 + system: realtime-streaming + target: prisma-migrate + skaffold_use_cluster_profile: true + requires: + - approve/prisma-migrate + - approve: + <<: *dev-filter + name: approve/clickhouse-migrate + type: approval + - gradle/deliver: + <<: *dev-filter + name: deliver/dev/clickhouse-migrate + docker: *orb_docker_gradle + aws_account: dev + env: "" + region: tokyo + cluster: common-0 + system: realtime-streaming + target: clickhouse-migrate + skaffold_use_cluster_profile: true + requires: + - approve/clickhouse-migrate + + deliver-prd: + jobs: + - approve: + <<: *master-filter + name: approve/postgres + type: approval + - deploy: + <<: *master-filter + name: deliver/prd/postgres + env: prd + region: tokyo + cluster: common-0 + component: postgres + requires: + - approve/postgres + - approve: + <<: *master-filter + name: approve/clickhouse + type: approval + - deploy: + <<: *master-filter + name: deliver/prd/clickhouse + env: prd + region: tokyo + cluster: common-0 + component: clickhouse + requires: + - approve/clickhouse + - approve: + <<: *master-filter + name: approve/supertokens + type: approval + - deploy: + <<: *master-filter + name: deliver/prd/supertokens + env: prd + region: tokyo + cluster: common-0 + component: supertokens + requires: + - approve/supertokens + - approve: + <<: *master-filter + name: approve/redis + type: approval + - deploy: + <<: *master-filter + name: deliver/prd/redis + env: prd + region: tokyo + cluster: common-0 + component: redis + requires: + - approve/redis + - approve: + <<: *master-filter + name: approve/local-kms + type: approval + - deploy: + <<: *master-filter + name: deliver/prd/local-kms + env: prd + region: tokyo + cluster: common-0 + component: local-kms + requires: + - approve/local-kms + - approve: + <<: *master-filter + name: approve/server + type: approval + - deploy: + <<: *master-filter + name: deliver/prd/server + env: prd + region: tokyo + cluster: common-0 + component: server + requires: + - approve/server + - approve: + <<: *master-filter + name: approve/console + type: approval + - deploy: + <<: *master-filter + name: deliver/prd/console + env: prd + region: tokyo + cluster: common-0 + component: console + requires: + - approve/console + - approve: + <<: *master-filter + name: approve/proxy + type: approval + - deploy: + <<: *master-filter + name: deliver/prd/proxy + env: prd + region: tokyo + cluster: common-0 + component: proxy + requires: + - approve/proxy + - approve: + <<: *master-filter + name: approve/prisma-migrate + type: approval + - deploy: + <<: *master-filter + name: deliver/prd/prisma-migrate + env: prd + region: tokyo + cluster: common-0 + component: prisma-migrate + requires: + - approve/prisma-migrate + - approve: + <<: *master-filter + name: approve/clickhouse-migrate + type: approval + - deploy: + <<: *master-filter + name: deliver/prd/clickhouse-migrate + env: prd + region: tokyo + cluster: common-0 + component: clickhouse-migrate + requires: + - approve/clickhouse-migrate + + terraform-trigger: + when: << pipeline.parameters.workflow_main >> + jobs: +# - terraform/trigger: +# docker: *orb_docker_terraform +# name: terraform/trigger/dev +# system: realtime-streaming +# path: . + - terraform/trigger: + docker: *orb_docker_terraform + name: terraform/trigger/prd + system: realtime-streaming + aws_account: prd + path: . + terraform: + when: << pipeline.parameters.workflow_terraform >> + jobs: + - terraform/plan: + <<: *master-filter + docker: *orb_docker_terraform + name: << pipeline.parameters.path >>/<< pipeline.parameters.aws_account >>/<< pipeline.parameters.region >>/plan + system: << pipeline.parameters.system >> + path: << pipeline.parameters.path >> + aws_account: << pipeline.parameters.aws_account >> + - approve: + <<: *master-filter + name: << pipeline.parameters.path >>/<< pipeline.parameters.aws_account >>/<< pipeline.parameters.region >>/approve + type: approval + requires: + - << pipeline.parameters.path >>/<< pipeline.parameters.aws_account >>/<< pipeline.parameters.region >>/plan + - terraform/apply: + <<: *master-filter + docker: *orb_docker_terraform + name: << pipeline.parameters.path >>/<< pipeline.parameters.aws_account >>/<< pipeline.parameters.region >>/apply + system: << pipeline.parameters.system >> + path: << pipeline.parameters.path >> + aws_account: << pipeline.parameters.aws_account >> + requires: + - << pipeline.parameters.path >>/<< pipeline.parameters.aws_account >>/<< pipeline.parameters.region >>/approve + +parameters: + workflow_main: + type: boolean + default: true + workflow_terraform: + type: boolean + default: false + env: + type: string + default: "" + region: + type: string + default: "" + system: + type: string + default: "" + path: + type: string + default: "" + aws_account: + type: string + default: "" diff --git a/apps/console/Dockerfile b/apps/console/Dockerfile index b1fc85b87..00fdd082a 100644 --- a/apps/console/Dockerfile +++ b/apps/console/Dockerfile @@ -1,14 +1,24 @@ +FROM node:20-alpine as builder +WORKDIR /app +COPY . . +RUN npm install +RUN npx nx run console:build + + FROM nginx:1.20-alpine LABEL org.opencontainers.image.source https://github.com/pezzolabs/pezzo -RUN apk add --update nodejs +RUN apk add --update nodejs npm WORKDIR /app -COPY dist/apps/console/nginx.conf /etc/nginx/conf.d/default.conf -COPY dist/apps/console . +# update file path based on real path +COPY --from=builder app/dist/apps/console/nginx.conf /etc/nginx/conf.d/default.conf +#COPY apps/dist/apps/console/nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=builder app/dist/apps/console . +#COPY apps/dist/apps/console . RUN chmod +x scripts/entrypoint.sh ENTRYPOINT ["./scripts/entrypoint.sh"] -CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file +CMD ["nginx", "-g", "daemon off;"] diff --git a/apps/console/nginx.conf b/apps/console/nginx.conf index fd8d6bf48..625671853 100644 --- a/apps/console/nginx.conf +++ b/apps/console/nginx.conf @@ -1,7 +1,8 @@ server { - listen 8080; + listen [::]:4200; + listen 4200; root /app; location / { - try_files $uri /index.html; + try_files $uri /index.html; } -} \ No newline at end of file +} diff --git a/apps/console/scripts/entrypoint.sh b/apps/console/scripts/entrypoint.sh index 6117411e6..0cc3746c6 100644 --- a/apps/console/scripts/entrypoint.sh +++ b/apps/console/scripts/entrypoint.sh @@ -1,4 +1,4 @@ #!/bin/sh set -e; node /app/scripts/inject-variables.js /app/index.html; -exec "$@"; \ No newline at end of file +exec "$@"; diff --git a/apps/console/src/app.tsx b/apps/console/src/app.tsx index 4614cc0bf..8565c0c4a 100644 --- a/apps/console/src/app.tsx +++ b/apps/console/src/app.tsx @@ -6,9 +6,9 @@ import { Toaster } from "@pezzo/ui"; // Auth import { QueryClientProvider } from "@tanstack/react-query"; -import { SuperTokensWrapper } from "supertokens-auth-react"; -import { SessionAuth } from "supertokens-auth-react/recipe/session"; -import { initSuperTokens } from "./lib/auth/supertokens"; +// import { SuperTokensWrapper } from "supertokens-auth-react"; +// import { SessionAuth } from "supertokens-auth-react/recipe/session"; +// import { initSuperTokens } from "./lib/auth/supertokens"; // Pages import { EnvironmentsPage } from "./pages/environments/EnvironmentsPage"; @@ -40,7 +40,8 @@ import { OrgPage } from "./pages/projects/OrgPage"; import { useCurrentOrganization } from "./lib/hooks/useCurrentOrganization"; import { WaitlistWrapper } from "~/pages/WaitlistWrapper"; -initSuperTokens(); +// use Okta for auth instead of SuperTokens +// initSuperTokens(); if (HOTJAR_SITE_ID && HOTJAR_VERSION) { hotjar.initialize(Number(HOTJAR_SITE_ID), Number(HOTJAR_VERSION)); @@ -62,114 +63,114 @@ export function App() { return (
- - - {/* Non-authorized routes */} - - {/* We don't render the LayoutWrapper for non-authorized routes */} + + {/* Non-authorized routes */} + + } + /> + } + /> + } /> + } /> + + {/* Authorized routes */} + + + + + + + } + > + } /> + } + path="/invitations/:token/accept" + element={ + + + + } /> - } /> - } /> - - {/* Authorized routes */} - + - - - - - - + + + + + } - > - } /> - - - - - } - /> + /> - + {/* Organizations */} + + }> - + - - } - /> + + + } + > + } /> + } /> + } /> + } /> + - {/* Organizations */} - - }> + {/* In-project routes */} + }> + + + - - - } - > - } /> - } /> - } /> - } /> - - - {/* In-project routes */} - }> - - - - - - - - - - - } - > - } /> - } /> - } /> - } /> - } /> - }> - } /> - - - - - - } - /> - } /> - + + + + + } + > + // TODO: decide if need DashboardPage or not, and change the index page to PromptPage + } /> + } /> + } /> + } /> + } /> + }> + } /> + + + + + + } + /> + } /> - - - + + +
); } diff --git a/apps/console/src/components/layout/Header.tsx b/apps/console/src/components/layout/Header.tsx index 13dedc1aa..b7663493c 100644 --- a/apps/console/src/components/layout/Header.tsx +++ b/apps/console/src/components/layout/Header.tsx @@ -9,10 +9,13 @@ import { UserMenu } from "./UserMenu"; import { useAuthContext } from "~/lib/providers/AuthProvider"; import { ProjectCopy } from "../projects/ProjectCopy"; import { OrgSelector } from "./OrgSelector"; +import { usePrompts } from "~/lib/hooks/usePrompts"; +import { PromptCopy } from "~/components/prompts/PromptCopy"; export const Header = () => { const { organization } = useCurrentOrganization(); const { project } = useCurrentProject(); + const { prompts } = usePrompts(); const { currentUser } = useAuthContext(); return ( @@ -62,6 +65,12 @@ export const Header = () => { )} + {prompts && ( +
+ +
+ )} + {project && (
diff --git a/apps/console/src/components/layout/SideNavigation.tsx b/apps/console/src/components/layout/SideNavigation.tsx index 0bd276a7c..7442fd727 100644 --- a/apps/console/src/components/layout/SideNavigation.tsx +++ b/apps/console/src/components/layout/SideNavigation.tsx @@ -20,9 +20,9 @@ export const SideNavigation = () => { const projectNavigation = [ { - name: "Dashboard", + name: "Prompts", href: `/projects/${projectId}`, - icon: BarChart2, + icon: BoxIcon, isActive: (href: string) => window.location.pathname === href, }, { @@ -32,17 +32,17 @@ export const SideNavigation = () => { isActive: (href: string) => window.location.pathname.startsWith(href), }, { - name: "Prompts", - href: `/projects/${projectId}/prompts`, - icon: BoxIcon, - isActive: (href: string) => window.location.pathname.startsWith(href), - }, - { - name: "Environments", - href: `/projects/${projectId}/environments`, - icon: HardDriveIcon, + name: "Dashboard", + href: `/projects/${projectId}/dashboard`, + icon: BarChart2, isActive: (href: string) => window.location.pathname.startsWith(href), }, + // { + // name: "Environments", + // href: `/projects/${projectId}/environments`, + // icon: HardDriveIcon, + // isActive: (href: string) => window.location.pathname.startsWith(href), + // }, ]; return ( @@ -111,7 +111,7 @@ export const SideNavigation = () => { {
- + Documentation diff --git a/apps/console/src/components/organizations/InviteOrgMemberModal.tsx b/apps/console/src/components/organizations/InviteOrgMemberModal.tsx index 01d7909fb..f95e76818 100644 --- a/apps/console/src/components/organizations/InviteOrgMemberModal.tsx +++ b/apps/console/src/components/organizations/InviteOrgMemberModal.tsx @@ -66,8 +66,9 @@ export const InviteOrgMemberModal = ({ open, onClose }: Props) => { onClose(); toast({ title: "Invitation sent", - description: `An invitation has been sent to ${inviteeEmail}`, + description: `Will add ${inviteeEmail} into ${organization.name} soon...`, }); + window.location.assign(`/orgs/${organization.id}`); }, } ); @@ -109,7 +110,7 @@ export const InviteOrgMemberModal = ({ open, onClose }: Props) => { - + diff --git a/apps/console/src/components/prompts/PromptCopy.tsx b/apps/console/src/components/prompts/PromptCopy.tsx new file mode 100644 index 000000000..f65b0e1db --- /dev/null +++ b/apps/console/src/components/prompts/PromptCopy.tsx @@ -0,0 +1,42 @@ + +import { copyToClipboard } from "~/lib/utils/browser-utils"; +import { useState } from "react"; +import { trackEvent } from "~/lib/utils/analytics"; +import { CheckIcon, CopyIcon } from "lucide-react"; +import { useCurrentPrompt } from "~/lib/providers/CurrentPromptContext"; +import { Button } from "@pezzo/ui"; + +export const PromptCopy = () => { + const { promptId, isLoading } = useCurrentPrompt(); + const [clicked, setClicked] = useState(false); + + if (isLoading) return null; + + return ( + + ); +}; diff --git a/apps/console/src/components/prompts/editor/ProviderSelector/providers.tsx b/apps/console/src/components/prompts/editor/ProviderSelector/providers.tsx index 439564330..558adb484 100644 --- a/apps/console/src/components/prompts/editor/ProviderSelector/providers.tsx +++ b/apps/console/src/components/prompts/editor/ProviderSelector/providers.tsx @@ -13,24 +13,24 @@ export const providersList: ProviderProps[] = [ value: PromptService.OpenAiChatCompletion, label: promptProvidersMapping[PromptService.OpenAiChatCompletion].name, }, - { - image: ( - Azure OpenAI - ), - value: PromptService.AzureOpenAiChatCompletion, - label: promptProvidersMapping[PromptService.AzureOpenAiChatCompletion].name, - }, - { - image: ( - Anthropic - ), - value: PromptService.AnthropicCompletion, - label: promptProvidersMapping[PromptService.AnthropicCompletion].name, - }, + // { + // image: ( + // Azure OpenAI + // ), + // value: PromptService.AzureOpenAiChatCompletion, + // label: promptProvidersMapping[PromptService.AzureOpenAiChatCompletion].name, + // }, + // { + // image: ( + // Anthropic + // ), + // value: PromptService.AnthropicCompletion, + // label: promptProvidersMapping[PromptService.AnthropicCompletion].name, + // }, ]; /** diff --git a/apps/console/src/components/prompts/editor/ProviderSettings/ProviderSettingsSchemaRenderer.tsx b/apps/console/src/components/prompts/editor/ProviderSettings/ProviderSettingsSchemaRenderer.tsx index 9c14ce6ab..9781bcbcb 100644 --- a/apps/console/src/components/prompts/editor/ProviderSettings/ProviderSettingsSchemaRenderer.tsx +++ b/apps/console/src/components/prompts/editor/ProviderSettings/ProviderSettingsSchemaRenderer.tsx @@ -11,17 +11,19 @@ import { } from "@pezzo/ui"; import { PromptSettingsSlider } from "../../PromptSettingsSlider"; import { useEditorContext } from "~/lib/providers/EditorContext"; -import { generateFormSchema } from "./providers/openai-chat-completion"; +import { GenerateFormSchema } from "./providers/openai-chat-completion"; import { SelectFormField, SliderFormField } from "./types"; import { ControllerRenderProps, FieldValues } from "react-hook-form"; interface Props { - schema: ReturnType; + schema: ReturnType; } export const ProviderSettingsSchemaRenderer = ({ schema }: Props) => { const { getForm } = useEditorContext(); const form = getForm(); + // const setting = form.watch("settings"); + // const model = setting.model; const renderField = ( renderSchema: any, @@ -39,10 +41,18 @@ export const ProviderSettingsSchemaRenderer = ({ schema }: Props) => { renderSchema: SelectFormField, field: ControllerRenderProps ) => { + // console.log("field.value: ", field.value) + // renderSchema.options.map((option) => { + // if (option.value === field.value) { + // console.log("option.label: ", option.label) + // } + // }); return (