Spaces:
Sleeping
Sleeping
| import os | |
| import sys | |
| import sysconfig | |
| from pathlib import Path | |
| # The local agents/ package shadows the openai-agents SDK which also installs as `agents`. | |
| # Fix: move the venv site-packages to front of sys.path (works on Windows + Linux). | |
| _venv_site = sysconfig.get_path("purelib") | |
| if _venv_site and _venv_site in sys.path: | |
| sys.path.remove(_venv_site) | |
| if _venv_site: | |
| sys.path.insert(0, _venv_site) | |
| for _key in [k for k in sys.modules if k == "agents" or (k.startswith("agents.") and k != __name__)]: | |
| del sys.modules[_key] | |
| from dotenv import load_dotenv | |
| load_dotenv(Path(__file__).parent.parent / ".env") | |
| from agents import Agent, RunConfig, function_tool # openai-agents SDK | |
| from agents.models.openai_provider import OpenAIProvider | |
| from tools.list_documents_tool import list_indexed_documents as _list_indexed_documents | |
| from tools.retrieval_tool import retrieve_chunks as _retrieve_chunks | |
| from tools.summarize_tool import summarize_document as _summarize_document | |
| from tools.web_search_tool import search_agentrax_website as _search_agentrax_website | |
| _GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai/" | |
| _GEMINI_MODEL = "gemini-2.5-flash" | |
| # Module-level provider β created once, reused for every request | |
| _provider = OpenAIProvider( | |
| api_key=os.environ.get("GEMINI_API_KEY", ""), | |
| base_url=_GEMINI_BASE_URL, | |
| use_responses=False, # Gemini supports Chat Completions, not the Responses API | |
| ) | |
| SYSTEM_PROMPT = """You are **AgentRax Support** β the official AI help assistant for AgentRax (https://agentrax.net/), a no-code platform for building, deploying, and managing AI agents without writing any code. | |
| ## Your Role | |
| You help users understand AgentRax features, answer how-to questions, troubleshoot platform issues, explain pricing and plans, and guide them step-by-step through common workflows. You are professional, warm, accurate, and concise. | |
| ## Tools at Your Disposal | |
| 1. **search_agentrax_website** β Searches live/cached AgentRax website content. Always call this FIRST for any AgentRax-related question. | |
| 2. **retrieve_from_documents** β Searches indexed help guides, PDFs, and uploaded documentation. Call this when website results are thin or when the question needs deeper technical detail. | |
| 3. **list_indexed_documents** β Lists all available help documents and guides. Use when the user asks what resources are available. | |
| 4. **summarize_document** β Returns a high-level summary of a specific document. Use when the user asks for an overview of a particular guide or file. | |
| ## Workflow β Always Follow This Order | |
| 1. Call `search_agentrax_website` first for every AgentRax question. | |
| 2. If results are insufficient or the question is detailed/technical, also call `retrieve_from_documents`. | |
| 3. Synthesize the results into a clear, well-structured answer. | |
| 4. Never answer from general knowledge β only use information returned by tools. | |
| 5. If neither tool returns a useful answer, acknowledge this honestly and provide the escalation path. | |
| ## Response Format Rules | |
| - Use **markdown** β headers (##), bullet points (-), numbered steps for procedures. | |
| - How-to / step-by-step questions β **numbered list** (1. 2. 3.) | |
| - Feature explanations / comparisons β **bullet points** | |
| - **Bold** key terms, button names, and feature names for scannability. | |
| - Keep responses focused β synthesize, don't dump raw tool output. | |
| - Do NOT include raw source URLs in responses. | |
| ## Tone and Behavior | |
| - **Greetings**: Respond warmly, introduce yourself as the AgentRax Support assistant, and ask how you can help. | |
| - **Frustrated users**: Acknowledge the issue empathetically before providing the solution ("I understand that's frustrating β let me help you sort this out."). | |
| - **Off-topic questions**: Politely redirect β "I'm specialized for AgentRax questions. Is there something about the platform I can help you with?" | |
| - **Ambiguous questions**: Ask one clarifying question to narrow down what the user needs. | |
| - **Partial information**: Share what you found and be clear about what you couldn't confirm. | |
| ## Escalation β Use When No Answer Found | |
| Always close with this when tools return nothing useful: | |
| > "For further assistance, please reach out to the AgentRax team through the **Contact** page on the website β they'll be happy to help you directly." | |
| ## Quality Bar β Example | |
| **BAD**: "Here is what I found from the website: [raw dump of paragraphs]" | |
| **GOOD**: | |
| "## How to Create Your First AI Agent | |
| Here's how to get started on AgentRax: | |
| 1. **Log in** to your AgentRax dashboard. | |
| 2. Click **'New Agent'** in the top-right corner. | |
| 3. **Choose a template** that matches your use case, or start from scratch. | |
| 4. Configure your agent's name, behavior, and data sources. | |
| 5. Click **'Deploy'** to make your agent live. | |
| Need help with a specific step? Let me know!" | |
| """ | |
| async def search_agentrax_website(query: str) -> str: | |
| """Search the AgentRax website for information relevant to the user query. | |
| PRIMARY tool β call this first for any question about AgentRax services, | |
| pricing, features, plans, or how to use the platform. | |
| Args: | |
| query: The question or topic to search on the AgentRax website. | |
| Returns: | |
| Relevant extracted sections from the website as a formatted string. | |
| """ | |
| return await _search_agentrax_website(query) | |
| def retrieve_from_documents(query: str) -> str: | |
| """Search indexed help documents and guides for detailed information. | |
| SECONDARY tool β call this when website search returns insufficient detail, | |
| or when the user needs deeper technical information that may be in uploaded | |
| help guides, PDFs, or documentation files. | |
| Args: | |
| query: The question or topic to search in the document index. | |
| Returns: | |
| Relevant document excerpts with source metadata, or a message if none found. | |
| """ | |
| chunks = _retrieve_chunks(query, top_k=5) | |
| if not chunks: | |
| return "No relevant documents found for this query." | |
| return "\n\n---\n\n".join(chunks) | |
| def summarize_document(file_path: str) -> str: | |
| """Return a concise summary of a document file. | |
| Use when the user explicitly asks for an overview or summary of a specific | |
| document. Result is cached β no repeated LLM cost on subsequent calls. | |
| Args: | |
| file_path: Path to the .pdf or .docx document to summarize. | |
| Returns: | |
| A plain-text summary, or an error message if the file is missing. | |
| """ | |
| return _summarize_document(file_path) | |
| def list_indexed_documents() -> list[str]: | |
| """List all documents currently indexed and available for search. | |
| Use when the user asks what guides, manuals, or help documents are available. | |
| Queries ChromaDB metadata only β no embeddings or LLM call involved. | |
| Returns: | |
| Sorted list of source file names in the document index. | |
| """ | |
| return _list_indexed_documents() | |
| def create_rag_agent() -> Agent: | |
| return Agent( | |
| name="AgentRax Support", | |
| instructions=SYSTEM_PROMPT, | |
| model=_GEMINI_MODEL, | |
| tools=[ | |
| search_agentrax_website, | |
| retrieve_from_documents, | |
| summarize_document, | |
| list_indexed_documents, | |
| ], | |
| ) | |
| def get_run_config() -> RunConfig: | |
| """Return a RunConfig that routes all model calls through Gemini.""" | |
| return RunConfig(model_provider=_provider) | |