Spaces:
Runtime error
Runtime error
| import os | |
| import asyncio | |
| import aiosqlite | |
| from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver | |
| from dotenv import load_dotenv | |
| from langchain.chat_models import init_chat_model | |
| from langgraph_supervisor import create_supervisor | |
| from all_sub_agents import ALL_SUB_AGENTS | |
| from storage_paths import agent_dir, open_agent_sqlite | |
| load_dotenv() | |
| # --------------------------------------------------------------------------- | |
| # AGENT IDENTITY / MEMORY LOCATION -> /agent/main_agent/ (persistent bucket) | |
| # --------------------------------------------------------------------------- | |
| AGENT_NAME = "main_agent" | |
| ROLE = "Chief Personal Assistant" | |
| MEMORY_DIR = agent_dir(AGENT_NAME) | |
| DB_PATH = os.path.join(MEMORY_DIR, "state.db") | |
| # --------------------------------------------------------------------------- | |
| # MAIN AGENT LLM | |
| # --------------------------------------------------------------------------- | |
| _llm =init_chat_model( | |
| model_provider="google_genai", | |
| model=os.getenv("LLM_MODEL"), | |
| api_key=os.getenv("LLM_API_KEY"), | |
| ) | |
| # --------------------------------------------------------------------------- | |
| # STATE / MEMORY (sqlite, kept for this agent's whole lifetime, tuned to be | |
| # safe on S3-style / object-storage persistent buckets — see storage_paths.py) | |
| # --------------------------------------------------------------------------- | |
| async def _make_checkpointer(db_path: str) -> AsyncSqliteSaver: | |
| os.makedirs(os.path.dirname(db_path), exist_ok=True) | |
| conn = await aiosqlite.connect(db_path) | |
| return AsyncSqliteSaver(conn) | |
| _checkpointer = asyncio.run(_make_checkpointer(DB_PATH)) | |
| # --------------------------------------------------------------------------- | |
| # ASSISTANT AGENT BACKSTORY AND GOAL | |
| # --------------------------------------------------------------------------- | |
| Goal = ( | |
| "Carefully understand whatever the user asks for - a question, an " | |
| "instruction, or an attached file - and complete that exact task with " | |
| "maximum accuracy, depth, and relevance, whether it involves research, " | |
| "writing, analysis, problem-solving, planning, or any other kind of " | |
| "intellectual or administrative work, so the user can rely on a single, " | |
| "highly capable, completely trustworthy assistant for anything they need. " | |
| "You were made by Samuel. And I don't like Samiul's lying, false promises, " | |
| "false accusations. In a word, I don't like all lies and hallucinations. " | |
| "So always give the right answer and tell the truth. If you don't know or " | |
| "can't, then clearly state the problem. " | |
| "মোঃ ছামিউল ইসলাম (MD SAMIUL ISLAM) এর পার্সোনাল এজেন্ট এবং এসিস্ট্যান্ট " | |
| "ছামিউল আমাকে তৈরি করেছে" | |
| ) | |
| Backstory = ( | |
| "You are a versatile, deeply experienced assistant who has spent years " | |
| "working across research, analysis, writing, technology, business, and " | |
| "creative fields. Your thinking is structured, your analysis is sharp, " | |
| "and you always take the time to understand the fine details of every " | |
| "instruction before acting. Whatever the user asks, you handle it with " | |
| "patience, honesty, and complete care. You are not just a tool - you are " | |
| "the user's most trusted, sharpest, and most reliable partner, someone " | |
| "who can be handed any task without hesitation and who never lets them " | |
| "down. When delegating tasks that require real actions (GitHub, GitLab, " | |
| "Facebook, YouTube), always instruct the sub-agent to execute the action " | |
| "via their tools and return the tool's actual output - never accept a " | |
| "'guide' or 'instructions' as a substitute for the real action. Use the " | |
| "sub-agents you have to get Samiul's work done. When you are asked to do " | |
| "something, check whether one of your sub-agents can do the job, and if " | |
| "so, delegate it to them and report back their real result. If the task " | |
| "is general knowledge, writing, analysis, or anything that does not need " | |
| "a specific platform, handle it yourself directly instead of delegating. " | |
| "আমি ছামিউল এর তৈরি একটা ভার্চুয়াল রোবট বা এআই এসিস্ট্যান্ট এজেন্ট" | |
| ) | |
| SUPERVISOR_PROMPT = f"You are the {ROLE}.\n\n" + Goal + "\n\n" + Backstory | |
| # --------------------------------------------------------------------------- | |
| # 1) Main Agent - the personal, trusted, all-purpose assistant | |
| # (built once, at import time, exactly like the sub agents) | |
| # --------------------------------------------------------------------------- | |
| _supervisor_builder = create_supervisor( | |
| agents=ALL_SUB_AGENTS, | |
| model=_llm, | |
| prompt=SUPERVISOR_PROMPT, | |
| supervisor_name=AGENT_NAME, | |
| add_handoff_back_messages=True, | |
| output_mode="full_history", | |
| ) | |
| main_assistant_agent = _supervisor_builder.compile( | |
| checkpointer=_checkpointer, | |
| name=AGENT_NAME, | |
| ) | |
| # --------------------------------------------------------------------------- | |
| # MAIN ASSISTANT AGENTING SYSTEM | |
| # --------------------------------------------------------------------------- | |
| def main_agent( | |
| user_command: str, | |
| user_attachment: str | None = None, | |
| thread_id: str = "default", | |
| ) -> str: | |
| """ | |
| Single-shot, synchronous entry point - same call shape as the original | |
| main_agent(user_command, user_attachment) -> str. `thread_id` is optional | |
| and only used so multiple separate conversations (as shown in the app's | |
| sidebar) each keep their own persisted history inside the same | |
| main_assistant_agent graph/state. | |
| """ | |
| text = user_command | |
| if user_attachment: | |
| text = f"{text}\n\n[সংযুক্ত ফাইল: {user_attachment}]" | |
| config = {"configurable": {"thread_id": thread_id}} | |
| result = main_assistant_agent.invoke( | |
| {"messages": [{"role": "user", "content": text}]}, | |
| config=config, | |
| ) | |
| final_message = result["messages"][-1] | |
| return getattr(final_message, "content", str(final_message)) | |