AI Agent Chat
Software Engineer/Developer: Manuel Solalinde (manolosolalinde@gmail.com)
A full-stack conversational AI agent that lets reservoir, production, and operations staff ask natural-language questions about the company's wells and get grounded, tool-backed answers. The agent reasons over the corporate well database, searches internal documentation, browses the web, and runs Python in a sandbox — streaming each step (tool calls, intermediate results, and the final answer) back to the user in real time. It is built on Amazon Bedrock AgentCore and was forked and substantially extended from AWS Labs' fullstack AgentCore solution template (FAST).
Overview
A user opens the chat, asks a question in plain English (e.g. "find all wells spud in 2026" or "when was the last time the bumper spring was pulled on this well?"), and the agent decides which tools to call to answer it. The model writes and runs read-only SQL against the corporate well-data warehouse, looks up table/column documentation, retrieves internal datadocs, searches the web, or executes Python — then synthesizes a cited answer. Conversations are persisted with searchable history, auto-generated titles, and per-message feedback, so the tool behaves like an internal ChatGPT scoped to the company's own operational data.
Applications
- Natural-language data access — engineers query well headers, production, directional surveys, stimulation stages, and more without writing SQL themselves; the agent translates intent into validated read-only queries and explains its results.
- Operational Q&A — answers grounded questions about specific wells, pads, and JV/GU units, citing the rows and documents it used.
- Internal knowledge retrieval — hybrid (embedding + keyword) search over the company's internal documentation index, with full-document fetch.
- Web research & code analysis — on-demand web search/fetch and a secure Python sandbox for ad-hoc computation, all inside the same conversation.
Architecture
A containerized, cloud-native stack on AWS, provisioned entirely as code with Pulumi (Python):
- Frontend — a React 19 + TypeScript single-page app (Vite, Tailwind CSS 4, shadcn/ui) served by Nginx on ECS Fargate behind an Application Load Balancer. A custom AgentCore streaming client parses Server-Sent Events to render tool calls, inputs, and results live as the agent works.
- Backend API — a FastAPI service handling conversations, feedback, dynamic runtime config, and the agent proxy.
- Agent Runtime — a containerized agent on Bedrock AgentCore Runtime (model: Claude Sonnet 4.5). The codebase ships four interchangeable agent patterns — Strands Agents (primary), LangGraph, and the Claude Agent SDK in both single- and multi-agent (Opus-orchestrates-Sonnet) configurations — selectable without touching the rest of the stack.
- Tools via Gateway — Lambda-backed tools exposed over the AgentCore Gateway (MCP protocol): read-only SQL execution against the corporate well database, well-database table/column documentation lookup, internal datadocs hybrid search and retrieval, web search and page extraction, plus a Bedrock Code Interpreter sandbox.
- Memory — AgentCore Memory provides session-scoped, persistent conversation history.
- Data — DynamoDB stores conversations and feedback; SSM Parameter Store holds runtime ARNs and config.
Design decisions & trade-offs
- Four interchangeable agent patterns — Strands Agents, LangGraph, and the Claude Agent SDK in single- and multi-agent configurations are selectable without touching the rest of the stack, future-proofing the system against framework and model changes.
- Read-only SQL execution — a deliberate safety decision: the agent can query the corporate well data but can never mutate it, preventing accidental data changes.
- Separated user vs. machine-to-machine auth — keeping the two identity types distinct prevents user credentials from crossing the service boundary.
- Lambda-backed tools over the AgentCore Gateway (MCP) — exposing tools through the Gateway decouples the agent runtime from tool implementations, so tools can evolve independently of the agent.
Hard problems solved
- Live streaming of agent reasoning — Server-Sent Events stream tool calls, inputs, intermediate results, and the final answer so they render live as the agent reasons, giving users visibility into multi-step reasoning instead of an opaque wait.
- Hybrid internal-doc search — combined embedding and keyword search over internal documentation, with full-document fetch, to surface the most relevant grounding material.
- Deploy-free local development — a local mode mocks authentication (no OIDC popup) and sources AWS credentials from the host profile, so the full chat flow runs end-to-end without deploying.
Authentication
The design keeps user identity and machine-to-machine identity fully separated:
- User auth — users sign in through Microsoft Entra ID (OIDC), and a validated token authorizes downstream services on the user's behalf.
- Machine-to-machine — services authenticate to one another with Cognito OAuth2 client-credentials, managed by AgentCore Identity. Because the two identity types are separate, user credentials never cross the service boundary.
CI/CD & Local Development
- Two deployment paths — infrastructure, frontend, backend, and Gateway tools deploy via Pulumi (
pulumi up), while agent code (system prompt, model, agent logic) deploys independently through the AgentCore CLI (agentcore deploy) which builds the agent container via CodeBuild. - Local environment — a
docker composestack runs the frontend, backend API, and agent together on a developer machine. A local-agent mode mocks authentication (no OIDC popup) and sources AWS credentials from the host profile, so the full chat flow can be exercised without deploying.
Note: Screenshots and internal application URLs are omitted, as they display proprietary client data. Available on request, subject to client approval.
