Metadata-Version: 2.4
Name: ingenious
Version: 0.2.7
Summary: An enterprise-grade Python library for quickly setting up APIs to interact with AI Agents
Project-URL: Homepage, https://github.com/Insight-Services-APAC/ingenious
Project-URL: Documentation, https://insight-services-apac.github.io/ingenious/
Project-URL: Repository, https://github.com/Insight-Services-APAC/ingenious
Project-URL: Issues, https://github.com/Insight-Services-APAC/ingenious/issues
Author-email: John Rampono <john.rampono@insight.com>, Kokko Ng <kokko.ng@insight.com>, Elliot Zhu <elliot.zhu@insight.com>
License: MIT
License-File: LICENSE
Keywords: agent,autogen,azure,fastapi
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.13
Requires-Dist: aiofiles>=24.1.0
Requires-Dist: aiohttp==3.12.15
Requires-Dist: dependency-injector==4.48.1
Requires-Dist: fastapi==0.115.9
Requires-Dist: pydantic-settings>=2.10.1
Requires-Dist: pydantic==2.11.5
Requires-Dist: python-dotenv>=1.0.1
Requires-Dist: rich==13.7.1
Requires-Dist: structlog==25.4.0
Requires-Dist: typer==0.16.0
Requires-Dist: uvicorn>=0.35.0
Provides-Extra: ai
Requires-Dist: ats>=1.0.8; extra == 'ai'
Requires-Dist: autogen-agentchat>=0.5.7; extra == 'ai'
Requires-Dist: autogen-ext>=0.5.7; extra == 'ai'
Requires-Dist: openai>=1.82.0; extra == 'ai'
Requires-Dist: tiktoken>=0.9.0; extra == 'ai'
Provides-Extra: auth
Requires-Dist: bcrypt==4.3.0; extra == 'auth'
Requires-Dist: passlib>=1.7.4; extra == 'auth'
Requires-Dist: python-jose[cryptography]>=3.5.0; extra == 'auth'
Provides-Extra: azure
Requires-Dist: azure-core==1.34.0; extra == 'azure'
Requires-Dist: azure-cosmos>=4.9.0; extra == 'azure'
Requires-Dist: azure-identity>=1.17.1; extra == 'azure'
Requires-Dist: azure-keyvault-secrets>=4.10.0; extra == 'azure'
Requires-Dist: azure-search-documents>=11.5.2; extra == 'azure'
Requires-Dist: azure-storage-blob>=12.25.1; extra == 'azure'
Provides-Extra: azure-full
Requires-Dist: aiosqlite==0.21.0; extra == 'azure-full'
Requires-Dist: ats>=1.0.8; extra == 'azure-full'
Requires-Dist: autogen-agentchat>=0.5.7; extra == 'azure-full'
Requires-Dist: autogen-ext>=0.5.7; extra == 'azure-full'
Requires-Dist: azure-core==1.34.0; extra == 'azure-full'
Requires-Dist: azure-cosmos>=4.9.0; extra == 'azure-full'
Requires-Dist: azure-identity>=1.17.1; extra == 'azure-full'
Requires-Dist: azure-keyvault-secrets>=4.10.0; extra == 'azure-full'
Requires-Dist: azure-search-documents>=11.5.2; extra == 'azure-full'
Requires-Dist: azure-storage-blob>=12.25.1; extra == 'azure-full'
Requires-Dist: bcrypt==4.3.0; extra == 'azure-full'
Requires-Dist: chromadb>=1.0.11; extra == 'azure-full'
Requires-Dist: fastapi-cli==0.0.7; extra == 'azure-full'
Requires-Dist: flask>=3.1.1; extra == 'azure-full'
Requires-Dist: jinja2==3.1.6; extra == 'azure-full'
Requires-Dist: jsonpickle==4.1.1; extra == 'azure-full'
Requires-Dist: markdown>=3.8.2; extra == 'azure-full'
Requires-Dist: openai>=1.82.0; extra == 'azure-full'
Requires-Dist: pandas>=2.3.1; extra == 'azure-full'
Requires-Dist: passlib>=1.7.4; extra == 'azure-full'
Requires-Dist: psutil>=7.0.0; extra == 'azure-full'
Requires-Dist: pyodbc>=5.2.0; extra == 'azure-full'
Requires-Dist: python-jose[cryptography]>=3.5.0; extra == 'azure-full'
Requires-Dist: tiktoken>=0.9.0; extra == 'azure-full'
Provides-Extra: chunk
Requires-Dist: ijson==3.2.3; extra == 'chunk'
Requires-Dist: jsonlines==3.1.0; extra == 'chunk'
Requires-Dist: langchain-experimental==0.3.4; extra == 'chunk'
Requires-Dist: langchain-openai==0.3.0; extra == 'chunk'
Requires-Dist: langchain-text-splitters==0.3.0; extra == 'chunk'
Requires-Dist: regex==2024.11.6; extra == 'chunk'
Requires-Dist: xxhash==3.5.0; extra == 'chunk'
Provides-Extra: core
Requires-Dist: aiosqlite==0.21.0; extra == 'core'
Requires-Dist: fastapi-cli==0.0.7; extra == 'core'
Requires-Dist: jinja2==3.1.6; extra == 'core'
Requires-Dist: jsonpickle==4.1.1; extra == 'core'
Requires-Dist: markdown>=3.8.2; extra == 'core'
Requires-Dist: pandas>=2.3.1; extra == 'core'
Provides-Extra: database
Requires-Dist: psutil>=7.0.0; extra == 'database'
Requires-Dist: pyodbc>=5.2.0; extra == 'database'
Provides-Extra: dataprep
Requires-Dist: backoff==2.2.0; extra == 'dataprep'
Requires-Dist: scrapfly-sdk==0.8.23; extra == 'dataprep'
Provides-Extra: development
Requires-Dist: ipython==9.2.0; extra == 'development'
Provides-Extra: docs
Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.4.7; extra == 'docs'
Requires-Dist: mkdocs-minify-plugin>=0.8.0; extra == 'docs'
Requires-Dist: mkdocs-nav-weight>=0.2.0; extra == 'docs'
Requires-Dist: mkdocs-redirects>=1.2.2; extra == 'docs'
Requires-Dist: mkdocs-table-reader-plugin>=3.1.0; extra == 'docs'
Provides-Extra: document-advanced
Requires-Dist: pdfminer-six==20250506; extra == 'document-advanced'
Requires-Dist: unstructured[all-docs]==0.17.2; extra == 'document-advanced'
Provides-Extra: document-processing
Requires-Dist: azure-ai-documentintelligence==1.0.2; extra == 'document-processing'
Requires-Dist: pymupdf==1.26.1; extra == 'document-processing'
Provides-Extra: full
Requires-Dist: aiosqlite==0.21.0; extra == 'full'
Requires-Dist: ats>=1.0.8; extra == 'full'
Requires-Dist: autogen-agentchat>=0.5.7; extra == 'full'
Requires-Dist: autogen-ext>=0.5.7; extra == 'full'
Requires-Dist: azure-ai-documentintelligence==1.0.2; extra == 'full'
Requires-Dist: azure-core==1.34.0; extra == 'full'
Requires-Dist: azure-cosmos>=4.9.0; extra == 'full'
Requires-Dist: azure-identity>=1.17.1; extra == 'full'
Requires-Dist: azure-keyvault-secrets>=4.10.0; extra == 'full'
Requires-Dist: azure-search-documents>=11.5.2; extra == 'full'
Requires-Dist: azure-storage-blob>=12.25.1; extra == 'full'
Requires-Dist: backoff==2.2.0; extra == 'full'
Requires-Dist: bcrypt==4.3.0; extra == 'full'
Requires-Dist: chromadb>=1.0.11; extra == 'full'
Requires-Dist: fastapi-cli==0.0.7; extra == 'full'
Requires-Dist: flask>=3.1.1; extra == 'full'
Requires-Dist: jinja2==3.1.6; extra == 'full'
Requires-Dist: jsonpickle==4.1.1; extra == 'full'
Requires-Dist: markdown>=3.8.2; extra == 'full'
Requires-Dist: matplotlib==3.10.3; extra == 'full'
Requires-Dist: openai>=1.82.0; extra == 'full'
Requires-Dist: pandas>=2.3.1; extra == 'full'
Requires-Dist: passlib>=1.7.4; extra == 'full'
Requires-Dist: psutil>=7.0.0; extra == 'full'
Requires-Dist: pymupdf==1.26.1; extra == 'full'
Requires-Dist: pyodbc>=5.2.0; extra == 'full'
Requires-Dist: python-jose[cryptography]>=3.5.0; extra == 'full'
Requires-Dist: scrapfly-sdk==0.8.23; extra == 'full'
Requires-Dist: seaborn==0.13.2; extra == 'full'
Requires-Dist: sentence-transformers==5.0.0; extra == 'full'
Requires-Dist: tiktoken>=0.9.0; extra == 'full'
Provides-Extra: knowledge-base
Requires-Dist: chromadb>=1.0.11; extra == 'knowledge-base'
Provides-Extra: knowledge-focused
Requires-Dist: aiosqlite==0.21.0; extra == 'knowledge-focused'
Requires-Dist: ats>=1.0.8; extra == 'knowledge-focused'
Requires-Dist: autogen-agentchat>=0.5.7; extra == 'knowledge-focused'
Requires-Dist: autogen-ext>=0.5.7; extra == 'knowledge-focused'
Requires-Dist: chromadb>=1.0.11; extra == 'knowledge-focused'
Requires-Dist: fastapi-cli==0.0.7; extra == 'knowledge-focused'
Requires-Dist: jinja2==3.1.6; extra == 'knowledge-focused'
Requires-Dist: jsonpickle==4.1.1; extra == 'knowledge-focused'
Requires-Dist: markdown>=3.8.2; extra == 'knowledge-focused'
Requires-Dist: openai>=1.82.0; extra == 'knowledge-focused'
Requires-Dist: pandas>=2.3.1; extra == 'knowledge-focused'
Requires-Dist: sentence-transformers==5.0.0; extra == 'knowledge-focused'
Requires-Dist: tiktoken>=0.9.0; extra == 'knowledge-focused'
Provides-Extra: minimal
Provides-Extra: ml
Requires-Dist: sentence-transformers==5.0.0; extra == 'ml'
Provides-Extra: standard
Requires-Dist: aiosqlite==0.21.0; extra == 'standard'
Requires-Dist: ats>=1.0.8; extra == 'standard'
Requires-Dist: autogen-agentchat>=0.5.7; extra == 'standard'
Requires-Dist: autogen-ext>=0.5.7; extra == 'standard'
Requires-Dist: bcrypt==4.3.0; extra == 'standard'
Requires-Dist: fastapi-cli==0.0.7; extra == 'standard'
Requires-Dist: jinja2==3.1.6; extra == 'standard'
Requires-Dist: jsonpickle==4.1.1; extra == 'standard'
Requires-Dist: markdown>=3.8.2; extra == 'standard'
Requires-Dist: openai>=1.82.0; extra == 'standard'
Requires-Dist: pandas>=2.3.1; extra == 'standard'
Requires-Dist: passlib>=1.7.4; extra == 'standard'
Requires-Dist: psutil>=7.0.0; extra == 'standard'
Requires-Dist: pyodbc>=5.2.0; extra == 'standard'
Requires-Dist: python-jose[cryptography]>=3.5.0; extra == 'standard'
Requires-Dist: tiktoken>=0.9.0; extra == 'standard'
Provides-Extra: test
Requires-Dist: httpx==0.28.1; extra == 'test'
Requires-Dist: hypothesis==6.136.2; extra == 'test'
Requires-Dist: mypy==1.16.1; extra == 'test'
Requires-Dist: pip-audit==2.9.0; extra == 'test'
Requires-Dist: pre-commit==4.2.0; extra == 'test'
Requires-Dist: pytest-asyncio==0.26.0; extra == 'test'
Requires-Dist: pytest-cov==6.1.1; extra == 'test'
Requires-Dist: pytest-mock==3.14.0; extra == 'test'
Requires-Dist: pytest-timeout==2.4.0; extra == 'test'
Requires-Dist: pytest==8.3.5; extra == 'test'
Requires-Dist: reportlab==4.4.2; extra == 'test'
Requires-Dist: ruff==0.11.10; extra == 'test'
Requires-Dist: twine==6.0.0; extra == 'test'
Requires-Dist: types-markdown==3.8.0.20250708; extra == 'test'
Requires-Dist: types-psutil==7.0.0.20250601; extra == 'test'
Requires-Dist: types-pyyaml==6.0.12.20250516; extra == 'test'
Requires-Dist: types-requests==2.32.4.20250611; extra == 'test'
Requires-Dist: vulture==2.14; extra == 'test'
Provides-Extra: ui
Requires-Dist: flask>=3.1.1; extra == 'ui'
Provides-Extra: visualization
Requires-Dist: matplotlib==3.10.3; extra == 'visualization'
Requires-Dist: seaborn==0.13.2; extra == 'visualization'
Description-Content-Type: text/markdown

# Insight Ingenious

[![Version](https://img.shields.io/badge/version-0.2.6-blue.svg)](https://github.com/Insight-Services-APAC/ingenious)
[![Python](https://img.shields.io/badge/python-3.13+-green.svg)](https://www.python.org/downloads/)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Insight-Services-APAC/ingenious)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![License](https://img.shields.io/badge/license-MIT-purple.svg)](LICENSE)

Ingenious is a tool for quickly setting up APIs to interact with AI Agents. It features multi-agent conversation flows using Microsoft's AutoGen, JWT authentication, and supports both local development (SQLite, ChromaDB) and production Azure deployments (Azure OpenAI, Azure SQL, Cosmos DB, Azure AI Search, Azure Blob, Container Apps).

## Quick Start

Get up and running in 5 minutes with just an Azure OpenAI API key!

### Prerequisites
- Python 3.13 or higher (required - earlier versions are not supported)
- OpenAI or Azure OpenAI API credentials
- [uv package manager](https://docs.astral.sh/uv/)

**Flexible Architecture**: Ingenious supports both local development (SQLite, ChromaDB) and production Azure deployments (Azure SQL, Cosmos DB, Azure AI Search, Azure Blob, Container Apps). Start local, scale to Azure as needed.

### AI-Assisted Set Up (give this prompt to your preferred coding agent)

**WARNING: Audit ALL Azure CLI commands!**

```markdown
Follow all steps in [this guide](https://blog.insight-services-apac.dev/ingenious/getting-started/) and [this guide](https://blog.insight-services-apac.dev/ingenious/guides/complete-azure-deployment/).

Set up ingenious locally first and then migrate to Azure services as shown in the docs.

- Deploy only required resources at minimal cost.
- Use a new resource group: **<your-new-rg-name>**.
- For the SQL Server SKU choose Basic - 5 DTUs
- Azure CLI access is available.
```
### 5-Minute Setup

1. **Install and Initialize**:
    ```bash
    # Navigate to your desired project directory first
    cd /path/to/your/project

    # Set up the uv project
    uv init

    # Choose installation based on features needed:

    # Basic API server only (33 packages)
    uv add "ingenious"

    # Standard production setup with auth + AI + database (86 packages)
    uv add "ingenious[standard]"

    # Full Azure cloud integration (recommended for production)
    uv add "ingenious[azure-full]"

    # Everything including document processing and ML
    uv add "ingenious[full]"

    # Or build your own combination:
    # uv add "ingenious[core,auth,ai]"           # Basic AI workflows with auth
    # uv add "ingenious[ai,knowledge-base]"      # AI + vector search only
    # uv add "ingenious[azure,database]"         # Azure + database without AI

    # For nightly builds, add --index-url prefix:
    # uv add --index-url https://test.pypi.org/simple/ "ingenious[azure-full]"

    # Initialize project in the current directory
    uv run ingen init
    ```

2. **Configure Credentials**:
    Create a `.env` file with your Azure OpenAI credentials:
    ```bash
    # Create .env file in current directory
    touch .env

    # Edit .env file with your actual credentials
    ```

    **Required configuration (add to .env file)**:
    ```bash
    # Core AI Model Configuration (REQUIRED)
    INGENIOUS_MODELS__0__MODEL=gpt-4o-mini
    INGENIOUS_MODELS__0__API_TYPE=rest
    INGENIOUS_MODELS__0__API_VERSION=2024-12-01-preview
    INGENIOUS_MODELS__0__DEPLOYMENT=gpt-4o-mini-deployment
    INGENIOUS_MODELS__0__API_KEY=your-actual-api-key-here
    INGENIOUS_MODELS__0__BASE_URL=https://eastus.api.cognitive.microsoft.com/

    # For Azure OpenAI: Use the Cognitive Services endpoint format (not OpenAI endpoint)
    # CORRECT: https://eastus.api.cognitive.microsoft.com/
    # INCORRECT: https://your-resource.openai.azure.com/
    # For OpenAI (not Azure), use:
    # INGENIOUS_MODELS__0__BASE_URL=https://api.openai.com/v1
    # INGENIOUS_MODELS__0__API_VERSION=2024-02-01

    # Web Server Configuration (use different port if 80 conflicts)
    INGENIOUS_WEB_CONFIGURATION__PORT=8000
    INGENIOUS_WEB_CONFIGURATION__IP_ADDRESS=0.0.0.0
    INGENIOUS_WEB_CONFIGURATION__AUTHENTICATION__ENABLE=false

    # Chat Service Configuration (REQUIRED)
    INGENIOUS_CHAT_SERVICE__TYPE=multi_agent

    # Production: Disable built-in workflows (optional)
    # INGENIOUS_CHAT_SERVICE__ENABLE_BUILTIN_WORKFLOWS=false

    # Chat History Database (Local SQLite)
    INGENIOUS_CHAT_HISTORY__DATABASE_TYPE=sqlite
    INGENIOUS_CHAT_HISTORY__DATABASE_PATH=./.tmp/chat_history.db
    INGENIOUS_CHAT_HISTORY__MEMORY_PATH=./.tmp

    # Knowledge base configuration - local ChromaDB for development
    KB_POLICY=local_only
    KB_TOPK_DIRECT=3
    KB_TOPK_ASSIST=5
    KB_MODE=direct

    # SQL database configuration - local SQLite for development
    INGENIOUS_LOCAL_SQL_DB__DATABASE_PATH=./.tmp/sample_sql.db

    # Logging Configuration
    INGENIOUS_LOGGING__ROOT_LOG_LEVEL=info
    INGENIOUS_LOGGING__LOG_LEVEL=info
    ```

3. **Validate Configuration**:
    ```bash
    uv run ingen validate  # Check configuration before starting
    ```

    **Expected validation output**: You should see confirmation that your configuration is valid and a count of available workflows:
    - **Minimal install**: 0/3 workflows (requires `[ai]` group for workflow functionality)
    - **Standard install**: 3/4 workflows (classification-agent, sql-manipulation-agent working; knowledge-base-agent requires `[knowledge-base]` group)
    - **Azure-full install**: 4/4 workflows working (classification-agent, knowledge-base-agent, sql-manipulation-agent, and bike-insights after `ingen init`)

    **If validation fails with port conflicts**:
    ```bash
    # Find and kill process using port 8000 (recommended approach)
    lsof -ti:8000 | xargs kill -9
    uv run ingen validate

    # Alternative: Check if validation passes with different port
    INGENIOUS_WEB_CONFIGURATION__PORT=8001 uv run ingen validate

    # Or update your .env file before validating:
    echo "INGENIOUS_WEB_CONFIGURATION__PORT=8001" >> .env
    uv run ingen validate
    ```

    > **⚠️ BREAKING CHANGE**: Ingenious now uses **pydantic-settings** for configuration via environment variables. Legacy YAML configuration files (`config.yml`, `profiles.yml`) are **no longer supported** and must be migrated to environment variables with `INGENIOUS_` prefixes. Use the migration script:
    > ```bash
    > uv run python scripts/migrate_config.py --yaml-file config.yml --output .env
    > uv run python scripts/migrate_config.py --yaml-file profiles.yml --output .env.profiles
    > ```

4. **Start the Server**:
    ```bash
    # REQUIRED: Use KB_POLICY=local_only for knowledge-base-agent to work with ChromaDB
    KB_POLICY=local_only uv run ingen serve --port 8000

    # Alternative: Start server without KB prefix (but knowledge-base-agent may not work)
    uv run ingen serve --port 8000

    # Note: Default port is 80, but port 8000 is recommended to avoid conflicts
    # Additional options:
    # --host 0.0.0.0         # Bind host (default: 0.0.0.0)
    # --port                 # Port to bind (default: 80 or $INGENIOUS_WEB_CONFIGURATION__PORT)
    ```

5. **Verify Health**:
    ```bash
    # Check server health (adjust port if different)
    curl http://localhost:8000/api/v1/health
    ```

    **Expected health response**: A JSON response indicating server status:
    ```json
    {
      "status": "healthy",
      "timestamp": "2025-08-29T01:15:30.830525",
      "response_time_ms": 1.4,
      "components": {"configuration": "ok", "profile": "ok"},
      "version": "1.0.0",
      "uptime": "available"
    }
    ```

6. **Test with Core Workflows**:

    Create test files to avoid JSON escaping issues:
    ```bash
    # Create test files for each workflow
    echo '{"user_prompt": "Analyze this customer feedback: Great product", "conversation_flow": "classification-agent"}' > test_classification.json
    echo '{"user_prompt": "Search for documentation about setup", "conversation_flow": "knowledge-base-agent"}' > test_knowledge.json
    echo '{"user_prompt": "Show me all tables in the database", "conversation_flow": "sql-manipulation-agent"}' > test_sql.json

    # Test each workflow
    curl -X POST http://localhost:8000/api/v1/chat -H "Content-Type: application/json" -d @test_classification.json
    curl -X POST http://localhost:8000/api/v1/chat -H "Content-Type: application/json" -d @test_knowledge.json
    curl -X POST http://localhost:8000/api/v1/chat -H "Content-Type: application/json" -d @test_sql.json
    ```

    **To populate knowledge base for testing** (optional but recommended):
    ```bash
    # Create sample knowledge base document for testing
    mkdir -p .tmp/knowledge_base
    cat > .tmp/knowledge_base/setup_guide.md << 'EOF'
    # Ingenious Setup Guide

    ## Quick Setup Instructions

    Ingenious is a multi-agent AI framework that allows you to quickly set up APIs for AI agents.

    ### Prerequisites
    - Python 3.13+
    - OpenAI API key or Azure OpenAI credentials
    - UV package manager

    ### Installation Steps
    1. Initialize UV project: `uv init`
    2. Install Ingenious: `uv add "ingenious[azure-full]"`
    3. Initialize project: `uv run ingen init`
    4. Configure environment variables in .env file
    5. Start server: `uv run ingen serve --port 8000`
    EOF

    # Now test knowledge-base-agent again to see populated results
    curl -X POST http://localhost:8000/api/v1/chat -H "Content-Type: application/json" -d @test_knowledge.json
    ```

**Expected Responses**:
- **Successful classification-agent response**: JSON with message analysis, sentiment scores, and topic categorization
- **Successful knowledge-base-agent response**: JSON with relevant information retrieved from local ChromaDB (with sample document, will contain setup instructions; without, may indicate empty knowledge base)
- **Successful sql-manipulation-agent response**: JSON with SQL query results showing database table information from local SQLite database (sample database includes `students_performance` table)

**Example successful responses**:
```bash
# classification-agent typical response format:
{"response": "Analysis: Positive sentiment (0.8/1.0)... Category: Product Feedback"}

# knowledge-base-agent with populated knowledge base:
{"response": "Based on the setup guide: Ingenious requires Python 3.13+..."}

# sql-manipulation-agent typical response:
{"response": "Found 3 tables in database: users, products, orders..."}
```

That's it! You should see a JSON response with AI analysis of the input.

**Next Steps - Test Additional Workflows**:

7. **Test bike-insights Workflow (Requires `ingen init` first)**:

    The `bike-insights` workflow is part of the project template and must be initialized first:
    ```bash
    # First initialize project to get bike-insights workflow
    uv run ingen init

    # Create bike-insights test data file
    # IMPORTANT: bike-insights requires JSON data in the user_prompt field (double-encoded JSON)
    printf '%s\n' '{
      "user_prompt": "{\"revision_id\": \"quickstart-1\", \"identifier\": \"test-001\", \"stores\": [{\"name\": \"Test Store\", \"location\": \"NSW\", \"bike_sales\": [{\"product_code\": \"MB-TREK-2021-XC\", \"quantity_sold\": 2, \"sale_date\": \"2023-04-01\", \"year\": 2023, \"month\": \"April\", \"customer_review\": {\"rating\": 4.5, \"comment\": \"Great bike\"}}], \"bike_stock\": []}]}",
      "conversation_flow": "bike-insights"
    }' > test_bike_insights.json

    # Test bike-insights workflow
    curl -X POST http://localhost:8000/api/v1/chat -H "Content-Type: application/json" -d @test_bike_insights.json
    ```

    **Expected bike-insights response**: JSON with comprehensive bike sales analysis from multiple agents (fiscal analysis, customer sentiment, summary, and bike lookup).

**Important Notes**:
- **Core Library Workflows** (`classification-agent`, `knowledge-base-agent`, `sql-manipulation-agent`) are available by default and accept simple text prompts
- **Template Workflows** like `bike-insights` require JSON-formatted data with specific fields and are only available after running `ingen init`
- The `bike-insights` workflow is the recommended "Hello World" example for new users
- **Production Security**: Set `INGENIOUS_CHAT_SERVICE__ENABLE_BUILTIN_WORKFLOWS=false` to disable built-in workflows and expose only your custom `ingenious_extensions` workflows

## Next Steps: Creating Custom Workflows

Once you have the basic setup working with the core workflows, you can create your own custom conversation flows:

**[Create Custom Workflows →](docs/guides/custom-workflows.md)**

Learn how to:
- Build custom AI agents for your specific use cases
- Implement multi-agent conversation patterns
- Handle complex business logic and data processing
- Deploy and test your custom workflows

## Documentation

For detailed documentation, see the [docs](https://insight-services-apac.github.io/ingenious/).

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](https://github.com/Insight-Services-APAC/ingenious/blob/main/CONTRIBUTING.md) for guidelines.

## License

This project is licensed under the terms specified in the [LICENSE](https://github.com/Insight-Services-APAC/ingenious/blob/main/LICENSE) file.
