Skip to content

hud63/account-intelligence-agent

Repository files navigation

🔎 Account Intelligence Agent

A ReAct AI agent that answers natural-language questions about any account by searching across HubSpot, Gmail, and Google Docs in parallel, then delivers the unified brief straight into Slack, where the sales team already works.

Ask @bot what's the proposal status for Acme? in Slack; the agent plans a multi-source search, runs it, reviews what's missing, and replies with a synthesized answer plus its sources, confidence, and gaps.


The problem this solves

  • A sales team's account data lived in three disconnected systems (HubSpot, Gmail, a support portal) with nothing tying them together.
  • The team burned 15+ hours a week on manual lookups just to assemble basic context before a call.
  • As the sales lead put it: "my team spends more time looking things up than following up."
  • Adoption had to require zero behavior change, so the interface is a Slack mention and the engine is a ReAct agent.
  • The team went from three-system manual lookups to a single mention, and deal reviews now start from agent output instead of hand-assembled context.

Why ReAct (and not a fixed pipeline)

The problem wasn't just pulling data from three systems. It's that what you find in one system changes what you need to look for in the next. A HubSpot deal stage tells you which email thread matters; an email reference tells you which doc to read. A fixed query-per-source would miss those connections.

So the agent plans, executes, reviews, and synthesizes, adapting between passes:

   Slack mention / REST query
            │
            ▼
   ┌─────────────────┐     ┌──────────────────────────────┐
   │  Planner        │────▶│ Parallel tool execution      │
   │ (Bedrock/Nova)  │     │  - HubSpot (deals/contacts)  │
   └────────┬────────┘     │  - Gmail (threads)           │
            │ review pass  │  - Google Docs (proposals)   │
            │◀─────────────│  dependency-aware, concurrent│
            ▼              └──────────────────────────────┘
   ┌─────────────────┐
   │  Synthesize     │──▶ answer + sources + confidence + gaps  ──▶ Slack thread
   └─────────────────┘

What it does

  • Natural-language account queries from Slack or a REST API.
  • Parallel, dependency-aware tool execution across HubSpot, Gmail, and Google Docs; independent steps run concurrently and dependent steps wait on their inputs.
  • Self-review loop: after the first pass the agent identifies gaps and issues follow-up steps before answering.
  • Evidence quality gates: system-specific ranking (CRM prioritized over low-signal docs in a company-context query), email-anchor matching, and noise filtering.
  • Sync + async: light queries answer within the API Gateway window; heavy ones queue to a Lambda worker with results in S3, polled by a status endpoint.
  • Durable Slack dedup: event-id deduplication + worker-side session claiming prevent double-processing of Slack retries.

Architecture

Serverless, Lambda-first:

Slack Events / REST ──▶ API Gateway ──▶ Lambda (API handler)
                                          │  light -> answer inline
                                          │  heavy -> enqueue
                                          ▼
                                   SQS FIFO (+ DLQ)
                                          ▼
                                 Lambda (worker) ──▶ ReAct pipeline
                                          │              │
                                   S3 (async status)     ├─ HubSpot (MCP / HTTP)
                                   Secrets Manager        ├─ Gmail + Google Docs
                                   (all credentials)      └─ Bedrock (plan/review/synthesize)

Tech stack

Layer Tooling
Language Python 3.12
API FastAPI + Uvicorn
Compute AWS Lambda (API + worker) behind API Gateway
Queue SQS FIFO + dead-letter queue
Reasoning AWS Bedrock (Amazon Nova Pro)
Integrations HubSpot (MCP server / HTTP), Gmail, Google Docs, Slack
State S3 (async status), PostgreSQL/SQLAlchemy (execution trace, optional)
Secrets AWS Secrets Manager
IaC / build SAM (template.yaml), Docker to ECR via CodeBuild

Project structure

account-intelligence-agent/
├── src/react_hubspot_slack_agent/
│   ├── planner.py            # ReAct planner: initial plan + multi-pass review
│   ├── execution.py          # Parallel, dependency-aware execution engine
│   ├── hubspot_client.py     # HubSpot via MCP server or direct HTTP
│   ├── google_client.py      # Gmail + Google Docs, term-aware evidence ranking
│   ├── bedrock_client.py     # Plan / review / synthesize calls
│   ├── slack_client.py       # Outbound Slack posting
│   ├── slack_security.py     # Slack signature verification + dedup
│   ├── lambda_handlers.py    # Sync/async resolution, Slack event handling
│   ├── async_status_store.py # S3-backed async status
│   ├── session_store.py / execution_store.py / models.py   # persistence
│   └── main.py / service.py / worker.py / queue.py / config.py
├── template.yaml             # SAM: Lambda, SQS, API Gateway
├── Dockerfile / buildspec.yml
├── scripts/                  # PowerShell deploy + provisioning automation
├── tests/                    # planner-graph + evidence-priority + handler tests
└── docs/                     # architecture, runbooks, DEV_LOG.md

Key engineering decisions

  • Model-first ReAct planner. Bedrock plans the search, and the system adapts between passes rather than running a hardcoded query per source.
  • Parallel execution with a dependency graph. Independent lookups run concurrently; dependent ones key off prior step outputs, with cycle detection.
  • Async fallback for heavy queries. API Gateway's ~29s timeout forces a clean split: light queries answer inline, heavy ones go to a worker + S3 status, so Slack never times out.
  • Durable deduplication. Slack retries are deduped by event-id and worker-side session claiming, so a single mention is processed exactly once.
  • Evidence quality over recall. Per-source ranking and anchor matching keep CRM signal from being drowned out by low-signal document hits.

Run / deploy (outline)

# Local API
uv sync   # or: pip install -r requirements.txt
uvicorn react_hubspot_slack_agent.main:app --reload   # http://127.0.0.1:8000/health

# Deploy (SAM, Lambda-first), credentials sourced from AWS Secrets Manager
pwsh scripts/deploy_proto_lambda.ps1

Example query:

curl -X POST .../api/v1/query -d '{"query":"proposal status for acme company hubspot"}'
# returns { "session_id": "...", "status": "completed|queued",
#           "answer": "...", "sources": [...], "confidence": 0.0-1.0, "issues": [...] }

Note: Portfolio extract of a production system. All credentials live in AWS Secrets Manager and none are committed. AWS account IDs, API IDs, and resource IDs in the docs have been replaced with placeholders (<AWS_ACCOUNT_ID>, <API_ID>, <VPC_ID>). The deep development log is preserved at docs/DEV_LOG.md.

About

Serverless ReAct AI agent (AWS Lambda + Bedrock) that answers account questions across HubSpot, Gmail, and Google Docs and delivers unified briefs into Slack

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors