-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat: surveys on Max AI #33111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat: surveys on Max AI #33111
Conversation
Size Change: 0 B Total Size: 2.57 MB ℹ️ View Unchanged
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works really well! Will review again when it has tests/it's out of draft 🫶
<
8000
a href="/PostHog/posthog/pull/33111/commits/61e9f5374db3357d3cfe5685ef9e9e3bd09ad3dd" class="Link--secondary">61e9f53
📸 UI snapshots have been updated2 snapshot changes in total. 0 added, 2 modified, 0 deleted:
Triggered by this commit. |
📸 UI snapshots have been updated1 snapshot changes in total. 0 added, 1 modified, 0 deleted:
Triggered by this commit. |
📸 UI snapshots have been updated1 snapshot changes in total. 0 added, 1 modified, 0 deleted:
Triggered by this commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Summary
Implements AI-powered survey creation through Max AI, enabling users to create and launch surveys using natural language chat interactions within PostHog.
- Added
SurveyCreatorTool
inproducts/surveys/backend/max_tools.py
with GPT-4 integration for converting natural language to structured survey configurations - Defined comprehensive Pydantic schemas in
products/surveys/backend/survey_schema.py
for validating LLM output and enforcing survey configuration rules - Added
DEFAULT_SURVEY_APPEARANCE
inposthog/constants.py
to maintain consistent styling hierarchy (frontend defaults -> team overrides -> LLM overrides) - Wrapped
Surveys
component withSurveysWithMaxTool
infrontend/src/scenes/surveys/Surveys.tsx
to provide AI chat interface while preserving existing functionality - Implemented extensive test suite in
products/surveys/backend/test_max_tools.py
covering survey creation, validation, and edge cases
10 files reviewed, 9 comments
Edit PR Review Bot Settings | Greptile
@@ -319,3 +319,32 @@ class FlagRequestType(StrEnum): | |||
PERMITTED_FORUM_DOMAINS = ["localhost", "posthog.com"] | |||
|
|||
INVITE_DAYS_VALIDITY = 3 # number of days for which team invites are valid | |||
|
|||
# Sync with frontend/src/scenes/surveys/constants.tsx | |||
DEFAULT_SURVEY_APPEARANCE = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Consider alphabetizing the properties in DEFAULT_SURVEY_APPEARANCE for better maintainability
thankYouMessageHeader: Optional[str] = Field(default=DEFAULT_SURVEY_APPEARANCE["thankYouMessageHeader"]) | ||
thankYouMessageDescription: Optional[str] = Field(default="We appreciate your feedback.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Default thankYouMessageDescription hardcoded to 'We appreciate your feedback' - should use the DEFAULT_SURVEY_APPEARANCE constant like other fields
thankYouMessageHeader: Optional[str] = Field(default=DEFAULT_SURVEY_APPEARANCE["thankYouMessageHeader"]) | |
thankYouMessageDescription: Optional[str] = Field(default="We appreciate your feedback.") | |
thankYouMessageHeader: Optional[str] = Field(default=DEFAULT_SURVEY_APPEARANCE["thankYouMessageHeader"]) | |
thankYouMessageDescription: Optional[str] = Field(default=DEFAULT_SURVEY_APPEARANCE["thankYouMessageDescription"]) |
widgetType: Optional[str] = Field(default=DEFAULT_SURVEY_APPEARANCE["widgetType"]) | ||
widgetLabel: Optional[str] = Field(default=DEFAULT_SURVEY_APPEARANCE["widgetLabel"]) | ||
widgetColor: Optional[str] = Field(default=DEFAULT_SURVEY_APPEARANCE["widgetColor"]) | ||
zIndex: Optional[str] = Field(default=DEFAULT_SURVEY_APPEARANCE["zIndex"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: zIndex should be typed as number instead of str to maintain type consistency and prevent invalid values
## Current Context | ||
Team survey configuration: {team_survey_config} | ||
Existing surveys: {existing_surveys} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Inconsistent format in template variables - using both {team_survey_config} and {existing_surveys} at line 45-46, but then only {team_survey_config} again at line 73. Ensure consistent context injection.
- **PMF**: "How would you feel if you could no longer use [product]?" (Very disappointed/Somewhat disappointed/Not disappointed) | ||
- **Feedback**: "What could we improve about [feature]?" (open text, optional) | ||
Current team survey settings: {team_survey_config}""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Redundant injection of team_survey_config at end of prompt - already included in 'Current Context' section above. Remove line 73 to avoid confusion.
# Use the proper serializer for validation and creation | ||
from posthog.api.survey import SurveySerializerCreateUpdateOnly | ||
from datetime import datetime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Move these imports to the top of the file with other imports
# Use the proper serializer for validation and creation | |
from posthog.api.survey import SurveySerializerCreateUpdateOnly | |
from datetime import datetime | |
from posthog.api.survey import SurveySerializerCreateUpdateOnly | |
from datetime import datetime |
if result.should_launch: | ||
survey_data["start_date"] = datetime.now() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Using datetime.now() without timezone awareness could cause issues. Consider using django.utils.timezone.now()
except Exception: | ||
return "Unable to load existing surveys" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Bare except clause is too broad - specify which exceptions you expect here for better error handling
You are helping create surveys for this PostHog team. | ||
|
||
Current context: | ||
- Total surveys: {{{total_surveys_count}}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: total_surveys_count is referenced in template but never passed to chain.invoke()
Problem
Closes #32818
Changes
Adds AI survey creation to PostHog's Max tool - users can now create and launch surveys through natural language chat.
What's New
create_survey
MaxTool that converts natural language into configured surveysKey Features
Testing
Navigate to Surveys page and try:
Implementation
products/surveys/backend/
Part of the Max AI initiative to streamline PostHog workflows through natural language.
Did you write or update any docs for this change?
How did you test this code?
Unit/integration tests for the max too. @kappa90 i'm not that familiar with evals though, maybe we can pair on it and you can show me around? Are they a good fit for this case?