Skip to content

Commit

Permalink
feedback: allow events coming from roleGen
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 committed Jan 28, 2025
1 parent b9818d6 commit b4ce2a0
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 61 deletions.
28 changes: 11 additions & 17 deletions ansible_ai_connect/ai/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,22 +262,14 @@ class IssueFeedback(serializers.Serializer):
)


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

action = serializers.ChoiceField(choices=USER_ACTION_CHOICES, required=True)
wizardId = serializers.UUIDField(
format="hex_verbose",
required=True,
label="Outline ID",
help_text="A UUID that identifies the UI session.",
)
GenerationActionEnum = serializers.ChoiceField(
choices=(("0", "OPEN"), ("1", "CLOSE_CANCEL"), ("2", "TRANSITION"), ("3", "CLOSE_ACCEPT")),
required=True,
)


class PlaybookGenerationAction(serializers.Serializer):
ACTIONS = (("0", "OPEN"), ("1", "CLOSE_CANCEL"), ("2", "TRANSITION"), ("3", "CLOSE_ACCEPT"))

action = serializers.ChoiceField(choices=ACTIONS, required=True)
action = GenerationActionEnum
wizardId = serializers.UUIDField(
format="hex_verbose",
required=True,
Expand All @@ -297,9 +289,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 +298,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 +389,8 @@ class FeedbackRequestSerializer(Metadata):
metadata = Metadata(required=False)
model = serializers.CharField(required=False)
playbookExplanationFeedback = PlaybookExplanationFeedback(required=False)
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
33 changes: 23 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 @@ -380,26 +379,40 @@ 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):
payload = {
"playbookGenerationAction": {
"action": 3,
"generationId": "2832e159-e0fe-4efc-9288-d60c96c88666",
"wizardId": "f3c5a9c4-9170-40b3-b46f-de387234410b",
"fromPage": 2,
"toPage": 3,
payload = (
{
"playbookGenerationAction": {
"action": 3,
"action": 3,
"generationId": "2832e159-e0fe-4efc-9288-d60c96c88666",
"generationId": "2832e159-e0fe-4efc-9288-d60c96c88666",
"wizardId": "f3c5a9c4-9170-40b3-b46f-de387234410b",
"wizardId": "f3c5a9c4-9170-40b3-b46f-de387234410b",
"fromPage": 2,
"fromPage": 2,
"toPage": 3,
"toPage": 3,
}
},
)
payload = {
"playbookGenerationAction": payload,
"roleGenerationAction": payload,
}
self.client.force_authenticate(user=self.user)
with self.assertLogs(logger="root", level="DEBUG") as log:
r = self.client.post(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
76 changes: 42 additions & 34 deletions tools/openapi-schema/ansible-ai-connect-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -695,16 +695,18 @@ paths:
description: One or more backend services are unavailable.
components:
schemas:
Action4c6Enum:
Action693Enum:
enum:
- '0'
- '1'
- '2'
- '3'
type: string
description: |-
* `0` - ACCEPTED
* `1` - REJECTED
* `2` - IGNORED
* `0` - OPEN
* `1` - CLOSE_CANCEL
* `2` - TRANSITION
* `3` - CLOSE_ACCEPT
ChatFeedback:
type: object
properties:
Expand Down Expand Up @@ -958,10 +960,10 @@ components:
type: string
playbookExplanationFeedback:
$ref: '#/components/schemas/PlaybookExplanationFeedback'
playbookGenerationFeedback:
$ref: '#/components/schemas/PlaybookGenerationFeedback'
playbookGenerationAction:
$ref: '#/components/schemas/PlaybookGenerationAction'
roleGenerationAction:
$ref: '#/components/schemas/RoleGenerationAction'
sentimentFeedback:
$ref: '#/components/schemas/SentimentFeedback'
suggestionQualityFeedback:
Expand Down Expand Up @@ -1147,7 +1149,7 @@ components:
documentUri:
type: string
action:
$ref: '#/components/schemas/Action4c6Enum'
$ref: '#/components/schemas/InlineSuggestionFeedbackActionEnum'
error:
type: string
suggestionId:
Expand All @@ -1158,6 +1160,16 @@ components:
required:
- action
- suggestionId
InlineSuggestionFeedbackActionEnum:
enum:
- '0'
- '1'
- '2'
type: string
description: |-
* `0` - ACCEPTED
* `1` - REJECTED
* `2` - IGNORED
IssueFeedback:
type: object
properties:
Expand Down Expand Up @@ -1228,7 +1240,7 @@ components:
type: object
properties:
action:
$ref: '#/components/schemas/Action4c6Enum'
$ref: '#/components/schemas/Action693Enum'
explanationId:
type: string
format: uuid
Expand All @@ -1241,7 +1253,7 @@ components:
type: object
properties:
action:
$ref: '#/components/schemas/PlaybookGenerationActionActionEnum'
$ref: '#/components/schemas/Action693Enum'
wizardId:
type: string
format: uuid
Expand All @@ -1258,31 +1270,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:
action:
$ref: '#/components/schemas/Action4c6Enum'
wizardId:
type: string
format: uuid
title: Outline ID
description: A UUID that identifies the UI session.
required:
- action
- wizardId
ReferencedDocuments:
type: object
properties:
Expand All @@ -1293,6 +1280,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 b4ce2a0

Please sign in to comment.