Skip to content

Commit

Permalink
feedback: allow events coming from roleGen (#1502)
Browse files Browse the repository at this point in the history
Accept the action and feeback events coming from the extension for the role generation.
  • Loading branch information
goneri authored Feb 4, 2025
1 parent ef52c47 commit b2e04ee
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 30 deletions.
28 changes: 22 additions & 6 deletions ansible_ai_connect/ai/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ class IssueFeedback(serializers.Serializer):
)


# TODO: we don't use this class, we can remove it
class PlaybookGenerationFeedback(serializers.Serializer):
USER_ACTION_CHOICES = (("0", "ACCEPTED"), ("1", "REJECTED"), ("2", "IGNORED"))

Expand All @@ -274,10 +275,21 @@ class PlaybookGenerationFeedback(serializers.Serializer):
)


class PlaybookGenerationAction(serializers.Serializer):
ACTIONS = (("0", "OPEN"), ("1", "CLOSE_CANCEL"), ("2", "TRANSITION"), ("3", "CLOSE_ACCEPT"))
class GenerationActionEnum(serializers.ChoiceField):
def __init__(self):
super().__init__(
choices=(
("0", "OPEN"),
("1", "CLOSE_CANCEL"),
("2", "TRANSITION"),
("3", "CLOSE_ACCEPT"),
),
required=True,
)


action = serializers.ChoiceField(choices=ACTIONS, required=True)
class PlaybookGenerationAction(serializers.Serializer):
action = GenerationActionEnum()
wizardId = serializers.UUIDField(
format="hex_verbose",
required=True,
Expand All @@ -297,9 +309,7 @@ class PlaybookGenerationAction(serializers.Serializer):


class PlaybookExplanationFeedback(serializers.Serializer):
USER_ACTION_CHOICES = (("0", "ACCEPTED"), ("1", "REJECTED"), ("2", "IGNORED"))

action = serializers.ChoiceField(choices=USER_ACTION_CHOICES, required=True)
action = GenerationActionEnum()
explanationId = serializers.UUIDField(
format="hex_verbose",
required=True,
Expand All @@ -308,6 +318,10 @@ class PlaybookExplanationFeedback(serializers.Serializer):
)


class RoleGenerationAction(PlaybookGenerationAction):
pass


class ChatRequestSerializer(serializers.Serializer):
conversation_id = serializers.UUIDField(
format="hex_verbose",
Expand Down Expand Up @@ -395,8 +409,10 @@ class FeedbackRequestSerializer(Metadata):
metadata = Metadata(required=False)
model = serializers.CharField(required=False)
playbookExplanationFeedback = PlaybookExplanationFeedback(required=False)
# NOTE: we can remove the following line, we don't use the event
playbookGenerationFeedback = PlaybookGenerationFeedback(required=False)
playbookGenerationAction = PlaybookGenerationAction(required=False)
roleGenerationAction = RoleGenerationAction(required=False)
sentimentFeedback = SentimentFeedback(required=False)
suggestionQualityFeedback = SuggestionQualityFeedback(required=False)
chatFeedback = ChatFeedback(required=False)
Expand Down
6 changes: 6 additions & 0 deletions ansible_ai_connect/ai/api/telemetry/schema2.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class AnalyticsTelemetryEvents(Enum):
RECOMMENDATION_ACTION = "Recommendation Action"
PRODUCT_FEEDBACK = "Product Feedback"
PLAYBOOK_GENERATION_ACTION = "Playbook Generation Action"
ROLE_GENERATION_ACTION = "Role Generation Action"
ONECLICK_TRIAL_STARTED = "OneClickTrial Started"


Expand Down Expand Up @@ -61,6 +62,11 @@ class AnalyticsPlaybookGenerationWizard:
)


@frozen
class AnalyticsRoleGenerationWizard(AnalyticsPlaybookGenerationWizard):
pass


@frozen
class AnalyticsRecommendationAction:
action: int = field(
Expand Down
24 changes: 14 additions & 10 deletions ansible_ai_connect/ai/api/tests/test_feedback_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import platform
import uuid
from http import HTTPStatus
from unittest import skip
from unittest.mock import Mock, patch

from django.apps import apps
Expand Down Expand Up @@ -382,26 +381,31 @@ def test_feedback_explanation(self):
properties = segment_events[0]["properties"]
self.assertEqual(properties["action"], "1")

@skip("Schema2 event is not enabled yet")
def test_feedback_generation(self):
action = {
"action": 3,
"generationId": "2832e159-e0fe-4efc-9288-d60c96c88666",
"wizardId": "f3c5a9c4-9170-40b3-b46f-de387234410b",
"fromPage": 2,
"toPage": 3,
}
payload = {
"playbookGenerationAction": {
"action": 3,
"generationId": "2832e159-e0fe-4efc-9288-d60c96c88666",
"wizardId": "f3c5a9c4-9170-40b3-b46f-de387234410b",
"fromPage": 2,
"toPage": 3,
},
"playbookGenerationAction": action,
"roleGenerationAction": action,
}
self.client.force_authenticate(user=self.user)
with self.assertLogs(logger="root", level="DEBUG") as log:
r = self.client.post(self.api_version_reverse("feedback"), payload, format="json")
self.assertEqual(r.status_code, HTTPStatus.OK)

segment_events = self.extractSegmentEventsFromLog(log)
self.assertTrue(len(segment_events) > 0)
self.assertTrue(len(segment_events) == 2)
properties = segment_events[0]["properties"]
self.assertEqual(properties["action"], 3)
self.assertEqual(segment_events[0]["event"], "playbookGenerationAction")
properties = segment_events[1]["properties"]
self.assertEqual(properties["action"], 3)
self.assertEqual(segment_events[1]["event"], "roleGenerationAction")

def test_feedback_chatbot(self):
payload = {
Expand Down
30 changes: 30 additions & 0 deletions ansible_ai_connect/ai/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
AnalyticsPlaybookGenerationWizard,
AnalyticsProductFeedback,
AnalyticsRecommendationAction,
AnalyticsRoleGenerationWizard,
AnalyticsTelemetryEvents,
)
from ansible_ai_connect.ai.api.utils.segment import (
Expand Down Expand Up @@ -128,6 +129,7 @@
IssueFeedback,
PlaybookExplanationFeedback,
PlaybookGenerationAction,
RoleGenerationAction,
SentimentFeedback,
SuggestionQualityFeedback,
)
Expand Down Expand Up @@ -342,6 +344,9 @@ def write_to_segment(
playbook_generation_action_data: PlaybookGenerationAction = validated_data.get(
"playbookGenerationAction"
)
role_generation_action_data: RoleGenerationAction = validated_data.get(
"roleGenerationAction"
)
chatbot_feedback_data: ChatFeedback = validated_data.get("chatFeedback")

ansible_extension_version = validated_data.get("metadata", {}).get(
Expand Down Expand Up @@ -450,6 +455,31 @@ def write_to_segment(
user,
ansible_extension_version,
)
if role_generation_action_data:
action = int(role_generation_action_data.get("action"))
from_page = role_generation_action_data.get("fromPage", 0)
to_page = role_generation_action_data.get("toPage", 0)
wizard_id = str(role_generation_action_data.get("wizardId", ""))
event = {
"action": action,
"wizardId": wizard_id,
"fromPage": from_page,
"toPage": to_page,
"modelName": model_name,
}
send_segment_event(event, "roleGenerationAction", user)
if False and from_page > 1 and action in [1, 3]:
send_segment_analytics_event(
AnalyticsTelemetryEvents.ROLE_GENERATION_ACTION,
lambda: AnalyticsRoleGenerationWizard(
action=action,
model_name=model_name,
rh_user_org_id=org_id,
wizard_id=str(role_generation_action_data.get("wizardId", "")),
),
user,
ansible_extension_version,
)

if chatbot_feedback_data:
response_data = chatbot_feedback_data.get("response")
Expand Down
51 changes: 37 additions & 14 deletions tools/openapi-schema/ansible-ai-connect-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,18 @@ components:
* `0` - ACCEPTED
* `1` - REJECTED
* `2` - IGNORED
Action693Enum:
enum:
- '0'
- '1'
- '2'
- '3'
type: string
description: |-
* `0` - OPEN
* `1` - CLOSE_CANCEL
* `2` - TRANSITION
* `3` - CLOSE_ACCEPT
ChatFeedback:
type: object
properties:
Expand Down Expand Up @@ -939,6 +951,8 @@ components:
$ref: '#/components/schemas/PlaybookGenerationFeedback'
playbookGenerationAction:
$ref: '#/components/schemas/PlaybookGenerationAction'
roleGenerationAction:
$ref: '#/components/schemas/RoleGenerationAction'
sentimentFeedback:
$ref: '#/components/schemas/SentimentFeedback'
suggestionQualityFeedback:
Expand Down Expand Up @@ -1205,7 +1219,7 @@ components:
type: object
properties:
action:
$ref: '#/components/schemas/Action4c6Enum'
$ref: '#/components/schemas/Action693Enum'
explanationId:
type: string
format: uuid
Expand All @@ -1218,7 +1232,7 @@ components:
type: object
properties:
action:
$ref: '#/components/schemas/PlaybookGenerationActionActionEnum'
$ref: '#/components/schemas/Action693Enum'
wizardId:
type: string
format: uuid
Expand All @@ -1235,18 +1249,6 @@ components:
required:
- action
- wizardId
PlaybookGenerationActionActionEnum:
enum:
- '0'
- '1'
- '2'
- '3'
type: string
description: |-
* `0` - OPEN
* `1` - CLOSE_CANCEL
* `2` - TRANSITION
* `3` - CLOSE_ACCEPT
PlaybookGenerationFeedback:
type: object
properties:
Expand All @@ -1270,6 +1272,27 @@ components:
required:
- docs_url
- title
RoleGenerationAction:
type: object
properties:
action:
$ref: '#/components/schemas/Action693Enum'
wizardId:
type: string
format: uuid
title: wizard ID
description: A UUID that identifies the UI session.
fromPage:
type: integer
title: page of origin
description: A number that indicate the page of origin
toPage:
type: integer
title: destination page
description: A number that indicate the destination page
required:
- action
- wizardId
SentimentEnum:
enum:
- '0'
Expand Down

0 comments on commit b2e04ee

Please sign in to comment.