File size: 6,086 Bytes
e10c43b 30bba8b 409ca76 00f8210 71d3b6e 24cd56e 409ca76 71d3b6e 24cd56e 71d3b6e 409ca76 e10c43b 71d3b6e 25a8d18 49e38f0 409ca76 24cd56e 30bba8b 24cd56e 8b9c5c2 71d3b6e 8b9c5c2 24cd56e 8b9c5c2 71d3b6e 369d687 8b9c5c2 24cd56e 8b9c5c2 71d3b6e 369d687 8b9c5c2 24cd56e 890ebcd e10c43b 24cd56e 8b9c5c2 24cd56e 71d3b6e 409ca76 24cd56e 71d3b6e 24cd56e 71d3b6e 24cd56e 605747a 24cd56e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | 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))
|