Skip to content
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

[DRAFT] AAP-32854: Decouple Views from Pipelines #1498

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
Empty file.
40 changes: 40 additions & 0 deletions ansible_ai_connect/ai/api/eventbus/sinks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright Red Hat
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from django.apps import apps
from django.dispatch import Signal, receiver

from ansible_ai_connect.ai.api.model_pipelines.pipelines import (
ChatBotParameters,
ModelPipelineChatBot,
)

chat_service = Signal()


@receiver(chat_service)
def chat_service_receiver(
sender, conversation_id, req_query, req_system_prompt, req_model_id, req_provider, **kwargs
):
llm: ModelPipelineChatBot = apps.get_app_config("ai").get_model_pipeline(ModelPipelineChatBot)
data = llm.invoke(
ChatBotParameters.init(
query=req_query,
system_prompt=req_system_prompt,
model_id=req_model_id or llm.config.model_id,
provider=req_provider,
conversation_id=conversation_id,
)
)
return data
37 changes: 37 additions & 0 deletions ansible_ai_connect/ai/api/eventbus/source.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations

from enum import StrEnum

from ansible_ai_connect.ai.api.eventbus.sinks import chat_service


class EventType(StrEnum):
CHAT = "chat"


class EventBus:

def send(self, event_type: EventType, **kwargs) -> any:
data = None
match event_type:
case "chat":
response = chat_service.send(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We'd send Cloud Events.. something I can refactor this PR to use... if there's any traction for it's full implementation.

event_type,
conversation_id=kwargs["conversation_id"],
req_query=kwargs["query"],
req_system_prompt=kwargs["system_prompt"],
req_model_id=kwargs["model_id"],
req_provider=kwargs["provider"],
)
data = response[0][1]
return data
18 changes: 9 additions & 9 deletions ansible_ai_connect/ai/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from rest_framework.views import APIView

from ansible_ai_connect.ai.api.aws.exceptions import WcaSecretManagerError
from ansible_ai_connect.ai.api.eventbus.source import EventBus, EventType
from ansible_ai_connect.ai.api.exceptions import (
BaseWisdomAPIException,
ChatbotInvalidResponseException,
Expand Down Expand Up @@ -68,7 +69,6 @@
WcaUserTrialExpired,
)
from ansible_ai_connect.ai.api.model_pipelines.pipelines import (
ChatBotParameters,
ContentMatchParameters,
MetaData,
ModelPipelineChatBot,
Expand Down Expand Up @@ -1007,14 +1007,14 @@ def post(self, request) -> Response:
self.event.conversation_id = conversation_id
self.event.modelName = self.req_model_id or self.llm.config.model_id

data = self.llm.invoke(
ChatBotParameters.init(
query=req_query,
system_prompt=req_system_prompt,
model_id=self.req_model_id or self.llm.config.model_id,
provider=req_provider,
conversation_id=conversation_id,
)
event_bus: EventBus = apps.get_app_config("ai").get_event_bus()
data = event_bus.send(
EventType.CHAT,
conversation_id=conversation_id,
query=req_query,
system_prompt=req_system_prompt,
model_id=self.req_model_id,
provider=req_provider,
)

response_serializer = ChatResponseSerializer(data=data)
Expand Down
7 changes: 7 additions & 0 deletions ansible_ai_connect/ai/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
)

from .api.aws.wca_secret_manager import AWSSecretManager, DummySecretManager
from .api.eventbus.source import EventBus

logger = logging.getLogger(__name__)

Expand All @@ -50,6 +51,7 @@ class AiConfig(AppConfig):
_ansible_lint_caller = UNINITIALIZED
_reports_postman = UNINITIALIZED
_pipeline_factory = UNINITIALIZED
_event_bus = UNINITIALIZED

def ready(self) -> None:
self._pipeline_factory = ModelPipelineFactory()
Expand All @@ -58,6 +60,11 @@ def ready(self) -> None:
def get_model_pipeline(self, feature: Type[PIPELINE_TYPE]) -> PIPELINE_TYPE:
return self._pipeline_factory.get_pipeline(feature)

def get_event_bus(self):
if self._event_bus is UNINITIALIZED:
self._event_bus = EventBus()
return self._event_bus

def get_ari_caller(self):
# Django calls apps.ready() when registering INSTALLED_APPS
# We can therefore guarantee self.model_mesh_client is not None
Expand Down
Loading