Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
722b808
implemented onboarding feature on the app
ashrafchowdury Nov 17, 2025
d8c851e
fixed codeql issue
ashrafchowdury Nov 17, 2025
dac403b
fixed trace drawer issue
ashrafchowdury Nov 17, 2025
abde757
fixed modal target issues
ashrafchowdury Nov 17, 2025
c779453
implemented steps for online eval creation
ashrafchowdury Nov 17, 2025
72613b1
fix playground step
ashrafchowdury Nov 17, 2025
82cacf5
fixed viewport issue
ashrafchowdury Nov 17, 2025
91ffc44
cleandup evaluation tours
ashrafchowdury Nov 17, 2025
ceb8d8d
fix the failure issue
ashrafchowdury Nov 17, 2025
5b445dd
added steps for online eval detail page
ashrafchowdury Nov 17, 2025
8805bc3
added sme journey
ashrafchowdury Nov 17, 2025
db1508a
fixed issue
ashrafchowdury Nov 17, 2025
a7af7e1
show onboarding for specific pages
ashrafchowdury Nov 17, 2025
2b6a0ce
fixed bugs
ashrafchowdury Nov 17, 2025
c4dbc5e
implemented posthog on onboarding
ashrafchowdury Nov 17, 2025
92d9ef4
fix pnpm file
ashrafchowdury Nov 17, 2025
716953f
fixed constant opening issue
ashrafchowdury Nov 17, 2025
1fbf3e4
fixed issues
ashrafchowdury Nov 19, 2025
11aac7b
Merge branch 'release/v0.62.6' of https://github.com/Agenta-AI/agenta…
ashrafchowdury Nov 19, 2025
c1aec44
fix code
ashrafchowdury Nov 19, 2025
754eb3d
format code
ashrafchowdury Nov 19, 2025
0444cc4
Merge branch 'main' of https://github.com/Agenta-AI/agenta into featu…
ashrafchowdury Nov 25, 2025
9d6bcb9
cleanup
ashrafchowdury Nov 25, 2025
5b9c76c
removed redundend playground steps
ashrafchowdury Nov 25, 2025
b3767e8
fixed issue for finish actions
ashrafchowdury Nov 26, 2025
202c2f0
cleaned up breadcrumb
ashrafchowdury Nov 29, 2025
34114e0
cleaned up old code
ashrafchowdury Nov 29, 2025
2bf80b4
added auto advance step feature
ashrafchowdury Nov 29, 2025
431218b
added widget
ashrafchowdury Nov 29, 2025
b8f4ad7
added extra utils on the onboarding step
ashrafchowdury Nov 30, 2025
d291bbb
refactored code
ashrafchowdury Nov 30, 2025
ae18f0f
triggering steps based on given tour id
ashrafchowdury Nov 30, 2025
ebfdc5d
created online evaluation in one click
ashrafchowdury Nov 30, 2025
b7fac29
made the tracker consistent
ashrafchowdury Nov 30, 2025
0e8fdb3
improved card ui
ashrafchowdury Nov 30, 2025
86c7db3
reverted post-signup changes
ashrafchowdury Nov 30, 2025
075eee3
Merge branch 'main' of https://github.com/Agenta-AI/agenta into featu…
ashrafchowdury Nov 30, 2025
3c0d9c5
added posthog tracker
ashrafchowdury Dec 1, 2025
9088e9e
improved widget reposition
ashrafchowdury Dec 1, 2025
b621e3b
added steps for prompt-management
ashrafchowdury Dec 1, 2025
45d11fc
fixed the arrow
ashrafchowdury Dec 1, 2025
51e9f11
fix bug
ashrafchowdury Dec 1, 2025
96da033
removed floating button
ashrafchowdury Dec 1, 2025
1529dbf
improved card ui
ashrafchowdury Dec 1, 2025
f041074
added a default "LLM-as-a-judge" evaluator on BE
ashrafchowdury Dec 1, 2025
d8e2d84
remove file
ashrafchowdury Dec 1, 2025
9ca0372
removed old auto eval steps code
ashrafchowdury Dec 1, 2025
4b2aef0
cleandup and reverted code changes
ashrafchowdury Dec 1, 2025
3de2014
fix
ashrafchowdury Dec 1, 2025
2d909b1
removed unused steps
ashrafchowdury Dec 2, 2025
43a9410
improved ui
ashrafchowdury Dec 2, 2025
fe8ccc2
added general guild open step
ashrafchowdury Dec 2, 2025
2bf7e3d
Merge branch 'main' of https://github.com/Agenta-AI/agenta into featu…
ashrafchowdury Dec 3, 2025
3a69f70
Merge branch 'release/v0.69.3' into feature/user-onbroading-to-app
mmabrouk Dec 17, 2025
13609c1
Refactor onboarding state management to utilize activePreviewRunIdAto…
mmabrouk Dec 17, 2025
8154da7
Refactor onboarding components to improve code organization and consi…
mmabrouk Dec 17, 2025
e298b60
revert changes to backend
mmabrouk Dec 17, 2025
aa829a4
chore(web): replace nextstepjs patch with @agentaai/nextstepjs package
mmabrouk Dec 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion web/ee/docker/Dockerfile.dev
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First check the below asnwer for better context. Since we have added a patch directory, we need to add that on dockerfile as well

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ COPY ee/package.json ./ee/yarn.lock* ./ee/package-lock.json* ./ee/pnpm-lock.yaml
COPY oss/package.json ./oss/yarn.lock* ./oss/package-lock.json* ./oss/pnpm-lock.yaml* ./oss/.npmrc* ./oss/
COPY ./pnpm-workspace.yaml ./turbo.json ./

COPY ./entrypoint.sh /app/entrypoint.sh
COPY ./entrypoint.sh /app/entrypoint.sh

RUN pnpm i

Expand Down
4 changes: 3 additions & 1 deletion web/oss/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
"lexical": "^0.38.2",
"lodash": "^4.17.21",
"lucide-react": "^0.475.0",
"motion": "^12.23.24",
"@agentaai/nextstepjs": "^2.1.3-agenta.1",
"next": "15.5.9",
"papaparse": "^5.5.3",
"postcss": "^8.5.6",
Expand Down Expand Up @@ -137,4 +139,4 @@
"node-mocks-http": "^1.17.2",
"tailwind-scrollbar": "^3"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import {ComponentProps, ReactNode, useState} from "react"
import {CloseOutlined, FullscreenExitOutlined, FullscreenOutlined} from "@ant-design/icons"
import {Button, Divider, Drawer} from "antd"
import clsx from "clsx"
import {useAtomValue} from "jotai"
import {useAtomValue, useSetAtom} from "jotai"
import {createUseStyles} from "react-jss"

import {envRevisionsAtom} from "@/oss/components/DeploymentsDashboard/atoms"
import {openSelectDeployVariantModalAtom} from "@/oss/components/DeploymentsDashboard/modals/store/deploymentModalsStore"
import EnhancedDrawer from "@/oss/components/EnhancedUIs/Drawer"
import {JSSTheme} from "@/oss/lib/Types"
import {revisionListAtom} from "@/oss/state/variant/selectors/variant"
Expand Down Expand Up @@ -98,6 +99,8 @@ const DeploymentsDrawerContent = ({
}: DeploymentsDrawerProps) => {
const variants = useAtomValue(revisionListAtom) || []
const envRevisions = useAtomValue(envRevisionsAtom)
const openSelectDeployVariantModal = useSetAtom(openSelectDeployVariantModalAtom)

return (
<div className="flex h-full">
<div className={`flex-1 overflow-auto ${mainContentClassName}`}>
Expand All @@ -118,7 +121,9 @@ const DeploymentsDrawerContent = ({
>
{envRevisions ? (
<UseApiContent
handleOpenSelectDeployVariantModal={() => close()}
handleOpenSelectDeployVariantModal={() =>
openSelectDeployVariantModal({variants, envRevisions})
}
variants={variants}
revisionId={drawerVariantId}
selectedEnvironment={envRevisions}
Expand Down
1 change: 1 addition & 0 deletions web/oss/src/components/DeploymentsDashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const DeploymentsDashboard: FC<DeploymentsDashboardProps> = ({
<Button
type="primary"
onClick={() => envRevisions && openDeploymentsDrawer({initialWidth: 720})}
id="tour-setup-prompt"
>
Use API
</Button>
Expand Down
7 changes: 6 additions & 1 deletion web/oss/src/components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@ import CustomWorkflowBanner from "../CustomWorkflowBanner"
import ProtectedRoute from "../ProtectedRoute/ProtectedRoute"

import BreadcrumbContainer from "./assets/Breadcrumbs"
import {useStyles} from "./assets/styles"
import {StyleProps, useStyles} from "./assets/styles"
import ErrorFallback from "./ErrorFallback"
import {SidebarIsland} from "./SidebarIsland"
import {getDeviceTheme, useAppTheme} from "./ThemeContextProvider"

const OnboardingWidget = dynamic(() => import("../Onboarding/components/OnboardingWidget"), {
ssr: false,
loading: () => null,
})
const FooterIsland = dynamic(() => import("./FooterIsland").then((m) => m.FooterIsland), {
ssr: false,
loading: () => null,
Expand Down Expand Up @@ -305,6 +309,7 @@ const App: React.FC<LayoutProps> = ({children}) => {
{children}
{contextHolder}
</AppWithVariants>
<OnboardingWidget />
</ProtectedRoute>
)}
</Suspense>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import {useEffect, useRef} from "react"

import {useAtomValue, useSetAtom} from "jotai"
import {NextStep, useNextStep} from "@agentaai/nextstepjs"

import {
isNewUserAtom,
onboardingStepsAtom,
triggerOnboardingAtom,
userOnboardingStatusAtom,
} from "@/oss/state/onboarding"
import {urlLocationAtom} from "@/oss/state/url"

import OnboardingCard from "../../index"
import OnboardingAutoAdvance from "../OnboardingAutoAdvance"

const CustomNextStepProvider = ({children}: {children: React.ReactNode}) => {
const onboardingSteps = useAtomValue(onboardingStepsAtom)
const isNewUser = useAtomValue(isNewUserAtom)
const userLocation = useAtomValue(urlLocationAtom)
const userOnboardingJourneyStatus = useAtomValue(userOnboardingStatusAtom)
const manualTrigger = useAtomValue(triggerOnboardingAtom)
const setTriggerOnboarding = useSetAtom(triggerOnboardingAtom)
const {startNextStep} = useNextStep()
const autoStartSignatureRef = useRef<string | null>(null)

const previousSectionRef = useRef(userLocation.resolvedSection ?? userLocation.section)
useEffect(() => {
const resolvedSection = userLocation.resolvedSection ?? userLocation.section
if (previousSectionRef.current !== resolvedSection) {
previousSectionRef.current = resolvedSection
if (!manualTrigger) {
setTriggerOnboarding(null)
}
}
}, [userLocation.resolvedSection, userLocation.section, manualTrigger, setTriggerOnboarding])

useEffect(() => {
if (!isNewUser) {
autoStartSignatureRef.current = null
return
}

const normalizedSection = userLocation.resolvedSection
if (!normalizedSection) {
autoStartSignatureRef.current = null
return
}

if (!onboardingSteps?.length) {
autoStartSignatureRef.current = null
return
}

const currentTour = onboardingSteps[0]
if (!currentTour?.tour) return

const tourSection =
(currentTour.steps?.find((step) => step?.onboardingSection)
?.onboardingSection as keyof typeof userOnboardingJourneyStatus) ??
normalizedSection

const signature = `${tourSection}:${currentTour.tour}:${currentTour.steps?.length ?? 0}`
if (autoStartSignatureRef.current === signature) return

autoStartSignatureRef.current = signature

startNextStep(currentTour.tour)
}, [
isNewUser,
userLocation.resolvedSection,
userOnboardingJourneyStatus,
onboardingSteps,
startNextStep,
])

const lastManualTriggerRef = useRef<typeof manualTrigger>(null)
useEffect(() => {
if (!manualTrigger) {
lastManualTriggerRef.current = null
return
}
if (!onboardingSteps?.length) return
if (lastManualTriggerRef.current === manualTrigger) return

lastManualTriggerRef.current = manualTrigger
const targetTour =
manualTrigger.tourId !== undefined
? (onboardingSteps.find((tour) => tour.tour === manualTrigger.tourId) ??
onboardingSteps[0])
: onboardingSteps[0]
const tourId = targetTour?.tour
if (!tourId) return

startNextStep(tourId)
}, [manualTrigger, onboardingSteps, startNextStep])

const handleComplete = () => {
setTriggerOnboarding(null)
}

return (
<NextStep
steps={onboardingSteps}
cardComponent={OnboardingCard}
showNextStep={true}
onComplete={handleComplete}
>
<OnboardingAutoAdvance />
{children}
</NextStep>
)
}

export default CustomNextStepProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {forwardRef, useEffect, useRef, type MutableRefObject, type ReactNode} from "react"

import clsx from "clsx"

interface NextViewportProps {
id: string
className?: string
children: ReactNode
}

const NextViewport = forwardRef<HTMLDivElement, NextViewportProps>(
({id, className, children}, forwardedRef) => {
const containerRef = useRef<HTMLDivElement | null>(null)

useEffect(() => {
const node = containerRef.current
if (typeof window === "undefined" || !node) return

let animationFrame: number | null = null
const notifyViewportChange = () => {
window.dispatchEvent(new CustomEvent("nextstep:viewport-scroll", {detail: {id}}))
window.dispatchEvent(new Event("resize"))
}

const scheduleNotification = () => {
if (animationFrame) cancelAnimationFrame(animationFrame)
animationFrame = window.requestAnimationFrame(() => {
notifyViewportChange()
})
}

const resizeObserver =
typeof ResizeObserver !== "undefined"
? new ResizeObserver(() => scheduleNotification())
: null

resizeObserver?.observe(node)
node.addEventListener("scroll", scheduleNotification, {passive: true})
scheduleNotification()

return () => {
node.removeEventListener("scroll", scheduleNotification)
resizeObserver?.disconnect()
if (animationFrame) cancelAnimationFrame(animationFrame)
}
}, [id])

const setRef = (node: HTMLDivElement | null) => {
containerRef.current = node
if (typeof forwardedRef === "function") {
forwardedRef(node)
} else if (forwardedRef) {
;(forwardedRef as MutableRefObject<HTMLDivElement | null>).current = node
}
}

return (
<div id={id} ref={setRef} className={clsx("relative h-full w-full", className)}>
{children}
</div>
)
},
)

NextViewport.displayName = "NextViewport"

export default NextViewport
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import {useEffect, useMemo} from "react"

import {useAtomValue, useSetAtom} from "jotai"
import {useNextStep} from "@agentaai/nextstepjs"

import {
onboardingStepsAtom,
triggerOnboardingAtom,
updateUserOnboardingStatusAtom,
} from "@/oss/state/onboarding"
import type {OnboardingStep, UserOnboardingStatus} from "@/oss/state/onboarding/types"
import {urlLocationAtom} from "@/oss/state/url"

const OnboardingAutoAdvance = () => {
const onboardingTours = useAtomValue(onboardingStepsAtom)
const updateUserOnboardingStatus = useSetAtom(updateUserOnboardingStatusAtom)
const setTriggerOnboarding = useSetAtom(triggerOnboardingAtom)
const userLocation = useAtomValue(urlLocationAtom)
const {currentTour, currentStep, isNextStepVisible, setCurrentStep, closeNextStep} =
useNextStep()

const {activeStep, totalSteps} = useMemo(() => {
if (!currentTour) {
return {activeStep: null, totalSteps: 0}
}

const matchingTour = onboardingTours.find((tour) => tour.tour === currentTour)
if (!matchingTour) {
return {activeStep: null, totalSteps: 0}
}

const step = matchingTour.steps[currentStep] as OnboardingStep | undefined
return {activeStep: step ?? null, totalSteps: matchingTour.steps.length}
}, [currentTour, currentStep, onboardingTours])

const resolvedSectionFromLocation = useMemo(
() => userLocation.resolvedSection ?? userLocation.section,
[userLocation.resolvedSection, userLocation.section],
)

useEffect(() => {
if (!activeStep?.advanceOnClick || !activeStep.selector || !isNextStepVisible) {
return
}

const handleClick = async (event: MouseEvent) => {
if (!activeStep.selector) return

const target = event.target
if (!(target instanceof Element)) return

const matchedTarget = target.closest(activeStep.selector)
if (!matchedTarget) {
return
}

try {
await activeStep.onNext?.()
} catch (error) {
console.error("Failed to run onboarding advance handler", error)
}

if (currentStep >= totalSteps - 1) {
const resolvedSection =
(activeStep?.onboardingSection as keyof UserOnboardingStatus | undefined) ??
resolvedSectionFromLocation
if (resolvedSection) {
updateUserOnboardingStatus({section: resolvedSection, status: "done"})
}
setTriggerOnboarding(null)
closeNextStep()
return
}

setCurrentStep(currentStep + 1)
}

document.addEventListener("click", handleClick, true)
return () => {
document.removeEventListener("click", handleClick, true)
}
}, [
activeStep,
currentStep,
totalSteps,
isNextStepVisible,
closeNextStep,
setCurrentStep,
resolvedSectionFromLocation,
setTriggerOnboarding,
updateUserOnboardingStatus,
])

return null
}

export default OnboardingAutoAdvance
Loading
Loading