Send a proactive message to a first-party platform user.
(agent_id: uuid.UUID, args: dict)
| 6501 | logger.exception("[WeChat] Error") |
| 6502 | return f"❌ WeChat message error: {str(e)[:200]}" |
| 6503 | async def _send_platform_message(agent_id: uuid.UUID, args: dict) -> str: |
| 6504 | """Send a proactive message to a first-party platform user.""" |
| 6505 | username = args.get("username", "").strip() |
| 6506 | message_text = args.get("message", "").strip() |
| 6507 | |
| 6508 | if not username or not message_text: |
| 6509 | return "❌ Please provide recipient username and message content" |
| 6510 | |
| 6511 | try: |
| 6512 | from datetime import datetime as _dt, timezone as _tz |
| 6513 | |
| 6514 | |
| 6515 | async with async_session() as db: |
| 6516 | # 0. Get agent's tenant_id for scoping |
| 6517 | agent_res = await db.execute(select(AgentModel).where(AgentModel.id == agent_id)) |
| 6518 | agent = agent_res.scalar_one_or_none() |
| 6519 | if not agent: |
| 6520 | return "❌ Agent not found" |
| 6521 | if await ensure_access_granted_platform_relationships(db, agent, created_by_user_id=agent.creator_id): |
| 6522 | await db.flush() |
| 6523 | |
| 6524 | # 1. Look up target user by username or display_name within tenant |
| 6525 | |
| 6526 | query = select(UserModel).where( |
| 6527 | or_( |
| 6528 | UserModel.username == username, |
| 6529 | UserModel.display_name == username, |
| 6530 | ) |
| 6531 | ) |
| 6532 | if agent.tenant_id: |
| 6533 | query = query.where(UserModel.tenant_id == agent.tenant_id) |
| 6534 | |
| 6535 | u_result = await db.execute(query) |
| 6536 | target_user = u_result.scalar_one_or_none() |
| 6537 | if not target_user: |
| 6538 | # List available users for the agent to pick from (within the same tenant) |
| 6539 | list_query = select(UserModel.username, UserModel.display_name).limit(20) |
| 6540 | if agent.tenant_id: |
| 6541 | list_query = list_query.where(UserModel.tenant_id == agent.tenant_id) |
| 6542 | |
| 6543 | all_r = await db.execute(list_query) |
| 6544 | names = [f"{r.display_name or r.username}" for r in all_r.all()] |
| 6545 | return f"❌ No user named '{username}' found in your organization. Available users: {', '.join(names) if names else 'none'}" |
| 6546 | |
| 6547 | rel_result = await db.execute( |
| 6548 | select(AgentRelationship) |
| 6549 | .join(OrgMember, AgentRelationship.member_id == OrgMember.id) |
| 6550 | .where( |
| 6551 | AgentRelationship.agent_id == agent_id, |
| 6552 | OrgMember.user_id == target_user.id, |
| 6553 | OrgMember.status == "active", |
| 6554 | ) |
| 6555 | .options(selectinload(AgentRelationship.member)) |
| 6556 | ) |
| 6557 | rel = rel_result.scalars().first() |
| 6558 | if not rel: |
| 6559 | return f"❌ {target_user.display_name or target_user.username} is not in your active relationship network" |
| 6560 | status_info = await evaluate_human_relationship_status(db, rel, source_agent=agent) |
no test coverage detected