Skip to content

kemalcalak/PPTX-Agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PPTX Agent

A terminal assistant that manages Google Slides and PowerPoint (.pptx) files on Google Drive through a Turkish- or English-speaking chat. It is built on the Agno framework, powered by OpenAI gpt-4o-mini, and talks to Google's official Slides/Drive APIs. It can read and edit both native Google Slides presentations and .pptx files — on Drive and on the local disk.


Key Features

  • Google Drive integration: file search, listing, opening.
  • Reads and edits native Google Slides files directly through the Slides API (GoogleSlidesTools).
  • Edits PowerPoint (.pptx) files while preserving the format. .pptx files on Drive are never converted to Google Slides; they are downloaded, edited locally with python-pptx, and uploaded back to the same Drive ID. The file stays .pptx; sharing settings and links are preserved.
  • Bulk operations across a Drive folder (bulk_find_replace_in_folder, with recursive support).
  • Opt-in local folder mode: the agent cannot touch any file on the local disk unless the user explicitly opens a folder. Once open_local_folder is called, the agent can list, read and edit .pptx files inside that folder. The project ships with a suggested presentations/ drop folder; open_local_folder() with no argument opens it. Any other path can be passed explicitly.
  • Bulk operations across the active local folder (bulk_find_replace_in_local_folder, search_in_all_local_files).
  • Slide tools: list/read slides, inspect shapes and layouts, add/delete/ move slides, set titles, update shape text, add text boxes, tables and images, bulk find-and-replace.
  • Multilingual UI: a TR / EN picker at startup; all strings are pulled from a single i18n module so adding a new language is a one-file change.
  • Persistent chat memory: conversation history and long-term user memories are stored in a local SQLite database. The agent remembers previous turns and durable facts (preferred language, frequently mentioned files/folders, workflow habits) across terminal restarts. A small local model running on Ollama (qwen2.5:3b-instruct by default) performs memory extraction in the background — no extra API cost, no presentation/Drive context leaves the machine. The main agent talks to OpenAI gpt-4o-mini for the tool-using work.
  • Rolling sessions with manual rotation: one active session is kept by default; type :new in the terminal to start a fresh session. Old sessions stay in the DB and can be surfaced via session search.
  • Path-traversal protection: in local folder mode the agent cannot escape the opened folder.
  • Secrets stay out of git: .env, credentials.json, token.json and the local DB (agent_data/) are excluded via .gitignore.

File Layout

PPTX Agent/
├── main.py                # Terminal chat entry point
├── pyproject.toml         # uv project definition and dependencies
├── uv.lock                # uv lockfile
├── .env.example           # Environment variable template
├── .gitignore
├── README.md
├── LICENSE
├── credentials.json       # (you provide — Google OAuth client)
├── token.json             # (auto-generated after the first auth)
├── presentations/         # suggested drop folder for local .pptx files
├── pptx_workdir/          # (runtime) downloaded Drive .pptx files
├── agent_data/            # (runtime) SQLite DB + active session id
└── src/
    ├── __init__.py
    ├── agent.py           # Agno agent setup + OpenAI gpt-4o-mini
    ├── google_auth.py     # Shared Google OAuth loader + scopes
    ├── pptx_tools.py      # Drive .pptx tools + folder tools
    ├── local_tools.py     # Local folder tools (opt-in)
    ├── memory.py          # SQLite DB + session/user memory wiring
    └── i18n.py            # All TR/EN strings in one place

Architecture and Toolkits

The agent operates with four toolkits. It picks the correct one for each task by itself.

1) GoogleDriveTools (official Agno)

Finds and lists files on Drive.

  • list_files — returns recent files.
  • search_files — Drive query-syntax search.
  • read_file — text-based content read.

2) GoogleSlidesTools (official Agno)

For native Google Slides files.

  • create_presentation, get_presentation, list_presentations, get_presentation_metadata.
  • get_page, get_slide_text, read_all_text, get_slide_thumbnail.
  • add_slide, add_text_box, add_table, set_background_image, duplicate_slide, move_slides.
  • insert_youtube_video, insert_drive_video.
  • delete_slide — removes a single slide.
  • batch_update_presentation — raw Slides API batch requests.

delete_presentation is intentionally disabled — deleting a whole presentation goes through Drive Trash instead.

3) PptxTools (custom — src/pptx_tools.py)

For .pptx files on Drive and Drive folders. Every tool name contains pptx so it never collides with the GoogleSlidesTools names.

Drive transfer:

  • download_pptx(file_id) — downloads the .pptx into pptx_workdir/.
  • upload_pptx(file_id) — uploads back to the same Drive ID; format is preserved.

Read / inspect (on the downloaded file):

  • list_pptx_slides, read_pptx_slide, read_all_pptx_text
  • list_pptx_shapes, list_pptx_slide_layouts
  • describe_pptx — slide count, per-slide shape breakdown.
  • find_text_pptx — locate slides/shapes matching a pattern.

Slide editing:

  • add_pptx_slide — new slide from a template layout, with optional title/body.
  • delete_pptx_slide, move_pptx_slide.

Shape / content editing:

  • set_pptx_slide_title, update_pptx_shape_text
  • add_pptx_text_box, add_pptx_table, add_pptx_image (positions in inches)
  • find_and_replace_pptx — bulk text replace across slides.

Drive-wide file management:

  • move_drive_file_to_trash(file_id) — recoverable from Drive Trash.
  • rename_drive_file, copy_drive_file.

Creation:

  • create_drive_pptx_file(name, target_folder_id) — uploads a brand-new empty .pptx to Drive and caches it locally for immediate editing.

Folder level (Drive):

  • find_folder_by_name(name)
  • list_pptx_in_folder(folder_id, include_slides, recursive, max_results)
  • bulk_find_replace_in_folder(folder_id, find, replace, ..., recursive) — runs the download → find/replace → upload loop on behalf of the agent. Files with zero replacements are not re-uploaded.

There is no slide-duplication tool for .pptx: python-pptx has no reliable primitive for it. For slide duplication, use a native Google Slides file (duplicate_slide in GoogleSlidesTools).

4) LocalPptxTools (custom — src/local_tools.py)

For .pptx files on the local disk. Stateful: no tool runs until a folder is opened.

Workspace lifecycle:

  • open_local_folder(path) — activates the folder and returns the initial listing. Empty path opens the default presentations/ folder.
  • close_local_folder(), show_local_folder().

File system:

  • list_local_folder(subpath, recursive) — the ls. With recursive=True it walks subdirectories and returns relative paths.

Presentation inspection and editing — local counterparts of the PptxTools operations:

  • list_local_slides, read_local_slide, read_all_local_text, list_local_shapes, list_local_slide_layouts, describe_local_pptx, find_text_local_pptx.
  • create_local_pptx_file — creates a new empty .pptx.
  • add_local_slide, delete_local_slide, move_local_slide.
  • set_local_slide_title, update_local_shape_text, add_local_text_box, add_local_table, add_local_image, find_and_replace_local_pptx.

Folder-wide:

  • bulk_find_replace_in_local_folder(find, replace, ..., recursive)
  • search_in_all_local_files(pattern, ..., recursive) — search only.

File management:

  • move_local_pptx_file_to_trash — moves the file to the OS Recycle Bin.
  • rename_local_pptx_file, copy_local_pptx_file, move_local_pptx_file.

Local files are saved in place — there is no download/upload step.


Setup

1. Google OAuth credentials

The agent reads only credentials.json for Google auth (no env vars).

  1. In the Google Cloud Console, create an OAuth client of type Desktop app.
  2. Enable the Google Slides API and the Google Drive API for the project.
  3. Download the client secret file, rename it to credentials.json, and place it in the project root.
  4. On the first run a browser window opens for consent; token.json is written and reused on subsequent runs. Both files are gitignored.

2. OpenAI API key

Copy .env.example to .env and set OPENAI_API_KEY.

3. Ollama (for persistent memory)

Memory extraction runs on a local Ollama model.

ollama pull qwen2.5:3b-instruct

Make sure the Ollama daemon is running before starting the agent.

4. Dependencies

uv sync

Usage

uv run python main.py

At startup, pick a language (tr / en). Then just type what you want in natural language. Examples:

  • "which presentations do I have?"
  • "open deck.pptx and list its slides"
  • "add a title slide: '2024 Results'"
  • "in the .pptx, replace 'old title' with 'new title'"
  • "open the local folder and show the slides in report.pptx"

Terminal commands:

  • :new — start a fresh session (the old one stays in the DB).
  • exit / quit / çık — leave.

Adding a Language

All user-facing text lives in src/i18n.py. To add a language, add a new entry to the LOCALES dict with the same keys as tr / en (name, banner, instructions, ready, user, bye, err_init, err_run, new_session, exit_words). The language picker lists the new code automatically.


Security Notes

  • .env, credentials.json and token.json are in .gitignore — they never enter version control.
  • In local folder mode the agent cannot do path traversal. Attempts to escape via ../ or absolute paths are rejected.
  • local_* tools refuse to run until a folder is opened; the default posture is safe-by-default.
  • When uploading a .pptx back to Drive the same file ID is reused; links and sharing stay intact.
  • PowerPoint lock files (~$filename.pptx) are skipped automatically during bulk operations.
  • There is no permanent-delete tool. Drive files go to Drive Trash; local files go to the OS Recycle Bin.

Developer Notes

Runtime

All commands run through uv:

uv run python main.py                                  # Start the agent
uv run python -c "import src.agent"                    # Quick import check

Dependencies

Managed in pyproject.toml:

  • agno — agent framework (also provides GoogleDriveTools / GoogleSlidesTools).
  • openai — OpenAI Python SDK (main agent).
  • google-api-python-client — Slides + Drive REST API.
  • google-auth-httplib2, google-auth-oauthlib — OAuth.
  • python-dotenv.env support.
  • python-pptx.pptx read/write.
  • send2trash — recoverable local file deletion.
  • sqlalchemy — required by agno's SQLite backend (sessions + memories).
  • ollama — Python client for the local memory-extraction model.

Configuration points

  • Main model: OpenAIChat(id=...) in src/agent.py.
  • Memory model: MEMORY_MODEL_ID in src/memory.py (defaults to qwen2.5:3b-instruct on Ollama). To use a different model, pull it first (ollama pull <name>) and set MEMORY_MODEL_ID to its tag.
  • History window: num_history_runs=10 in src/agent.py.
  • Past sessions surfaced via search: num_history_sessions=3.
  • DB location: DB_PATH in src/memory.py (defaults to agent_data/agent.db).
  • User identity: PPTX_AGENT_USER_ID environment variable.
  • OAuth scopes: SCOPES in src/google_auth.pypresentations + full drive (the full Drive scope is required to download/upload arbitrary .pptx files).

Design decisions worth knowing

  • Drive .pptx files are updated in place via drive.files().update, not by copying. Drive ID, link and sharing all stay the same.
  • Slide delete and reorder are done by manipulating the <p:sldIdLst> XML directly — python-pptx exposes no public API for either.
  • find_and_replace_pptx joins a paragraph's runs, replaces on the joined string, then writes the result into the first run. This guarantees the replacement at the cost of collapsing per-run formatting in changed paragraphs.
  • Slide duplication is intentionally not offered for .pptx (no reliable python-pptx primitive); the agent routes the user to native Google Slides for that.
  • Folder-wide find/replace skips upload for files with zero replacements (bandwidth saving).
  • The python-pptx logic lives in pptx_tools.py; local_tools.py imports those helpers so the slide/text logic exists in exactly one place.

Common Issues

"OPENAI_API_KEY is not set in .env" The .env file must be in the project root. Copy from .env.example and put the real key inside.

The browser OAuth screen says "access blocked" Add your Gmail address as a test user in Google Cloud Console > OAuth consent screen.

File is not .pptx (mimeType=...) download_pptx works only on PowerPoint binary files. For native Google Slides, the agent uses GoogleSlidesTools instead.

Path escapes the active folder In local folder mode the agent cannot leave the opened folder. Open a higher-level folder that contains the path you need.

No folder is open. Call open_local_folder(path) first. Local tools are opt-in. Ask the agent to open a folder first.

Agent doesn't remember what we talked about last time Memory persistence requires agent_data/agent.db to be present and writable. Use :new only when you actually want a fresh session.

Ollama connection error / "model not found" Memory extraction runs on a local Ollama model. Make sure Ollama is installed and the daemon is running (ollama list should respond), and that the model is pulled: ollama pull qwen2.5:3b-instruct.


Roadmap (possible future additions)

  • Folder-wide bulk operations for native Google Slides.
  • Slide-level operations on speaker notes.
  • Theme / template application across a deck.
  • Async processing (parallel execution for large folders).
  • A web interface (Streamlit or FastAPI).

License

This project is distributed under the MIT License. See the LICENSE file in the project root for the full text.

About

Terminal AI agent that creates, edits and designs Google Slides & PowerPoint (.pptx) presentations on Google Drive and local disk — format-preserving, multilingual (TR/EN), with persistent memory.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages