First commit
This commit is contained in:
0
packages/dialogflow/README.md
Normal file
0
packages/dialogflow/README.md
Normal file
21
packages/dialogflow/pyproject.toml
Normal file
21
packages/dialogflow/pyproject.toml
Normal file
@@ -0,0 +1,21 @@
|
||||
[project]
|
||||
name = "dialogflow"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
authors = [
|
||||
{ name = "Anibal Angulo", email = "a8065384@banorte.com" }
|
||||
]
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"google-cloud-dialogflow-cx",
|
||||
"typer",
|
||||
"rich"
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
conv-agents = "dialogflow.cli:app"
|
||||
|
||||
[build-system]
|
||||
requires = ["uv_build>=0.8.12,<0.9.0"]
|
||||
build-backend = "uv_build"
|
||||
2
packages/dialogflow/src/dialogflow/__init__.py
Normal file
2
packages/dialogflow/src/dialogflow/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
def hello() -> str:
|
||||
return "Hello from dialogflow!"
|
||||
54
packages/dialogflow/src/dialogflow/cli.py
Normal file
54
packages/dialogflow/src/dialogflow/cli.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import typer
|
||||
from rich import print
|
||||
|
||||
from .main import DialogflowAgent
|
||||
|
||||
app = typer.Typer()
|
||||
|
||||
@app.command()
|
||||
def send(
|
||||
message: str = typer.Argument(..., help="The message to send to the agent."),
|
||||
flow_id: str = typer.Option(None, "--flow-id", "-f", help="The specific flow ID to target."),
|
||||
):
|
||||
"""
|
||||
Sends a message to the Dialogflow CX agent and prints the response.
|
||||
"""
|
||||
try:
|
||||
agent = DialogflowAgent()
|
||||
response = agent.call(query=message, flow_id=flow_id)
|
||||
print(f"Agent: {response['response_text']}")
|
||||
print(f"[dim]Match Type: {response['match_type']} | Details: {response['details']}[/dim]")
|
||||
except Exception as e:
|
||||
print(f"[bold red]Error:[/bold red] {e}")
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
@app.command()
|
||||
def chat(
|
||||
flow_id: str = typer.Option(None, "--flow-id", "-f", help="The specific flow ID to start the conversation with."),
|
||||
):
|
||||
"""
|
||||
Starts a multi-turn, stateful conversation with the Dialogflow CX agent.
|
||||
"""
|
||||
try:
|
||||
agent = DialogflowAgent()
|
||||
print("[bold green]Starting a new conversation. Type 'exit' or 'quit' to end.[/bold green]")
|
||||
|
||||
is_first_message = True
|
||||
while True:
|
||||
message = input("You: ")
|
||||
if message.lower() in ["exit", "quit"]:
|
||||
print("[bold yellow]Ending conversation.[/bold yellow]")
|
||||
break
|
||||
|
||||
# Only use the flow_id for the very first message in the chat session
|
||||
response = agent.call(query=message, flow_id=flow_id if is_first_message else None)
|
||||
is_first_message = False
|
||||
|
||||
print(f"Agent: {response['response_text']}")
|
||||
print(f"[dim]Match Type: {response['match_type']} | Details: {response['details']}[/dim]")
|
||||
except Exception as e:
|
||||
print(f"[bold red]Error:[/bold red] {e}")
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
app()
|
||||
80
packages/dialogflow/src/dialogflow/main.py
Normal file
80
packages/dialogflow/src/dialogflow/main.py
Normal file
@@ -0,0 +1,80 @@
|
||||
import uuid
|
||||
|
||||
from google.api_core import client_options
|
||||
from google.cloud import dialogflowcx_v3beta1 as dialogflow
|
||||
|
||||
from rag_eval.config import settings
|
||||
|
||||
|
||||
class DialogflowAgent:
|
||||
"""A class to interact with a Dialogflow CX agent."""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initializes the DialogflowAgent.
|
||||
"""
|
||||
self.agent_path = (
|
||||
f"projects/{settings.project_id}/locations/{settings.location}"
|
||||
f"/agents/{settings.dialogflow_agent_id}"
|
||||
)
|
||||
|
||||
api_endpoint = f"{settings.location}-dialogflow.googleapis.com"
|
||||
client_opts = client_options.ClientOptions(api_endpoint=api_endpoint)
|
||||
|
||||
self.sessions_client = dialogflow.SessionsClient(client_options=client_opts)
|
||||
self.session_id = str(uuid.uuid4())
|
||||
|
||||
|
||||
def call(self, query: str, flow_id: str | None = None, session_id: str | None = None) -> dict:
|
||||
"""
|
||||
Sends a message to the Dialogflow CX agent and gets the response.
|
||||
|
||||
Args:
|
||||
query: The message to send to the agent.
|
||||
flow_id: The specific flow to target within the agent.
|
||||
session_id: The session ID to use for the conversation. If not provided, the instance's default session ID is used.
|
||||
|
||||
Returns:
|
||||
A dictionary containing the agent's response and other details.
|
||||
"""
|
||||
current_session_id = session_id or self.session_id
|
||||
session_path = f"{self.agent_path}/sessions/{current_session_id}"
|
||||
|
||||
text_input = dialogflow.TextInput(text=query)
|
||||
query_input = dialogflow.QueryInput(text=text_input, language_code="ES")
|
||||
|
||||
request = dialogflow.DetectIntentRequest(
|
||||
session=session_path,
|
||||
query_input=query_input,
|
||||
)
|
||||
|
||||
if flow_id:
|
||||
flow_path = f"{self.agent_path}/flows/{flow_id}"
|
||||
request.query_params = dialogflow.QueryParameters(flow=flow_path)
|
||||
|
||||
response = self.sessions_client.detect_intent(request=request)
|
||||
query_result = response.query_result
|
||||
|
||||
response_messages = [
|
||||
" ".join(msg.text.text) for msg in query_result.response_messages if msg.text
|
||||
]
|
||||
response_text = " ".join(response_messages)
|
||||
|
||||
match_type = query_result.match.match_type
|
||||
|
||||
details = {
|
||||
"response_text": response_text,
|
||||
"match_type": match_type.name,
|
||||
"details": "N/A"
|
||||
}
|
||||
|
||||
if match_type == dialogflow.Match.MatchType.PLAYBOOK:
|
||||
playbook = query_result.generative_info.current_playbooks[0].split('/')[-1] if query_result.generative_info.current_playbooks else "N/A"
|
||||
details["details"] = f"Playbook: {playbook}"
|
||||
elif match_type == dialogflow.Match.MatchType.INTENT:
|
||||
flow = query_result.current_flow.display_name if query_result.current_flow else "N/A"
|
||||
page = query_result.current_page.display_name if query_result.current_page else "N/A"
|
||||
intent = query_result.intent.display_name if query_result.intent else "N/A"
|
||||
details["details"] = f"Flow: {flow} | Page: {page} | Intent: {intent}"
|
||||
|
||||
return details
|
||||
0
packages/dialogflow/src/dialogflow/py.typed
Normal file
0
packages/dialogflow/src/dialogflow/py.typed
Normal file
Reference in New Issue
Block a user