Skip to content

Commit

Permalink
Add persona stats (#3282)
Browse files Browse the repository at this point in the history
* Added a chart to display persona message stats

* polish

* k

* hope this works

* cleanup
  • Loading branch information
hagen-danswer authored Dec 5, 2024
1 parent c81e704 commit 14772de
Show file tree
Hide file tree
Showing 5 changed files with 442 additions and 3 deletions.
64 changes: 64 additions & 0 deletions backend/ee/danswer/db/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,67 @@ def fetch_danswerbot_analytics(
)

return results


def fetch_persona_message_analytics(
db_session: Session,
persona_id: int,
start: datetime.datetime,
end: datetime.datetime,
) -> list[tuple[int, datetime.date]]:
"""Gets the daily message counts for a specific persona within the given time range."""
query = (
select(
func.count(ChatMessage.id),
cast(ChatMessage.time_sent, Date),
)
.join(
ChatSession,
ChatMessage.chat_session_id == ChatSession.id,
)
.where(
or_(
ChatMessage.alternate_assistant_id == persona_id,
ChatSession.persona_id == persona_id,
),
ChatMessage.time_sent >= start,
ChatMessage.time_sent <= end,
ChatMessage.message_type == MessageType.ASSISTANT,
)
.group_by(cast(ChatMessage.time_sent, Date))
.order_by(cast(ChatMessage.time_sent, Date))
)

return [tuple(row) for row in db_session.execute(query).all()]


def fetch_persona_unique_users(
db_session: Session,
persona_id: int,
start: datetime.datetime,
end: datetime.datetime,
) -> list[tuple[int, datetime.date]]:
"""Gets the daily unique user counts for a specific persona within the given time range."""
query = (
select(
func.count(func.distinct(ChatSession.user_id)),
cast(ChatMessage.time_sent, Date),
)
.join(
ChatSession,
ChatMessage.chat_session_id == ChatSession.id,
)
.where(
or_(
ChatMessage.alternate_assistant_id == persona_id,
ChatSession.persona_id == persona_id,
),
ChatMessage.time_sent >= start,
ChatMessage.time_sent <= end,
ChatMessage.message_type == MessageType.ASSISTANT,
)
.group_by(cast(ChatMessage.time_sent, Date))
.order_by(cast(ChatMessage.time_sent, Date))
)

return [tuple(row) for row in db_session.execute(query).all()]
82 changes: 79 additions & 3 deletions backend/ee/danswer/server/analytics/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@
from danswer.db.models import User
from ee.danswer.db.analytics import fetch_danswerbot_analytics
from ee.danswer.db.analytics import fetch_per_user_query_analytics
from ee.danswer.db.analytics import fetch_persona_message_analytics
from ee.danswer.db.analytics import fetch_persona_unique_users
from ee.danswer.db.analytics import fetch_query_analytics

router = APIRouter(prefix="/analytics")


_DEFAULT_LOOKBACK_DAYS = 30


class QueryAnalyticsResponse(BaseModel):
total_queries: int
total_likes: int
Expand All @@ -33,7 +38,7 @@ def get_query_analytics(
daily_query_usage_info = fetch_query_analytics(
start=start
or (
datetime.datetime.utcnow() - datetime.timedelta(days=30)
datetime.datetime.utcnow() - datetime.timedelta(days=_DEFAULT_LOOKBACK_DAYS)
), # default is 30d lookback
end=end or datetime.datetime.utcnow(),
db_session=db_session,
Expand Down Expand Up @@ -64,7 +69,7 @@ def get_user_analytics(
daily_query_usage_info_per_user = fetch_per_user_query_analytics(
start=start
or (
datetime.datetime.utcnow() - datetime.timedelta(days=30)
datetime.datetime.utcnow() - datetime.timedelta(days=_DEFAULT_LOOKBACK_DAYS)
), # default is 30d lookback
end=end or datetime.datetime.utcnow(),
db_session=db_session,
Expand Down Expand Up @@ -98,7 +103,7 @@ def get_danswerbot_analytics(
daily_danswerbot_info = fetch_danswerbot_analytics(
start=start
or (
datetime.datetime.utcnow() - datetime.timedelta(days=30)
datetime.datetime.utcnow() - datetime.timedelta(days=_DEFAULT_LOOKBACK_DAYS)
), # default is 30d lookback
end=end or datetime.datetime.utcnow(),
db_session=db_session,
Expand All @@ -115,3 +120,74 @@ def get_danswerbot_analytics(
]

return resolution_results


class PersonaMessageAnalyticsResponse(BaseModel):
total_messages: int
date: datetime.date
persona_id: int


@router.get("/admin/persona/messages")
def get_persona_messages(
persona_id: int,
start: datetime.datetime | None = None,
end: datetime.datetime | None = None,
_: User | None = Depends(current_admin_user),
db_session: Session = Depends(get_session),
) -> list[PersonaMessageAnalyticsResponse]:
"""Fetch daily message counts for a single persona within the given time range."""
start = start or (
datetime.datetime.utcnow() - datetime.timedelta(days=_DEFAULT_LOOKBACK_DAYS)
)
end = end or datetime.datetime.utcnow()

persona_message_counts = []
for count, date in fetch_persona_message_analytics(
db_session=db_session,
persona_id=persona_id,
start=start,
end=end,
):
persona_message_counts.append(
PersonaMessageAnalyticsResponse(
total_messages=count,
date=date,
persona_id=persona_id,
)
)

return persona_message_counts


class PersonaUniqueUsersResponse(BaseModel):
unique_users: int
date: datetime.date
persona_id: int


@router.get("/admin/persona/unique-users")
def get_persona_unique_users(
persona_id: int,
start: datetime.datetime,
end: datetime.datetime,
_: User | None = Depends(current_admin_user),
db_session: Session = Depends(get_session),
) -> list[PersonaUniqueUsersResponse]:
"""Get unique users per day for a single persona."""
unique_user_counts = []
daily_counts = fetch_persona_unique_users(
db_session=db_session,
persona_id=persona_id,
start=start,
end=end,
)
for count, date in daily_counts:
unique_user_counts.append(
PersonaUniqueUsersResponse(
unique_users=count,
date=date,
persona_id=persona_id,
)
)
return unique_user_counts
66 changes: 66 additions & 0 deletions web/src/app/ee/admin/performance/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,69 @@ export function getDatesList(startDate: Date): string[] {

return datesList;
}

export interface PersonaMessageAnalytics {
total_messages: number;
date: string;
persona_id: number;
}

export interface PersonaSnapshot {
id: number;
name: string;
description: string;
is_visible: boolean;
is_public: boolean;
}

export const usePersonaMessages = (
personaId: number | undefined,
timeRange: DateRangePickerValue
) => {
const url = buildApiPath(`/api/analytics/admin/persona/messages`, {
persona_id: personaId?.toString(),
start: convertDateToStartOfDay(timeRange.from)?.toISOString(),
end: convertDateToEndOfDay(timeRange.to)?.toISOString(),
});

const { data, error, isLoading } = useSWR<PersonaMessageAnalytics[]>(
personaId !== undefined ? url : null,
errorHandlingFetcher
);

return {
data,
error,
isLoading,
refreshPersonaMessages: () => mutate(url),
};
};

export interface PersonaUniqueUserAnalytics {
unique_users: number;
date: string;
persona_id: number;
}

export const usePersonaUniqueUsers = (
personaId: number | undefined,
timeRange: DateRangePickerValue
) => {
const url = buildApiPath(`/api/analytics/admin/persona/unique-users`, {
persona_id: personaId?.toString(),
start: convertDateToStartOfDay(timeRange.from)?.toISOString(),
end: convertDateToEndOfDay(timeRange.to)?.toISOString(),
});

const { data, error, isLoading } = useSWR<PersonaUniqueUserAnalytics[]>(
personaId !== undefined ? url : null,
errorHandlingFetcher
);

return {
data,
error,
isLoading,
refreshPersonaUniqueUsers: () => mutate(url),
};
};
Loading

0 comments on commit 14772de

Please sign in to comment.