Skip to content

xoTEMPESTox-Archive/FluidAI_Assignment

Repository files navigation

60-Minute Autonomous Agent API

This is an autonomous document agent API built using FastAPI, Groq, and python-docx. The agent takes natural language prompts, creates its own plan, drafts structured content, self-checks for accuracy, and compiles a polished Word .docx document.


πŸ› οΈ Technology Stack & Architectural Decisions

1. Native Procedural Loop vs. Frameworks (LangChain/CrewAI)

We chose a native procedural Python loop rather than complex orchestration frameworks (like LangChain or CrewAI). This gives us:

  • Maximum Execution Speed: Direct API calls minimize execution latency.
  • Full Determinism: Procedural flows are predictable, easy to debug, and free of framework overhead.
  • Simplicity & Extensibility: We maintain complete control over the prompts, parsers, and system states without learning complex abstractions.

2. Markdown-to-Docx Custom Parsing

Using a two-step drafting pipeline (Drafter writes Markdown -> Executor parses Markdown to DOCX) ensures:

  • Separation of Concerns: The LLM focuses on content creation using standard markdown semantics, while our backend handles styling (margins, fonts, colors).
  • Speed & Reliability: We do not rely on resource-heavy tools like Pandoc or LibreOffice. Our lightweight custom parser parses Headings, Paragraphs, and Bullet Lists directly using python-docx and translates horizontal rules (---) into page breaks.

3. Principle of Least Privilege

The agent does not execute code or run arbitrary shell commands. It writes markdown, which is validated and fed into a whitelisted, sandboxed python tool (render_and_save_docx). Filenames are strictly sanitized to prevent directory traversal attacks (e.g. ../).

4. Observability & Tracing

Every major state transition, LLM call, self-check event, or exception is caught and logged to an execution_trace array. If a component fails, a 500 Internal Server Error is returned alongside the full trace, rather than crashing the API.


πŸ“‚ Project Structure

FluidAI_Assignment/
β”‚
β”œβ”€β”€ .env.example            # Environment variables template (copy to .env)
β”œβ”€β”€ requirements.txt        # Python dependencies
β”œβ”€β”€ README.md               # Swagger & Postman documentation (this file)
β”‚
β”œβ”€β”€ app/                    # Application source files
β”‚   β”œβ”€β”€ main.py             # FastAPI entrypoint & routes
β”‚   β”œβ”€β”€ security.py         # Mock authentication and path validation
β”‚   β”œβ”€β”€ agent.py            # Planner, Drafter (concurrency limit=1), and QA loop
β”‚   └── document_generator.py # Custom Markdown-to-Docx renderer with page-breaks
β”‚
└── outputs/                # Sandbox folder where generated docx documents are saved

πŸš€ Running the API Locally

1. Configure Environment Variables

Copy the .env.example template to .env and fill in your Groq API key:

cp .env.example .env

Open .env and configure:

GROQ_API_KEY=your_actual_groq_api_key_here

2. Activate Environment & Start Server

Make sure you are in the workspace root directory. Run the following commands to activate your environment and start the development server:

# Activate the conda environment
conda activate fluid_agent

# Run the FastAPI server
python -m uvicorn app.main:app --reload

The server will start on http://127.0.0.1:8000.

3. Access Swagger Documentation

Once the server is running, open your web browser and navigate to: πŸ‘‰ http://127.0.0.1:8000/docs

This provides an interactive Swagger UI where you can set headers, try out endpoints, and download the generated responses directly.


πŸ§ͺ Testing Guidelines (Swagger / Postman / cURL)

Required Headers

Every API request must include the following header for mock authentication:

  • X-API-Key: fluid-secret-key-2026

If this header is missing or incorrect, the server will return a 401 Unauthorized error.


Test Case 1: Standard Business Request

Copy and paste this payload into Swagger UI or Postman to test a standard business document prompt:

HTTP Request

  • Method: POST
  • URL: http://127.0.0.1:8000/agent
  • Header: X-API-Key: fluid-secret-key-2026
  • Body (JSON):
{
  "request": "Draft a project plan for implementing a new customer support CRM system."
}

Expected Response (200 OK)

{
    "status": "success",
    "response": "I'm glad to let you know that the project plan for implementing a customer support CRM system has been successfully built and saved as 'document.docx'. Based on the tasks we completed, I defined the project scope and objectives, identified key stakeholders and CRM requirements, developed an implementation timeline, and planned a data migration and integration strategy. This document is fully structured to guide your implementation process.",
    "tasks": [
        "Define Project Scope and Objectives",
        "Identify Key Stakeholders and CRM Requirements",
        "Develop an Implementation Timeline and Milestones",
        "Plan Data Migration and Integration Strategy"
    ],
    "document_path": "/outputs/document.docx",
    "execution_trace": [
        "[00:01:29] Request received and authenticated.",
        "[00:01:29] Planner Phase: Requesting Groq to generate execution plan.",
        "[00:01:30] Planner Phase: Successfully generated 4 tasks.",
        "[00:01:30] Drafter Phase: Dispatching cover page and 4 section drafts.",
        "[00:01:37] Drafter Phase: Markdown generation complete.",
        "[00:01:37] Reflection/Self-Check Phase: Reviewing generated draft against planning tasks.",
        "[00:36:28] Reflection/Self-Check Phase: Identified missing details. Appending supplemental appendix.",
        "[00:36:28] Executor Phase: Requesting LLM to select document tool for compilation.",
        "[00:36:29] Executor Phase: LLM invoked tool 'render_and_save_docx' with arguments: {'output_filename': 'document.docx'}.",
        "[00:36:29] File saved successfully. Final output path: ./outputs\\document.docx",
        "[00:36:30] Response Phase: Generating conversational summary response.",
        "[00:36:31] Response Phase: Response generated successfully."
    ]
}

Test Case 2: Complex Business Request (Ambiguous & Multi-Step)

Copy and paste this payload to test how the agent resolves ambiguous requirements and makes reasonable assumptions:

HTTP Request

  • Method: POST
  • URL: http://127.0.0.1:8000/agent
  • Header: X-API-Key: fluid-secret-key-2026
  • Body (JSON):
{
  "request": "Create a technical design document for a high-availability shopping cart service, but it needs to be both extremely secure and cost-efficient under high traffic, while we don't have clear requirements on the hosting provider or database choice."
}

Expected Response (200 OK)

The agent will autonomously decide database choices (e.g., PostgreSQL for relational data, Redis for caching) and cloud architectures (e.g., AWS ECS/EKS) to resolve the lack of hosting requirements, outlining the exact solutions in a multi-page document compiled in under 20-30 seconds.


🚫 Error Responses

1. Unauthorized (401 Unauthorized)

Returned if the X-API-Key header is missing, empty, or incorrect.

{
  "detail": "Unauthorized: Invalid or missing X-API-Key"
}

2. Internal Server Error (500 Internal Server Error)

Returned if any phase of the agent loop (LLM call or Document Generation) encounters an error, preventing crashing of the server.

{
  "status": "error",
  "message": "Groq API Connection Failed",
  "execution_trace": [
    "[00:01:29] Request received and authenticated.",
    "[00:01:29] Planner Phase: Requesting Groq to generate execution plan.",
    "[00:01:30] Planner Phase Failed: API connection error."
  ]
}

πŸŽ™οΈ On-Screen Talking Points (Your Recording Cheat Sheet)

1. Strategy, Introduction & Tech Stack

  • Architecture & Technologies: High-performance FastAPI backend interface, native Python procedural control loop, and Groq llama-3.3-70b-versatile client.
  • Tradeoff: Simplicity vs Extensibility:
    • Decision: We opted for a lightweight procedural framework over heavy agent frameworks (like LangChain or CrewAI).
    • Rationale: This gives us direct control over LLM prompts, state management, and speed. The code remains clean and extremely easy to extend (by adding python functions as whitelisted tools or introducing new pipeline steps) without being locked into complex library abstractions.
  • Tradeoff: Single-Agent vs Multi-Agent Architecture:
    • Decision: A single-agent procedural pipeline (driving sequential phases) was chosen instead of a multi-agent chat system.
    • Rationale: Multi-agent setups introduce severe latency, infinite loops, and massive API token consumption. A single agent running through structured planning, drafting, and QA phases is highly deterministic, fast (executes in sub-20 seconds), and fully capable of compiling professional business documents.

2. Live Demo & API Design

  • API Design & Security: Standard synchronous POST /agent endpoint with Pydantic request-response schemas. Includes mock API key headers (X-API-Key: fluid-secret-key-2026) to enforce access control (demonstrate a 401 response first).
  • Document Generation & Styling: Custom Markdown-to-Docx rendering engine built on top of python-docx. It translates headings, bullet points, paragraphs, and markdown page breaks (---) directly into a stylized executive layout (Arial, 1-inch margins, brand-navy colored headings, centered cover page).
  • Tradeoff: Autonomous Planning vs Deterministic Workflows:
    • Decision: The agent's workflow phases are deterministic (Planner -> Drafter -> Reflection -> Executor -> Response), but the planning logic and content generation are fully autonomous.
    • Demonstration: Test 2 shows this. When given an ambiguous prompt lacking database or hosting constraints, the agent's planning logic autonomously assumes database layers (PostgreSQL + Redis caching) and hosting details (AWS EKS) to satisfy the "high-availability" requirement without code changes or manual intervention.

3. Agent Workflow & LLM Integration

  • The 5-Phase Agent Workflow:
    1. Planner (Planning Logic): Analyzes the prompt and generates exactly 4 structured tasks using JSON schema instructions.
    2. Drafter (LLM Integration): Generates Markdown cover pages and section drafts sequentially. We use a concurrency limit (Semaphore=1) to prevent rate-limit 429 issues on free/low-tier API accounts.
    3. Reflection (QA Check): Automated QA that compares the drafted Markdown against the planner's task list, appending a supplemental appendix if any core requirement is missing.
    4. Executor (Tool Usage): The LLM outputs a structured tool-call requesting execution of render_and_save_docx, which our sandboxed python parser runs securely.
    5. Response (New): Generates a conversational 1-paragraph summary response confirming document completion, completed tasks, and file locations.
  • Tradeoff: Speed vs Functionality:
    • Decision: Decoupling content generation (Markdown text created by Groq) from visual layout compilation (docx file written by Python).
    • Rationale: It allows the LLM to write quickly and cleanly in standard Markdown without struggling with binary file formats. Our python backend compiles a beautifully formatted, publication-ready Word file in milliseconds, delivering the optimal balance of rich document styling and low API execution times.

4. Debugging & Engineering Insight

  • Tradeoff: Accuracy vs Development Time:
    • Decision: Utilizing Llama-3.3-70B with few-shot prompts and structured JSON formatting instructions rather than writing complex, brittle rule-based validation logic.
    • Rationale: This approach allowed us to achieve near-perfect planning and drafting accuracy in minimal development time, keeping the codebase clean and agile.
  • Debugging & Resolution Highlights:
    • JSON Sanitization: Built a custom strip-and-clean parser in agent.py to strip out markdown code blocks (e.g. json ... ) which often cause standard JSON parsers to crash.
    • SSL File Error Issue: Diagnosed a critical FileNotFoundError on startup caused by an invalid SSL_CERT_FILE path in the terminal environment. Solved this by implementing startup path sanitization in main.py to check certificate existence and safely clean invalid env variables.
    • State Management Tradeoff: Used in-memory execution trace arrays since FastAPI processes this synchronously. In a large production setting, these tasks would run asynchronously using a persistent state database or a file-based scratchpad.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages