Skip to content

harmeshgv/idea2tasks-ai-assistant

Repository files navigation

Idea2Tasks AI Assistant

Capture free-form thoughts and turn them into:

  • Structured markdown notes in your Obsidian vault
  • Extracted tasks
  • Optional Google Calendar events

This project is designed as a clean, modular Python service with explicit boundaries between orchestration, LLM reasoning, and tool integrations.

Why This Project

The goal is to reduce friction between thinking and execution:

  • You type one unstructured capture.
  • The system classifies intent.
  • It structures the content.
  • It writes a clean note.
  • It optionally creates calendar events.

The same pipeline can be run from CLI today and extended to API/webhooks later.

Core Features

  • Groq LLM integration (OpenAI-compatible chat endpoint)
  • Task-specific model routing (fast default classifier + stronger default structurer)
  • LangGraph runtime when available
  • Deterministic inline fallback runner when langgraph is not installed
  • Obsidian vault markdown writer with safe path checks
  • Optional Google Calendar event creation with OAuth refresh-token flow
  • One-time helper script to generate and persist GOOGLE_REFRESH_TOKEN
  • Heuristic fallbacks when LLM/network errors occur
  • .env loading built into config (no extra dotenv dependency)
  • Timezone-aware scheduling for relative time phrases (today/tomorrow/next week)

What Is Working

  • End-to-end CLI capture flow (main.py)
  • Groq-backed classification + structuring with JSON/fallback handling
  • Obsidian note writing with safe path validation
  • Google Calendar integration using OAuth refresh-token flow
  • Automatic access-token refresh and retry on token expiration (401)
  • Local timezone handling for relative schedule phrases
  • One-time refresh-token generation helper script

Architecture (Clean Boundaries)

  • main.py: composition root + CLI entrypoint
  • services/: application use-case orchestration
  • graph/: workflow state machine, nodes, routing
  • llm/: prompt loading, reasoning, and Groq adapter
  • interfaces/: ports/protocols for dependency inversion
  • tools/: concrete adapters (Obsidian, Google Calendar)
  • schemas/: typed, validated dataclass contracts
  • utils/: file helper primitives

High-level flow:

CLI input
  -> CapturePipelineService
    -> WorkflowGraphBuilder
      -> ClassifyNode
      -> StructureNode
      -> WriteNoteNode
      -> (optional) CalendarNode
  -> PipelineResult

Repository Structure

idea2tasks-ai-assistant/
├── main.py
├── config.py
├── pyproject.toml
├── .env.example
├── prompts/
│   ├── classifier.txt
│   └── formatter.txt
├── llm/
│   ├── groq_client.py
│   ├── prompt_loader.py
│   └── reasoner.py
├── graph/
│   ├── builder.py
│   ├── state.py
│   └── nodes/
│       ├── classify.py
│       ├── structure.py
│       ├── write_note.py
│       └── calendar.py
├── services/
│   └── capture_pipeline.py
├── interfaces/
│   ├── llm.py
│   ├── note_sink.py
│   └── calendar.py
├── tools/
│   ├── obsidian_writer.py
│   ├── google_calendar_auth.py
│   └── google_calendar.py
├── scripts/
│   └── generate_refresh_token.py
├── schemas/
│   └── capture.py
├── utils/
│   └── file_helpers.py
└── tests/
    └── test_pipeline.py

End-to-End Runtime Behavior

  1. Input is collected via CLI (--text, stdin, or prompt).
  2. CaptureRequest validates raw capture text.
  3. Workflow state is initialized.
  4. ClassifyNode predicts one of: note_only, note_and_tasks, note_tasks_calendar, unknown.
  5. StructureNode produces StructuredCapture.
  6. WriteNoteNode writes markdown to Obsidian using filename format YYYY-MM-DD_HHMMSS_<slug>.md.
  7. CalendarNode runs only if events exist.
  8. PipelineResult returns note_path, tasks_count, and created_event_ids.

LLM Strategy

  • Provider: Groq (llm/groq_client.py)
  • Classifier model default: llama-3.1-8b-instant
  • Structurer model default: llama-3.3-70b-versatile

Fallback behavior:

  • If Groq request fails or returns invalid JSON, classification falls back to deterministic heuristics.
  • Structuring falls back to a minimal safe structured output.

This guarantees pipeline continuity even during partial LLM outages.

Setup

1. Clone and enter project

git clone <your-repo-url>
cd idea2tasks-ai-assistant

2. Install dependencies (uv recommended)

uv sync

Alternative:

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

2.5 (Optional) Install the CLI entrypoint

uv run idea2tasks --text "quick capture"

3. Configure environment

cp .env.example .env

Minimum required .env:

GROQ_API_KEY=your_groq_api_key_here
OBSIDIAN_VAULT_ROOT=/absolute/path/to/your/obsidian/vault

Important:

  • OBSIDIAN_VAULT_ROOT should point to the vault root, not .obsidian.
  • Correct: /home/user/Documents/Obsidian Vault
  • Incorrect: /home/user/Documents/Obsidian Vault/.obsidian

Configuration Reference

Required:

  • GROQ_API_KEY
  • OBSIDIAN_VAULT_ROOT

Optional:

  • GROQ_BASE_URL (default: https://api.groq.com/openai/v1)
  • GROQ_MODEL (default: llama-3.3-70b-versatile)
  • GROQ_MODEL_CLASSIFIER (default: llama-3.1-8b-instant)
  • GROQ_MODEL_STRUCTURER (default: GROQ_MODEL)
  • LLM_TEMPERATURE (default: 0.2, valid range 0.0-2.0)
  • PROMPTS_DIR (default: ./prompts)
  • OBSIDIAN_NOTES_SUBDIR (default: Inbox)
  • CALENDAR_ENABLED (true/false, default: false)
  • GOOGLE_CALENDAR_ID (required if calendar enabled)
  • GOOGLE_CLIENT_ID (required if calendar enabled)
  • GOOGLE_CLIENT_SECRET (required if calendar enabled)
  • GOOGLE_REFRESH_TOKEN (required if calendar enabled)

Usage

Run with inline text:

python main.py --text "Plan sprint review tomorrow at 10am and follow up with design team"

Run with stdin:

echo "Need to prepare proposal by Friday and schedule a client call next week" | python main.py

If installed as script:

idea2tasks --text "Draft product brief and create follow-up tasks"

If using uv:

uv run idea2tasks --text "Draft product brief and create follow-up tasks"

Example output:

Note path: Inbox/2026-02-20_214501_draft-product-brief.md
Tasks extracted: 2
Calendar events created: none

Calendar Integration

Set:

CALENDAR_ENABLED=true
GOOGLE_CALENDAR_ID=primary
GOOGLE_CLIENT_ID=<google_oauth_client_id>
GOOGLE_CLIENT_SECRET=<google_oauth_client_secret>
GOOGLE_REFRESH_TOKEN=<google_oauth_refresh_token>

Generate GOOGLE_REFRESH_TOKEN automatically (one-time):

python scripts/generate_refresh_token.py

The script:

  • uses Installed App OAuth flow in your browser
  • requests https://www.googleapis.com/auth/calendar
  • forces access_type=offline and prompt=consent
  • validates calendar API access
  • saves GOOGLE_REFRESH_TOKEN into .env

Behavior:

  • Access tokens are refreshed automatically from GOOGLE_REFRESH_TOKEN.
  • No manual access-token rotation in .env is required.
  • Legacy GOOGLE_CALENDAR_ACCESS_TOKEN is no longer used.
  • If calendar is enabled and structured events exist, events are created via Google Calendar API.
  • If disabled, calendar node is a no-op.

Testing

Run tests:

python -m pytest -q

Current tests cover:

  • Note-only flow
  • Calendar-disabled behavior with event-like captures

Pre-Push Checklist

Before pushing to GitHub:

  • Confirm .env is not tracked (git status should not show .env)
  • Keep .env.example placeholder-only (no real keys/tokens)
  • Run python -m compileall main.py config.py graph llm tools services schemas interfaces utils scripts tests to catch syntax errors
  • Run python -m pytest -q (if pytest installed)
  • Verify README.md reflects current env variables and auth flow
  • Verify no secrets appear in staged diff (git diff --staged)
  • Ensure generated artifacts are ignored (.venv, __pycache__, *.egg-info)

Troubleshooting

Missing required environment variable: GROQ_API_KEY

  • Ensure .env exists at repo root.
  • Ensure line format is valid: GROQ_API_KEY=...
  • Restart shell/session if you rely on exported env vars.

Groq API request failed: 403 ... 1010

  • Cloudflare/network policy block.
  • Disable VPN/proxy/ad blockers.
  • Try another network.
  • Regenerate API key and verify account permissions.

Error 403: access_denied during Google OAuth

  • In Google Cloud, your OAuth app is likely in Testing mode.
  • Add your Google account under Google Auth Platform -> Audience -> Test users.
  • If app type is Internal, use an account in that Workspace org.
  • Retry python scripts/generate_refresh_token.py after updating audience/test users.

Permission denied writing notes

  • Check OBSIDIAN_VAULT_ROOT.
  • Do not point it at .obsidian.
  • Verify write permission to vault directory.

Calendar created at wrong local time

  • The app now uses local timezone from your system clock for capture timestamps.
  • For unambiguous scheduling, include timezone in text, e.g. 10:00 AM IST.

pytest: command not found

  • Install dev deps: uv sync or pip install -e ".[dev]"

uv sync package discovery issues

  • This repo uses explicit setuptools package discovery in pyproject.toml.
  • Re-run uv sync after pulling latest pyproject.toml.

Security Notes

  • Never commit .env.
  • .env.example must contain placeholders only.
  • Treat GROQ_API_KEY and calendar tokens as secrets.
  • Rotate keys immediately if accidentally exposed.
  • If a key/token was ever committed, revoke and replace it before publishing.

Development Notes

  • Code style is intentionally explicit and modular.
  • Protocol interfaces in interfaces/ make swapping providers straightforward.
  • Graph logic stays isolated from tool implementations.
  • You can replace Groq by implementing interfaces.llm.LLMClient.

Extending the Project

Common extension points:

  • Add new graph nodes for additional actions.
  • Add new providers (Notion, Todoist, etc.) in tools/.
  • Replace CLI entry with FastAPI while reusing service layer.
  • Add richer prompt templates under prompts/.

Status

This is a working implementation with robust fallbacks and clear architecture. It is suitable for personal use and as a base for open-source collaboration.

License

No license file is currently included in this repository.
If you plan to publish it as open source, add a LICENSE file (for example MIT or Apache-2.0).

About

An AI-powered project assistant that transforms user-submitted ideas—spoken or written—into actionable tasks, visualizes them as graphs, and helps manage project planning in a conversational manner.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages