{"id":49362733,"url":"https://github.com/haseeb-heaven/gworkspace-agent","last_synced_at":"2026-05-04T04:04:02.386Z","repository":{"id":350596158,"uuid":"1207409831","full_name":"haseeb-heaven/gworkspace-agent","owner":"haseeb-heaven","description":"Smart Agentic Assistant for your Google Workspace","archived":false,"fork":false,"pushed_at":"2026-04-24T22:06:52.000Z","size":9274,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2026-04-27T17:32:11.647Z","etag":null,"topics":["agents","agents-sdk","claude","gemini","google","google-api","gws","llm","openai"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/haseeb-heaven.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-10T23:03:18.000Z","updated_at":"2026-04-24T22:06:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/haseeb-heaven/gworkspace-agent","commit_stats":null,"previous_names":["haseeb-heaven/gworkspace-agent"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/haseeb-heaven/gworkspace-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haseeb-heaven%2Fgworkspace-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haseeb-heaven%2Fgworkspace-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haseeb-heaven%2Fgworkspace-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haseeb-heaven%2Fgworkspace-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haseeb-heaven","download_url":"https://codeload.github.com/haseeb-heaven/gworkspace-agent/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haseeb-heaven%2Fgworkspace-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32593948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T22:12:39.696Z","status":"online","status_checked_at":"2026-05-04T02:00:06.625Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","agents-sdk","claude","gemini","google","google-api","gws","llm","openai"],"created_at":"2026-04-27T17:06:31.882Z","updated_at":"2026-05-04T04:04:02.380Z","avatar_url":"https://github.com/haseeb-heaven.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🚀 Google Workspace Agent\n\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/release/python-3119/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Framework: LangGraph](https://img.shields.io/badge/Framework-LangGraph-orange.svg)](https://langchain-ai.github.io/langgraph/)\n[![LangChain](https://img.shields.io/badge/LangChain-ReAct-blueviolet.svg)](https://python.langchain.com/)\n[![Safety: Sandbox](https://img.shields.io/badge/Safety-Sandboxed-green.svg)](#safety--security)\n[![Tests](https://img.shields.io/badge/tests-pytest-brightgreen.svg)](https://pytest.org/)\n[![CI/CD](https://github.com/haseeb-heaven/gworkspace-agent/actions/workflows/pipeline.yml/badge.svg)](https://github.com/haseeb-heaven/gworkspace-agent/actions/workflows/pipeline.yml)\u003c/br\u003e\nAn autonomous AI agent for Google Workspace, built on a hybrid **LangChain ReAct + LangGraph DAG** architecture. It converts natural language into verified, multi-step workflows across Gmail, Drive, Sheets, Docs, Calendar, and 15+ other Google services — with built-in safety, memory, and sandboxed code execution.\n\n---\n\n## Table of Contents\n\n- [Key Features](#key-features)\n- [Demos](#demos)\n- [Architecture](#architecture)\n- [LangGraph DAG](#langgraph-dag)\n- [ReAct Loop](#react-loop)\n- [Supported Services](#supported-services)\n- [Getting Started](#getting-started)\n- [Interfaces](#interfaces)\n- [Configuration](#configuration)\n- [Safety \u0026 Security](#safety--security)\n- [Testing](#testing)\n- [Contributing](#contributing)\n\n---\n\n## Version\nLatest: **v1.0.0**  \nSee [CHANGELOG.md](CHANGELOG.md) for full version history.\n\n---\n\n## Key Features\n\n- **5-Step Verification Engine** - Strict, non-bypassable verification system with severity levels (CRITICAL, ERROR, WARNING) that validates parameters, permissions, results, data integrity, and idempotency\n- **Hybrid ReAct + LangGraph Engine** — LLM-driven planner generates a typed DAG of tasks; LangGraph executes nodes with full state persistence and smart retry logic\n- **Multi-Service Orchestration** — a single natural language request can chain Gmail, Drive, Sheets, Docs, Calendar, and Code execution in one plan\n- **Long-Term Memory via Mem0** — agent learns from past interactions and recalls user preferences across sessions\n- **Sandboxed Code Execution** — Python code runs inside a restricted E2B sandbox with stdout/stderr capture and exit code tracking\n- **Safety-by-Default** — Read-Only mode blocks all writes; Sandbox mode requires manual confirmation before any state-changing action\n- **Multi-Interface** — CLI, Desktop GUI, Web (Gradio), and Telegram Bot all share the same agent core\n- **Model Agnostic** — works with any OpenAI-spec tool-calling model (Gemini, GPT-4o, Claude, Mistral, LLaMA) via OpenRouter or direct APIs\n- **Verified Tool-Calling** — `model_registry.py` validates that the configured model supports function calling before any plan is generated\n\n---\n\n---\n\n## 🎬 Demos \u0026 Showcases\n\n### ⚡ Live Previews\nThe following animated showcases demonstrate the agent's autonomous planning and multi-service execution in real-time.\n\n| Autonomous Workflow Demo | Multi-Interface Simulation |\n| :---: | :---: |\n| ![Animated Demo](assets/demo_animated.svg) | ![Simulation](assets/simulation_animated.svg) |\n\n\u003e **Dynamic Multi-Mode Preview:** The simulation on the right is automatically generated and cycles through the CLI, Desktop, and Web interfaces.\n\n### 🖼️ Interface Gallery\nDetailed snapshots of the available user interfaces.\n\n#### 💻 CLI (Typer + Rich)\n![CLI Demo](assets/cli_demo.png)\n\n#### 🖥️ Desktop GUI\n![Desktop GUI Demo](assets/gui_desktop_demo.png)\n\n#### 🌐 Web Interface (Gradio)\n![Web GUI Demo](assets/gui_web_demo.png)\n\n### Architecture Diagram\n![Architecture](assets/architecture_diagram.png)\n\n---\n\n## Architecture\n\nThe agent uses a **three-layer architecture**: an LLM Planner that reasons about intent, a LangGraph Workflow that manages stateful execution, and a GWS Executor that calls real Google APIs.\n\n```mermaid\n---\nid: 381d8783-6e2b-46fa-b5fa-879171ca0dbf\n---\nflowchart TD\n    USER[\"👤 User Request\"] --\u003e AGENT\n\n    subgraph AGENT[\"🤖 Agent System\"]\n        PL[\"🧠 Planner LLM → TaskPlan DAG\"]\n        WF[\"⚙️ LangGraph Workflow generate → execute → reflect\"]\n    end\n\n    AGENT --\u003e EX\n\n    subgraph EX[\"⚡ Execution Engine\"]\n        direction LR\n        RS[\"Resolver\"] --\u003e EXC[\"Executor\"] --\u003e CU[\"Context Updater\"] --\u003e VF[\"Verifier\"]\n    end\n\n    EX --\u003e APIS\n\n    subgraph APIS[\"☁️ Google Workspace APIs\"]\n        direction LR\n        GM[\"Gmail\"] --- DR[\"Drive\"] --- SH[\"Sheets\"] --- DC[\"Docs\"] --- CA[\"Calendar\"]\n    end\n\n    AGENT \u003c--\u003e SUP\n\n    subgraph SUP[\"🛡️ Support\"]\n        direction LR\n        MEM[\"Memory\\nMem0\"] --- SG[\"Safety\\nGuard\"] --- MR[\"Model\\nRegistry\"]\n    end\n\n    style AGENT fill:#1a1a2e,color:#fff,stroke:#4A90D9\n    style EX fill:#0f3460,color:#fff,stroke:#E67E22\n    style APIS fill:#16213e,color:#fff,stroke:#2ECC71\n    style SUP fill:#1a1a2e,color:#fff,stroke:#8E44AD\n```\n---\n\n## LangGraph DAG\n\nThe agent's execution graph is a **stateful directed acyclic graph** with four core nodes and conditional edges. Each node operates on a shared `AgentState` object that persists across the entire request lifecycle.\n\n```mermaid\nflowchart TD\n    START([\"▶ START\"]) --\u003e GP\n\n    GP[\"🧠 generate_plan\\nLLM generates TaskPlan\\nwith typed task list\\nand service/action pairs\"]\n\n    GP --\u003e ET\n\n    ET[\"⚡ execute_task\\n① Resolver expands $placeholders\\n② Executor calls GWS API\\n③ ContextUpdater writes outputs\\n④ Verifier checks integrity\"]\n\n    ET --\u003e RN\n\n    RN{\"🔍 reflect_node\\nAll tasks done?\\nAny errors?\"}\n\n    RN --\u003e|\"more tasks remaining\"| ET\n    RN --\u003e|\"transient error → retry\"| GP\n    RN --\u003e|\"AUTH / NOT_FOUND → skip\"| FO\n    RN --\u003e|\"all tasks complete\"| FO\n\n    FO[\"📋 format_output\\nApply output_formatter\\nBuild final response string\"]\n\n    FO --\u003e END([\"⏹ END\"])\n\n    style GP fill:#4A90D9,color:#fff,stroke:#2c6fad\n    style ET fill:#27AE60,color:#fff,stroke:#1a7a43\n    style RN fill:#E67E22,color:#fff,stroke:#b85e0a\n    style FO fill:#8E44AD,color:#fff,stroke:#6b2f87\n    style START fill:#2ECC71,color:#fff,stroke:#27ae60\n    style END fill:#E74C3C,color:#fff,stroke:#c0392b\n\n```\n\n---\n\n### AgentState Schema\n\npython\nclass AgentState(TypedDict):\n    user_request:   str            # original natural language query\n    task_plan:      list[Task]     # planned task list generated by LLM\n    context:        dict           # shared execution context (placeholders live here)\n    task_results:   dict           # keyed outputs per task ID e.g. task-1, task-2\n    current_index:  int            # execution cursor pointing to current task\n    error:          str | None     # last error string for reflect_node classification\n    retry_count:    int            # retry counter — capped per task to prevent loops\n    final_output:   str            # formatted final response string\n\n\n---\n\n## ReAct Loop\n\nEach task execution follows the **ReAct (Reason → Act → Observe)** pattern:\n\n```mermaid\nflowchart LR\n    R[\"REASON\u003cbr\u003ePlanner reads user intent\u003cbr\u003e+ service catalog 100+ actions\u003cbr\u003e+ Mem0 conversation memory\u003cbr\u003e→ generates typed TaskPlan JSON\"]\n    A[\"ACT\u003cbr\u003eFor each Task in plan:\u003cbr\u003e① Resolver expands $placeholders\u003cbr\u003e② Task validated vs model registry\u003cbr\u003e③ GWS API called via executor\u003cbr\u003e④ Result written to shared context\"]\n    O[\"OBSERVE\u003cbr\u003eVerifier checks output integrity\u003cbr\u003eReflect node classifies errors\u003cbr\u003eAUTH/NOT_FOUND → skip\u003cbr\u003eSERVER/UNKNOWN → retry\u003cbr\u003eMemory updated with outcome\"]\n\n    R --\u003e A --\u003e O --\u003e R\n```\n\n---\n\n## Supported Services\n\nThe agent orchestrates **20+ Google services** and **100+ actions** via `service_catalog.py`:\n\n| Service | Key Actions |\n|---|---|\n| 📧 **Gmail** | send, read, search, reply, forward, label, delete messages |\n| 📂 **Drive** | list, upload, download, export, move, delete, share files and folders |\n| 📊 **Sheets** | create, read, append, update, format spreadsheets |\n| 📝 **Docs** | create, read, batch-update documents |\n| 📅 **Calendar** | create, list, update, delete events with reminders |\n| 📽️ **Slides** | create and read presentations |\n| 👥 **Contacts** | list, search, create contacts |\n| 💬 **Chat** | send messages to Google Chat spaces |\n| 🐍 **Code** | execute Python in E2B sandbox, capture stdout/stderr/exit code |\n| 🔍 **Web Search** | search and summarize web results |\n| 🧠 **Memory** | store and retrieve user preferences via Mem0 |\n| 🛡️ **Admin SDK** | manage users, groups, org units |\n| 📜 **Apps Script** | run Google Apps Scripts |\n| 🔐 **Model Armor** | content safety screening |\n| 📋 **Tasks** | manage Google Tasks lists |\n| 🗒️ **Keep** | create and read Google Keep notes |\n| 📝 **Forms** | create and read Google Forms |\n| 👥 **Meet** | create Meet links |\n| 🏫 **Classroom** | manage courses and assignments |\n\n---\n\n## Getting Started\n\nTo get the agent running on your local machine, please follow the comprehensive **[Setup Guide (SETUP.md)](SETUP.md)**.\n\n### Quick Start\n1. **Clone \u0026 Install:**\n   ```bash\n   git clone https://github.com/haseeb-heaven/gworkspace-agent.git\n   cd gworkspace-agent\n   pip install -e .\n   ```\n2. **Configure Credentials:** Follow the [Google Cloud Setup](SETUP.md#%EF%B8%8F-step-3-google-cloud--credentials-setup) instructions.\n3. **Run the Agent:**\n   ```bash\n   python gws_cli.py --task \"List my drive files\"\n   ```\n\n---\n\n## Interfaces\n\n| Interface | Command | Description |\n|---|---|---|\n| **💻 CLI** | `python gws_cli.py` | Rich terminal UI with streaming output, tables, and interactive prompts |\n| **🖥️ Desktop GUI** | `python gws_gui.py` | Native app with visual task logs and manual controls |\n| **🌐 Web UI** | `python gws_gui_web.py` | Gradio chat interface accessible from any browser |\n| **🤖 Telegram Bot** | `python gws_telegram.py` | Secure mobile access via whitelisted Telegram Bot API |\n\n---\n\n## Configuration\n\nAll system configuration (API keys, security modes, and service endpoints) is managed via the `.env` file. \n\n\u003e [!IMPORTANT]\n\u003e Detailed configuration steps and a full environment variable reference can be found in the **[Configuration Section of SETUP.md](SETUP.md#%EF%B8%8F-step-5-agent-configuration)**.\n\n---\n\n## Safety \u0026 Security\n\n```mermaid\nflowchart TD\n    REQ[\"Incoming Task\"] --\u003e RO{\"Read-Only Mode\\nON by default\"}\n    RO --\u003e|\"write / delete / send action\"| BLOCK[\"🚫 Blocked\\nAction rejected immediately\"]\n    RO --\u003e|\"read-only action\"| SB{\"Sandbox Mode\\nON by default\"}\n    SB --\u003e|\"state-changing action\"| CONF{\"User Confirmation\\nY / N prompt\"}\n    CONF --\u003e|\"N\"| SKIP[\"⏭ Skipped\"]\n    CONF --\u003e|\"Y\"| EXEC[\"✅ Execute\"]\n    SB --\u003e|\"safe read action\"| EXEC\n    RO --\u003e|\"--read-write flag set\"| SB\n\n    style BLOCK fill:#E74C3C,color:#fff\n    style SKIP fill:#E67E22,color:#fff\n    style EXEC fill:#27AE60,color:#fff\n```\n\n- **Read-Only Mode** — default ON. Enable writes with `--read-write` or `READ_ONLY_MODE=false`\n- **Sandbox Mode** — default ON. Disable with `--no-sandbox` or `SANDBOX_ENABLED=false`\n- **Email Recipient Lock** — `DEFAULT_RECIPIENT_EMAIL` forces all outbound emails to one address regardless of what the LLM generates\n- **Model Registry** — raises `ValueError` at startup if the configured model is not on the tool-calling allowlist in `model_registry.py`\n\n---\n\n## Testing\n\n```bash\n# Full test suite\npython -m pytest\n```\n\n```bash\n# Drive metadata and placeholder contract tests only\npython -m pytest -m \"drive\" -v\n```\n\n```bash\n# With coverage report\npython -m pytest --cov=gws_assistant --cov-report=term-missing\n```\n\n```bash\n# Integration tests (requires live Google credentials)\npython -m pytest -m \"not skip_integration\" -v\n```\n\n| Test File | Coverage |\n|---|---|\n| `tests/test_placeholder_contracts.py` | Canonical and legacy placeholder resolution |\n| `tests/test_drive_metadata.py` | Drive file summarizer helper |\n| `tests/test_resolver.py` | Full resolver logic including LEGACY_MAP |\n\n---\n\n## Releases\nSee the [CHANGELOG.md](CHANGELOG.md) for details on all versions.\n\n---\n\n## Contributing\n\n1. Fork the repository\n2. Branch from `develop`: `git checkout -b feature/your-feature develop`\n3. Make changes with tests\n4. Ensure all tests pass: `python -m pytest`\n5. Open a Pull Request targeting **`develop`** — never target `master` directly\n\n---\n\n## License\n\nDistributed under the **MIT License**. See [`LICENSE`](LICENSE) for details.\n\n---\n\n\u003e **Note:** This project was **architected and designed** by **Haseeb Mir**.\n\u003e AI tools (GitHub Copilot, Jules) were used to assist with **implementation**,\n\u003e **boilerplate generation**, and **refactoring** — all **features**, **architecture**\n\u003e **decisions**, and **system design** are **original**.\n\n\u003cp align=\"center\"\u003e\n  Built with ❤️ by \u003ca href=\"https://github.com/haseeb-heaven\"\u003eHaseeb Mir\u003c/a\u003e\n\u003c/p\u003e\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaseeb-heaven%2Fgworkspace-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhaseeb-heaven%2Fgworkspace-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaseeb-heaven%2Fgworkspace-agent/lists"}