{"id":47800289,"url":"https://github.com/finmars-platform/finmars-ai-assistant","last_synced_at":"2026-04-03T16:58:50.659Z","repository":{"id":345417972,"uuid":"1065523100","full_name":"finmars-platform/finmars-ai-assistant","owner":"finmars-platform","description":"Finmars AI Assistant","archived":false,"fork":false,"pushed_at":"2026-03-27T01:01:47.000Z","size":922,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-27T13:07:10.115Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/finmars-platform.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2025-09-27T22:32:10.000Z","updated_at":"2026-03-02T13:23:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/finmars-platform/finmars-ai-assistant","commit_stats":null,"previous_names":["finmars-platform/finmars-ai-assistant"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/finmars-platform/finmars-ai-assistant","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/finmars-platform%2Ffinmars-ai-assistant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/finmars-platform%2Ffinmars-ai-assistant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/finmars-platform%2Ffinmars-ai-assistant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/finmars-platform%2Ffinmars-ai-assistant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/finmars-platform","download_url":"https://codeload.github.com/finmars-platform/finmars-ai-assistant/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/finmars-platform%2Ffinmars-ai-assistant/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31364571,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T15:19:21.178Z","status":"ssl_error","status_checked_at":"2026-04-03T15:19:20.670Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2026-04-03T16:58:49.911Z","updated_at":"2026-04-03T16:58:50.645Z","avatar_url":"https://github.com/finmars-platform.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Finmars AI Assistant\n\nAn intelligent AI assistant system for portfolio management using cutting-edge agent architectures and modular components.\n\n## Architecture Overview\n\n### 1. Chat Interface - Open WebUI\nWe utilize [Open WebUI](https://github.com/open-webui/open-webui) as our chat interface platform. Open WebUI is an extensible, feature-rich, and user-friendly self-hosted AI platform that offers:\n- Support for Ollama and OpenAI-compatible APIs\n- Built-in RAG (Retrieval Augmented Generation) capabilities\n- Granular user permissions and access control\n- Responsive design with mobile support\n- Plugin framework for custom logic\n- Web search and browsing integration\n\n### 2. Pipeline Modules - Open WebUI Pipelines\n[Open WebUI Pipelines](https://github.com/open-webui/pipelines) provides the capability to build modular agent logic. This framework allows us to:\n- Create customizable Python-based workflows\n- Build dynamic AI multi-agent behaviors\n- Integrate complex business logic\n- Support computationally heavy tasks\n- Enable function calling and custom RAG implementations\n\nPipelines is a **FastAPI application** with a fully **OpenAI-compatible API interface**. This means:\n- All API endpoints follow the OpenAI API specification\n- Any OpenAI client can be made compatible with our agent API by simply replacing the `base_url`\n- Seamless integration with existing OpenAI SDK implementations\n- Standard request/response formats for chat completions, embeddings, and other endpoints\n\n#### Agent Pipelines Service\nThe project includes an `agent-pipelines` service in Docker Compose that:\n- Runs as a FastAPI application on port 9299\n- Provides OpenAI-compatible API endpoints\n- Includes Swagger documentation at http://localhost:9299/docs\n- Main endpoint: `/v1/chat/completions` for chat interactions\n- Integrates with Langfuse for observability\n- Connects to Open WebUI for a seamless chat interface\n\n\n![img_2.png](docs/img_2.png)\n\n![img_3.png](docs/img_3.png)\n\n### 3. Agent Architecture\nAgents are implemented using:\n- **LangGraph** with ReAct pattern as the primary framework\n- **AutoGen** as an alternative agent framework\n\n#### Simple ReAct Agent Architecture as First Step (LangGraph)\nThe ReAct (Reasoning and Acting) agent follows this workflow:\n\n```\n┌─────────────────┐\n│   User Input    │\n└────────┬────────┘\n         │\n         ▼\n┌─────────────────┐\n│   LLM Reasoning │◄──────┐\n└────────┬────────┘       │\n         │                │\n         ▼                │\n┌─────────────────┐       │\n│ Tool Selection? │       │\n└────┬──────┬─────┘       │\n     │      │             │\n  No │      │ Yes         │\n     │      │             │\n     ▼      ▼             │\n┌────────┐ ┌─────────────┐│\n│Response│ │Tool Execution││\n└────────┘ └──────┬───────┘│\n              │            │\n              └────────────┘\n```\n\nThe agent:\n1. Receives user input\n2. Uses LLM to reason about the task\n3. Decides whether to use tools or respond\n4. If tools are needed, executes them\n5. Adds results back to context\n6. Loops until task completion\n\n### 4. Tool Infrastructure\nTools are accessible through:\n- **LangChain** tooling ecosystem for LangGraph agents\n- **AutoGen adapter** ([autogen_ext.tools.langchain](https://microsoft.github.io/autogen/stable//reference/python/autogen_ext.tools.langchain.html#module-autogen_ext.tools.langchain)) for AutoGen agents\n\nThis allows seamless tool integration across both agent frameworks.\n\n#### 4.1 Tool Implementation Pattern\nEach tool follows a three-step pattern:\n1. **Pre-process**: LLM-based input (tool call) preparation and validation\n2. **API Request**: Calls to [Finmars Portfolio API](https://api-docs.finmars.com/portfolio.html)\n3. **Post-process**: Format results into LLM-optimized strings\n\n#### 4.2 Pydantic Models Architecture\nThe project uses two distinct types of Pydantic models:\n\n##### API Payload Models (`libs/schema/`)\n- **Purpose**: Define the exact structure for API requests/responses\n- **Location**: `libs/schema/` directory\n- **Characteristics**:\n  - Auto-generated from OpenAPI specification using `datamodel-codegen`\n  - Strict validation constraints (string lengths, numeric ranges, formats)\n  - Optional fields for flexible API operations\n  - View models for read operations\n  - Light models for minimal representations\n- **Examples**: `Portfolio`, `PortfolioType`, `PortfolioHistory`, `GenericAttribute`\n\nThe main schema files include:\n- `base.py` - Base enums and types (SourceTypeEnum, StatusEnum, etc.)\n- `responses.py` - Paginated response models for API endpoints\n- `via_data_model_codegen/portfolio_schema.py` - Auto-generated models from OpenAPI spec\n\n##### Tool-Calling Input Schemas\n- **Purpose**: Define input structures for LLM tool calls\n- **Characteristics**:\n  - Simplified schemas focused on LLM-friendly inputs\n  - May have different field names and structures than API models\n  - Related but not inherited from API models\n  - Optimized for natural language understanding\n  - Flexible validation for conversational inputs\n- **Relationship**: These schemas act as adapters between LLM-generated parameters and API payload models\n\nThis separation allows for:\n- LLM-optimized tool interfaces without API constraints\n- Independent evolution of tool calling schemas\n- Clear boundary between AI interaction layer and API layer\n\n#### 4.3 Future Extensions\n- MCP Server implementation for comprehensive tool sharing capabilities\n\n### 5. Observability - Langfuse (Optional)\n[Langfuse](https://github.com/langfuse/langfuse) provides comprehensive observability when configured:\n- **Trace Tracking**: Monitor all agent execution steps\n- **Prompt Management**: Version control and collaborative iteration on prompts\n- **Evaluations**: LLM-as-a-judge and custom evaluation pipelines\n- **Datasets**: Test sets and benchmarks for continuous improvement\n- **LLM Playground**: Testing and iteration environment\n\n**Note**: Langfuse integration is now optional. The system will automatically detect if Langfuse environment variables are configured and enable observability features accordingly\n\n#### Langfuse Integration Details (When Configured)\n\nThe project integrates Langfuse at multiple levels when the required environment variables are set:\n\n1. **Prompt Management (`libs/utils/langfuse_manager.py`)**:\n   - Automatic prompt versioning with labels\n   - Prompt creation if not found in Langfuse\n   - Message format mapping between LangChain and Langfuse\n   - Centralized prompt retrieval for consistency\n\n2. **Agent Tracing** (when Langfuse is configured):\n   - All agent executions are automatically traced\n   - Metadata support (user_id, session_id, tags)\n   - Tool call tracking and performance monitoring\n   - Error tracking and debugging capabilities\n   - Automatically disabled if Langfuse environment variables are not set\n\n3. **Docker Compose Deployment Options**:\n   - **docker-compose-core.yaml**: Minimal setup with just Open WebUI and Agent Pipelines\n   - **docker-compose.yaml**: Full stack including Langfuse observability:\n     - PostgreSQL for data persistence\n     - ClickHouse for analytics\n     - MinIO for object storage\n     - Redis for caching\n\n4. **Usage in Code**:\n   ```python\n   from libs.utils.langfuse_callback import get_langfuse_callbacks\n   \n   # Automatically detects if Langfuse is configured\n   callbacks = get_langfuse_callbacks()\n   \n   # Use with agent - callbacks will be empty list if Langfuse not configured\n   response = await agent.ainvoke(\n       {\\\"messages\\\": [HumanMessage(content=\\\"Your query\\\")]},\n       config={\\\"callbacks\\\": callbacks}\n   )\n   ```\n   \n   The system automatically checks for Langfuse environment variables and only enables callbacks when properly configured\n\n### 5.1. Prompt Management System\n\nThe project supports flexible prompt management with the ability to load prompts from either local code or Langfuse:\n\n#### Prompt Suggestions System\n\nThe project includes a pre-configured prompt suggestions system (`libs/openwebui_utils/prompt-suggestions.json`) that enhances the user experience in Open WebUI with intelligent query recommendations:\n\n**Example Prompts**:\n- \"What companies are in portfolio XYZ?\"\n- \"Show me the P\u0026L for portfolio ABC\"\n- \"List all transactions in the last month\"\n- \"What's the current allocation of portfolio DEF?\"\n- \"Check if there are any short positions\"\n\nThese prompts are automatically suggested to users in the Open WebUI interface, making it easier to discover agent capabilities.\n\n#### Configuration Options\n\n1. **Environment Variable** (Recommended):\n   ```bash\n   # Use prompts from local code (default)\n   export PROMPT_SOURCE=code\n   \n   # Use prompts from Langfuse\n   export PROMPT_SOURCE=langfuse\n   ```\n\n2. **Programmatic Usage**:\n   ```python\n   from libs.utils.langfuse_manager import PromptSource\n   from agents.runner import run_agent\n   \n   # Use local prompts\n   response = await run_agent(messages, prompt_source=PromptSource.CODE)\n   \n   # Use Langfuse prompts\n   response = await run_agent(messages, prompt_source=PromptSource.LANGFUSE)\n   ```\n\n#### Benefits\n\n- **Development Flexibility**: Use local prompts during development for rapid iteration\n- **Production Control**: Manage prompts in Langfuse for A/B testing and versioning\n- **Zero Code Changes**: Switch between sources using environment variables\n- **Automatic Sync**: If a prompt doesn't exist in Langfuse, it's automatically created from code\n\n## Current Implementation Status\n\n### ✅ Phase 1: Core Infrastructure (Completed)\n- **Finmars API Client Library** - Fully async Python client with type safety\n- **Schema Generation** - Auto-generated Pydantic models from OpenAPI specification\n- **CLI Interface** - Command-line tools for API interaction and testing\n- **Comprehensive Testing** - Test suite for all client components\n\n### ✅ Phase 2: Agent Implementation (Completed)\n- **ReAct Agent** implemented using LangGraph with full reasoning and tool-calling capabilities\n- **Langfuse Integration** for prompt management and observability\n- **8 Comprehensive Toolkits** for portfolio operations and reporting\n- **Async Runner** with metadata support for tracing\n\n```bash\n# Simple Fast Run the ReAct agent\npython agents/react_agent/runner.py\n```\n\n### ✅ Phase 3: Observability Setup (Completed)\n- **Langfuse** fully integrated with Docker Compose deployment\n- **Prompt Management** system with versioning and automatic prompt creation\n- **Trace Tracking** enabled for all agent executions\n- **Callback Handlers** integrated into the ReAct agent\n\n### ✅ Phase 4: Pipeline Integration (Completed)\n- **Agent Pipelines Service** deployed as FastAPI application with OpenAI-compatible API\n- **Pipeline endpoints** configured at `/v1/chat/completions`\n- **Swagger documentation** available at http://localhost:9299/docs\n- **Integration with Langfuse** for observability and tracing\n- **Full compatibility** with OpenAI SDK and LangChain\n\n### ✅ Phase 5: UI Deployment (Completed)\n- **Open WebUI** deployed with Docker Compose on port 8881\n- **Agent Pipelines** connected to chat interface\n- **Chat-based interactions** fully functional with streaming support\n- **Prompt Suggestions System** with pre-configured queries for common tasks\n- **Enhanced user experience** with intelligent prompt recommendations\n\n## Tools Implementation\n\nThe project includes 8 comprehensive toolkits that provide the ReAct agent with full access to Finmars Portfolio API and reporting capabilities:\n\n### 1. Portfolio Toolkit (`tools/portfolio_toolkit.py`)\n- **list_portfolios**: Search and filter portfolios with pagination\n- **get_portfolio**: Retrieve detailed portfolio information\n- **list_portfolios_light**: Get minimal portfolio representations\n- **list_portfolio_attributes**: Access portfolio custom attributes\n- **get_inception_date**: Retrieve portfolio inception dates\n- **list_first_transaction_dates**: Get first transaction dates by portfolio type\n\n### 2. Portfolio Type Toolkit (`tools/portfolio_type_toolkit.py`)\n- **list_portfolio_types**: Browse available portfolio types\n- **get_portfolio_type**: Get detailed portfolio type configuration\n- **list_portfolio_types_light**: Minimal portfolio type listings\n- **list_portfolio_attribute_types**: Discover available attribute types\n- **get_portfolio_type_attributes**: Get type-specific attribute definitions\n\n### 3. Portfolio Register Toolkit (`tools/portfolio_register_toolkit.py`)\n- **list_portfolio_registers**: Browse portfolio registers\n- **get_portfolio_register**: Access specific register details\n- **list_portfolio_register_records**: Query register records with filtering\n- **get_portfolio_register_record**: Retrieve individual record details\n\n### 4. Portfolio History Toolkit (`tools/portfolio_history_toolkit.py`)\n- **list_portfolio_history**: Access historical portfolio data\n- **get_portfolio_history**: Retrieve specific history records\n\n### 5. Portfolio Reconcile Toolkit (`tools/portfolio_reconcile_toolkit.py`)\n- **list_portfolio_reconcile_groups**: Browse reconciliation groups\n- **get_portfolio_reconcile_group**: Access group configurations\n- **list_portfolio_reconcile_history**: Query reconciliation history\n- **list_portfolio_reconcile_status**: Check current reconciliation status\n\n### 6. Balance Report Toolkit (`tools/balance_report_toolkit.py`)\n- **get_balance_report**: Retrieve portfolio holdings and positions\n- **analyze_allocations**: Get asset allocation and exposure analysis\n- **get_market_values**: Calculate current market values and weights\n- **get_bond_metrics**: Access YTM, duration, and other bond analytics\n- **check_short_positions**: Identify and analyze short positions\n\n### 7. P\u0026L Report Toolkit (`tools/pl_report_toolkit.py`)\n- **get_pl_report**: Comprehensive profit \u0026 loss analysis\n- **analyze_performance**: Calculate returns and performance metrics\n- **get_realized_gains**: Track realized gains and losses\n- **get_unrealized_gains**: Monitor unrealized P\u0026L positions\n- **calculate_carry_pl**: Analyze carry and overhead components\n\n### 8. Transaction Report Toolkit (`tools/transaction_report_toolkit.py`)\n- **list_transactions**: Query transaction history with filters\n- **get_transaction_details**: Retrieve specific transaction information\n- **export_transactions**: Export transaction data for analysis\n- **analyze_trading_activity**: Summary of buy/sell activities\n- **get_recent_transactions**: Quick access to latest transactions\n\n### Tool Architecture\nEach toolkit follows a consistent implementation pattern:\n- **LLM-Optimized Input Schemas**: Separate from API models for better agent interaction\n- **Async Operations**: All tools use async/await for efficient execution\n- **Structured Output**: JSON-formatted responses for agent consumption\n- **Error Handling**: Graceful error management with informative messages\n\n## Getting Started\n\n### Prerequisites\n- Python 3.12+\n- Docker and Docker Compose\n- API access to Finmars Portfolio service\n- OpenAI API key (or compatible LLM provider)\n\n### Installation\n```bash\n# Clone the repository\ngit clone remote-repo-address/finmars-ai-assistant.git\ncd finmars-ai-assistant\n\n# Install dependencies\npip install -r requirements.txt\n\n# Set up environment variables\ncp .env.example .env\n# Edit .env with your API keys and configuration\n```\n\n### Configuration\n\n#### Required Environment Variables\n```bash\n# Finmars API Configuration\nexport FINMARS_EXPERT_TOKEN='your-api-token'\nexport FINMARS_BASE_URL='https://api.finmars.com'\nexport FINMARS_REALM='your-realm'\nexport FINMARS_SPACE='your-space'\n\n# LLM Provider (OpenAI or compatible)\nexport OPENAI_API_KEY='your-openai-key'\nexport OPENAI_BASE_URL='https://api.openai.com/v1'  # Optional, for custom endpoints\n\n# Langfuse Observability (optional)\n# If these variables are not set, the system will run without Langfuse integration\nexport LANGFUSE_PUBLIC_KEY='your-public-key'  # Optional\nexport LANGFUSE_SECRET_KEY='your-secret-key'  # Optional\nexport LANGFUSE_HOST='http://localhost:3000'  # Optional, or your Langfuse URL\n\n# Prompt Source Configuration\n# Options: \"code\" (use local prompts) or \"langfuse\" (use Langfuse prompts)\n# Default: \"code\"\nexport PROMPT_SOURCE='code'\n\n# Open WebUI Pipelines (for future integration)\nexport PIPELINES_API_KEY='your-pipelines-key'\n```\n\n### Docker Compose Setup\n\nThe project includes two Docker Compose configurations:\n\n#### Option 1: Core Services Only (without Langfuse)\n```bash\n# Start core services only (Open WebUI, Agent Pipelines)\ndocker-compose -f docker-compose-core.yaml up -d\n```\n\n#### Option 2: Full Stack with Observability (with Langfuse)\n```bash\n# Start all services including Langfuse observability stack\ndocker-compose up -d\n\n# Check service status\ndocker-compose ps\n\n# View logs\ndocker-compose logs -f\n\n# Stop all services\ndocker-compose down\n```\n\n#### Available Services:\n\n**Core Services (always available):**\n- **Open WebUI**: http://localhost:8881 - Chat interface for interacting with agents\n- **Agent Pipelines**: http://localhost:9299 - FastAPI service providing OpenAI-compatible API\n  - Swagger docs: http://localhost:9299/docs\n  - Chat completions endpoint to make requests to Finmars Agent: `/v1/chat/completions`\n\n**Observability Services (with full docker-compose.yaml only):**\n- **Langfuse**: http://localhost:3000 - Observability and prompt management\n- **PostgreSQL**: Port 5432 - Database for Langfuse\n- **ClickHouse**: Port 8123 - Analytics database for Langfuse\n- **MinIO**: Port 9001 - Object storage for Langfuse\n- **Redis**: Port 6379 - Caching layer\n\n### Quick Start\n\nFor detailed development setup instructions, see [SETUP_DEVELOPMENT.md](SETUP_DEVELOPMENT.md).\n\n1. **Set up environment**:\n   ```bash\n   cp .env.example .env\n   # Edit .env with your credentials\n   ```\n\n2. **Start Docker services**:\n   ```bash\n   # Option A: Core services only (without Langfuse)\n   docker-compose -f docker-compose-core.yaml up -d\n   \n   # Option B: Full stack with Langfuse observability\n   docker-compose up -d\n   ```\n\n3. **Run the ReAct agent**:\n   ```bash\n   python agents/react_agent/runner.py\n   ```\n\n4. **Use the CLI for direct API access**:\n   ```bash\n   python cli/main.py list-portfolios --page 1 --page-size 10\n   ```\n\n5. **Interact with agent via LangChain API** (OpenAI-compatible):\n   ```bash\n   python scripts/interact_to_agent_via_api.py\n   ```\n\n## Project Structure\n```\nfinmars-ai-assistant/\n├── README.md\n├── docker-compose.yaml              # Full stack with Langfuse observability\n├── docker-compose-core.yaml         # Core services only (without Langfuse)\n├── .env.example                     # Environment variables template\n├── requirements.txt                 # Python dependencies\n├── libs/\n│   ├── client/                      # Finmars API Client Library\n│   │   ├── __init__.py              # Client exports\n│   │   ├── base.py                  # Base HTTP client with async support\n│   │   ├── finmars_client.py        # Main client aggregating all sub-clients\n│   │   ├── portfolio.py             # Portfolio operations client\n│   │   ├── portfolio_type.py        # Portfolio type operations client\n│   │   ├── portfolio_register.py    # Portfolio register operations client\n│   │   ├── portfolio_history.py     # Portfolio history operations client\n│   │   ├── portfolio_reconcile.py   # Portfolio reconciliation client\n│   │   ├── balance_report.py        # Balance report client\n│   │   ├── pl_report.py             # P\u0026L report client\n│   │   ├── transaction_report.py    # Transaction report client\n│   │   ├── price_history_check.py   # Price history validation client\n│   │   └── tests/                   # Test suite for client library\n│   │       ├── test_base.py         # Base client tests\n│   │       ├── test_finmars_client.py # Main client tests\n│   │       ├── test_portfolio.py    # Portfolio client tests\n│   │       └── test_portfolio_type.py # Portfolio type tests\n│   ├── openapi/\n│   │   ├── portfolio/\n│   │   │   ├── openapi.json         # Local portfolio API specification\n│   │   │   └── openapi_remote.json  # Remote portfolio API specification\n│   │   └── report/\n│   │       └── openapi_v3.json      # Report API specification\n│   ├── openwebui_utils/             # Open WebUI integration utilities\n│   │   └── prompt-suggestions.json  # Pre-configured prompt suggestions\n│   ├── schema/                      # Pydantic models for API payloads\n│   │   ├── __init__.py              # Schema exports\n│   │   ├── base.py                  # Base enums and common types\n│   │   ├── responses.py             # Paginated response models\n│   │   ├── README.md                # Schema generation documentation\n│   │   └── via_data_model_codegen/  # Auto-generated models\n│   │       ├── __init__.py          # Generated schema exports\n│   │       ├── portfolio_schema.py  # Complete portfolio API models\n│   │       └── report_schema.py     # Complete report API models\n│   ├── basic/                       # Basic utilities\n│   │   └── base_enum.py             # Base enum with string representation\n│   ├── logger/                      # Logging configuration\n│   │   └── logger.py                # Custom logger setup\n│   └── utils/                       # Utility modules\n│       ├── key_manager.py           # API key management\n│       ├── langfuse_manager.py      # Langfuse prompt management\n│       ├── langfuse_callback.py     # Optional Langfuse callback handler\n│       └── prompt_map_builder.py    # Prompt configuration builder\n├── cli/                             # Command-line interface\n│   ├── __init__.py                  # CLI exports\n│   ├── main.py                      # Main CLI application\n│   ├── examples.py                  # Usage examples and demos\n│   └── README.md                    # CLI documentation\n├── agents/                          # Agent implementations\n│   └── react_agent/                 # ReAct agent using LangGraph\n│       ├── __init__.py              # Agent exports\n│       ├── agent_react_builder.py   # ReAct agent builder with Langfuse\n│       ├── runner.py                # Async agent runner with tracing\n│       └── system_prompt.py         # System prompt configuration\n├── tools/                           # Tool implementations with LangChain\n│   ├── __init__.py                  # Tool exports and registry\n│   ├── portfolio_toolkit.py         # Portfolio management tools\n│   ├── portfolio_type_toolkit.py    # Portfolio type tools\n│   ├── portfolio_register_toolkit.py # Portfolio register tools\n│   ├── portfolio_history_toolkit.py # Portfolio history tools\n│   ├── portfolio_reconcile_toolkit.py # Portfolio reconciliation tools\n│   ├── balance_report_toolkit.py   # Balance and holdings report tools\n│   ├── pl_report_toolkit.py        # P\u0026L analysis and performance tools\n│   └── transaction_report_toolkit.py # Transaction history tools\n├── pipelines/                       # Open WebUI pipeline modules\n│   └── finmars-ai-assistant.py     # Main pipeline implementation\n├── utils/                           # Utility modules\n│   ├── __init__.py                  # Utils exports  \n│   ├── agent_utils/                 # Agent utility functions\n│   │   ├── __init__.py              # Agent utils exports\n│   │   ├── async_loop_to_sync.py   # Async to sync converter\n│   │   └── lc_converter.py         # LangChain converter utilities\n│   └── pipelines/                   # Pipeline utility modules\n│       ├── __init__.py              # Pipeline utils exports\n│       ├── auth.py                  # Authentication utilities\n│       ├── main.py                  # Main pipeline utilities\n│       └── misc.py                  # Miscellaneous utilities\n├── scripts/                         # Utility scripts and examples\n│   ├── __init__.py                  # Scripts exports\n│   ├── interact_to_agent_via_api.py # Interactive API client\n│   ├── test_single_query.py        # Single query testing\n│   ├── GENERATE_QUERIE.md          # Query generation guide\n│   ├── TO_UPDATE_AGENT_QUERIES_AND_RESULTS.md # Update guide\n│   ├── helper_agent_task_prompt.md # Agent task prompts\n│   └── examples_of_queries/        # Query examples\n│       ├── AGENT_QUERIES_AND_RESULTS.md # Agent query examples\n│       └── PL_TOOLKIT_QUERIES.md   # P\u0026L toolkit queries\n├── docs/                            # Documentation assets\n│   ├── img.png                      # Architecture diagrams\n│   ├── img_1.png                    # UI screenshots\n│   ├── img_2.png                    # Pipeline screenshots\n│   └── img_3.png                    # Additional visuals\n└── SETUP_DEVELOPMENT.md             # Development environment setup guide\n```\n\n## Finmars API Client Library\n\n### Overview\nThe `libs/client/` directory contains a fully async Python client library for interacting with the Finmars Portfolio API. The client is organized into logical sub-clients based on business domains.\n\n### Features\n- **Async/await support** for all API operations\n- **Type-safe** with Pydantic model validation\n- **Organized by business logic** into specialized sub-clients\n- **Comprehensive test coverage** with mocked HTTP requests\n- **Built-in authentication** with API key support\n- **Configurable timeouts** and error handling\n- **Environment variable integration** for configuration\n\n### Usage Example\n\n```python\nimport asyncio\nfrom libs.client import FinmarsPortfolioClient\n\nasync def main():\n    # Initialize the client (loads from environment variables)\n    client = FinmarsPortfolioClient(\n        base_url=\"https://api.finmars.com\",\n        realm=\"your-realm\",\n        space=\"your-space\",\n        # api_key automatically loaded from FINMARS_EXPERT_TOKEN\n    )\n    \n    # List portfolios with pagination\n    portfolios = await client.portfolios.list_portfolios(page=1, page_size=10)\n    print(f\"Found {portfolios.count} portfolios\")\n    \n    # Get specific portfolio\n    portfolio = await client.portfolios.get_portfolio(portfolio_id=1)\n    print(f\"Portfolio: {portfolio.name}\")\n    \n    # List portfolio types\n    portfolio_types = await client.portfolio_types.list_portfolio_types()\n    \n    # Get portfolio history\n    history = await client.portfolio_history.list_portfolio_history()\n    \n    # Access reconciliation data\n    reconcile_groups = await client.portfolio_reconcile.list_portfolio_reconcile_groups()\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### Client Structure\n\nThe main `FinmarsPortfolioClient` aggregates the following sub-clients:\n\n1. **portfolios** (`PortfolioClient`) - Portfolio operations\n   - `list_portfolios()` - List all portfolios with pagination\n   - `get_portfolio()` - Get specific portfolio by ID\n   - `list_portfolios_light()` - List portfolios in minimal format\n   - `list_portfolio_attributes()` - Get portfolio attributes\n   - `get_inception_date()` - Get portfolio inception dates\n   - `list_first_transaction_dates()` - Get first transaction dates\n\n2. **portfolio_types** (`PortfolioTypeClient`) - Portfolio type management\n   - `list_portfolio_types()` - List all portfolio types\n   - `get_portfolio_type()` - Get specific portfolio type by ID\n   - `list_portfolio_types_light()` - List types in minimal format\n   - `list_portfolio_attribute_types()` - Get portfolio attribute types\n   - `get_portfolio_type_attributes()` - Get type-specific attributes\n\n3. **portfolio_registers** (`PortfolioRegisterClient`) - Portfolio register operations\n   - `list_portfolio_registers()` - List all portfolio registers\n   - `get_portfolio_register()` - Get specific register by ID\n   - `list_portfolio_register_records()` - List register records\n   - `get_portfolio_register_record()` - Get specific record\n\n4. **portfolio_history** (`PortfolioHistoryClient`) - Historical portfolio data\n   - `list_portfolio_history()` - List portfolio history records\n   - `get_portfolio_history()` - Get specific history record\n\n5. **portfolio_reconcile** (`PortfolioReconcileClient`) - Reconciliation operations\n   - `list_portfolio_reconcile_groups()` - List reconcile groups\n   - `get_portfolio_reconcile_group()` - Get specific group\n   - `list_portfolio_reconcile_history()` - List reconcile history\n   - `list_portfolio_reconcile_status()` - Get reconciliation status\n\n6. **balance_report** (`BalanceReportClient`) - Portfolio balance and holdings reports\n   - `get_balance_report()` - Retrieve detailed portfolio holdings\n   - `get_allocations()` - Asset allocation breakdowns\n   - `get_exposures()` - Market exposure analysis\n   - `get_bond_analytics()` - Bond-specific metrics (YTM, duration)\n\n7. **pl_report** (`PLReportClient`) - Profit \u0026 loss performance reports\n   - `get_pl_report()` - Comprehensive P\u0026L analysis\n   - `get_performance_metrics()` - Return calculations and attribution\n   - `get_realized_pl()` - Realized gains and losses\n   - `get_unrealized_pl()` - Mark-to-market valuations\n\n8. **transaction_report** (`TransactionReportClient`) - Transaction history and details\n   - `list_transactions()` - Query transaction history\n   - `get_transaction_summary()` - Aggregated transaction statistics\n   - `export_transactions()` - Export functionality\n\n9. **price_history_check** (`PriceHistoryCheckClient`) - Price data validation\n   - `check_price_availability()` - Validate price data completeness\n   - `get_missing_prices()` - Identify gaps in price history\n   - `get_price_diagnostics()` - Price quality and consistency checks\n\n### Schema Models\n\nThe schema system uses auto-generated Pydantic models from the OpenAPI specification:\n\n#### Key Models\n- **Portfolio** - Full portfolio model with all fields\n- **PortfolioLight** - Minimal portfolio representation\n- **PortfolioType** - Portfolio type with configuration\n- **PortfolioHistory** - Historical portfolio data\n- **GenericAttribute** - Flexible attribute system\n- **PortfolioReconcileGroup** - Reconciliation group configuration\n\n#### Response Models\n- **PaginatedResponse** - Base pagination model\n- **PortfolioListResponse** - Paginated portfolio lists\n- **PortfolioTypeListResponse** - Paginated portfolio type lists\n- **GenericAttributeTypeListResponse** - Paginated attribute type lists\n\n### Testing\n\nThe client library includes comprehensive test coverage:\n\n```bash\n# Install test dependencies\npip install pytest pytest-asyncio httpx\n\n# Run all tests\npytest libs/client/tests/\n\n# Run specific test file\npytest libs/client/tests/test_portfolio.py\n\n# Run with coverage\npytest libs/client/tests/ --cov=libs/client\n```\n\n## Agent Usage Examples\n\n### Running the ReAct Agent\n\nThe ReAct agent provides an interactive way to query and analyze portfolio data:\n\n```python\n# Basic usage\npython agents/react_agent/runner.py\n\n# Example queries you can ask:\n# - \"List all active portfolios\"\n# - \"Show me portfolios of type 'HEDGE_FUND'\"\n# - \"Get the inception date for portfolio ID 123\"\n# - \"What portfolio types are available?\"\n# - \"Show reconciliation status for all portfolios\"\n```\n\n### Programmatic Agent Usage\n\n```python\nimport asyncio\nfrom agents import create_finmars_agent_react\nfrom langchain_core.messages import HumanMessage\n\n\nasync def query_agent():\n    # Create the agent\n    agent = await create_finmars_agent_react()\n\n    # Ask a question\n    response = await agent.ainvoke({\n        \"messages\": [HumanMessage(content=\"List all portfolios with their types\")]\n    })\n\n    # Print the response\n    print(response[\"messages\"][-1].content)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(query_agent())\n```\n\n### Agent Capabilities\n\nThe agent can help with:\n- **Portfolio Discovery**: Search and filter portfolios by various criteria\n- **Portfolio Analysis**: Get detailed information about specific portfolios\n- **Type Management**: Explore portfolio types and their configurations\n- **Historical Data**: Access portfolio history and transaction dates\n- **Reconciliation**: Check reconciliation status and groups\n- **Attribute Management**: Query portfolio and type-specific attributes\n\n### Interacting with Agent via LangChain API\n\nThe project includes a script that demonstrates how to interact with the agent using LangChain's ChatOpenAI interface, which is compatible with the OpenAI API:\n\n```python\n# Run the interactive chat client\npython scripts/interact_to_agent_via_api.py\n```\n\nThis script provides:\n- **Interactive Chat Interface**: Continuous conversation with the agent\n- **Streaming Support**: Real-time response streaming for better UX\n- **Automatic Retry Logic**: Retries failed requests up to 3 times\n- **Simple API Integration**: Uses standard LangChain ChatOpenAI client\n\nExample usage:\n```python\nfrom langchain_openai import ChatOpenAI\nfrom langchain_core.messages import HumanMessage\n\n# Initialize client with custom endpoint\nchat = ChatOpenAI(\n    base_url=\"http://localhost:9199/v1\",\n    api_key=\"test\",\n    model=\"finmars-ai-assistant\"\n)\n\n# Send a message\nresponse = chat.invoke([\n    HumanMessage(content=\"List all active portfolios\")\n])\nprint(response.content)\n```\n\nThis demonstrates how any OpenAI-compatible client can interact with the Finmars agent by simply changing the `base_url`.\n\n## Command Line Interface\n\nThe CLI provides direct access to the Finmars Portfolio API:\n\n### Basic Usage\n```bash\n# List portfolios\npython cli/main.py list-portfolios --page 1 --page-size 10\n\n# Get specific portfolio\npython cli/main.py get-portfolio --id 123\n\n# List portfolio types\npython cli/main.py list-portfolio-types\n\n# Run examples\npython cli/examples.py\n```\n\nSee [CLI README](cli/README.md) for complete documentation.\n\n## Schema Generation\n\nThe project uses `datamodel-codegen` to automatically generate Pydantic models from the OpenAPI specifications:\n\n### Portfolio Schema Generation\n```bash\ndatamodel-codegen \\\n  --input ./libs/openapi/portfolio/openapi.json \\\n  --input-file-type openapi \\\n  --output ./libs/schema/via_data_model_codegen/portfolio_schema.py \\\n  --target-python-version 3.12 \\\n  --output-model-type pydantic_v2.BaseModel\n```\n\n### Report Schema Generation\n```bash\ndatamodel-codegen \\\n  --input ./libs/openapi/report/openapi_v3.json \\\n  --input-file-type openapi \\\n  --output ./libs/schema/via_data_model_codegen/report_schema.py \\\n  --target-python-version 3.12 \\\n  --output-model-type pydantic_v2.BaseModel\n```\n\nThis ensures type safety and automatic updates when the API specification changes. The generated schemas include:\n- **Portfolio Models**: `Portfolio`, `PortfolioType`, `PortfolioHistory`, `GenericAttribute`\n- **Report Models**: `PLReportItems`, `BalanceReportItems`, `TransactionReportItems`, `PriceHistoryCheckItems`\n- **Entities**: `ReportInstrument`, `ReportPortfolio`, `ReportAccount`, `ReportTransaction`\n\n## Contributing\nPlease read our contributing guidelines before submitting pull requests.\n\n## License\n[Specify your license here]","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffinmars-platform%2Ffinmars-ai-assistant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffinmars-platform%2Ffinmars-ai-assistant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffinmars-platform%2Ffinmars-ai-assistant/lists"}