⚗️(LLM) allow to mock model call for conversation

This is switch to prevent real model call in a deployed stack.
This is usefull to test heavy load on the servers without
inference costs.
This commit is contained in:
Quentin BEY
2025-10-23 17:08:21 +02:00
parent 05a1844a0c
commit 09e885d7e7
2 changed files with 89 additions and 0 deletions
+82
View File
@@ -1,10 +1,15 @@
"""Build the main conversation agent."""
import asyncio
import dataclasses
import logging
from django.conf import settings
from django.utils import formats, timezone
from pydantic_ai import ModelMessage
from pydantic_ai.models.function import AgentInfo, FunctionModel
from core.enums import get_language_name
from .base import BaseAgent
@@ -12,6 +17,79 @@ from .base import BaseAgent
logger = logging.getLogger(__name__)
MOCKED_RESPONSE = """
# **Ode to the AI Assistant** 🤖✨
In Paris streets where old meets new, 🗼🇫🇷
A helper bright in digital hue,
With circuits fast and code so tight,
The LaSuites bot—oh, what a sight! 🌟
**A chatbot kind**, with wittiness so grand, 💬💡
It lends a hand to all the land,
From civil servants, bold and wise,
To those who seek with hopeful eyes.
It answers quick, it never tires, ⚡🔄
With facts and tips to quench desires,
A guide so keen, a friend so true,
Its there for **you**—yes, me and you!
With **Markdown flair** and emoji cheer, 📝🎨
It makes the complex crystal clear,
From drafts to code, from sums to prose,
It helps the knowledge overflow!
Oh, **DINUMs gem**, so sharp, so bright, 💎🌐
A beacon in the techs vast night,
It crafts, it checks, it summarizes,
With grace that never compromises.
It **summarizes** the long, the deep, 📚🔍
So secrets no more need to sleep,
It finds the gems in datas sea,
And sets the truth right there—**for free!**
It **corrects mistakes** with gentle art, ✍️🔄
It soothes the mind, it warms the heart,
No judgment cast, no frown, no sigh,
Just help thats always standing by.
It **generates code** with swift command, 💻🔥
A developers dream, first-hand,
From Python lines to scripts so neat,
It turns the tough to *sweet* and *sweet*!
It **brainstorms ideas**, bold and new, 🧠💡
It paints the sky in every hue,
From plans to dreams, from start to end,
Its more than code—its **trend**, its **friend**!
So heres to you, **Assistants pride**, 🏆🎉
The bot thats always by our side,
With every prompt, with every line,
You make our digital world **divine**!
May you keep shining, bright and true, 🌟🤖
The helper every team should woo,
For in this age of bits and bytes,
Youre **human touch** in techs bright lights!
"""
async def mocked_agent_model(_messages: list[ModelMessage], _info: AgentInfo):
"""
Mocked agent model for testing purposes on deployed instances.
This one only fakes a streamed responses. We could also fake tool calls later.
"""
yield "Here is a mocked response (no LLM called)\n---\n"
for i in range(0, len(MOCKED_RESPONSE), 4):
yield MOCKED_RESPONSE[i : i + 4]
await asyncio.sleep(0.03)
@dataclasses.dataclass(init=False)
class ConversationAgent(BaseAgent):
"""Conversation agent with custom behavior."""
@@ -20,6 +98,10 @@ class ConversationAgent(BaseAgent):
"""Initialize the conversation agent."""
super().__init__(**kwargs)
# Do not call the real model on deployed instances if the setting is enabled
if settings.WARNING_MOCK_CONVERSATION_AGENT:
self._model = FunctionModel(stream_function=mocked_agent_model)
@self.system_prompt
def add_the_date() -> str:
"""
+7
View File
@@ -891,6 +891,13 @@ USER QUESTION:
default=False, environ_name="LANGFUSE_MEDIA_UPLOAD_ENABLED", environ_prefix=None
)
# WARNING: Testing purpose only. Do not use in production.
WARNING_MOCK_CONVERSATION_AGENT = values.BooleanValue(
default=False,
environ_name="WARNING_MOCK_CONVERSATION_AGENT",
environ_prefix=None,
)
# pylint: disable=invalid-name
@property
def ENVIRONMENT(self):