Agent Service Architecture (AgentCore)
Overview
AgentCore is a standalone, containerized, multi-agent AI service. It provides a pluggable runtime for deploying specialized, domain-specific AI agents within the OnRamp platform.
Architecture Components
1. Standalone Python Service (interactive-agent-service/)
A dedicated Python-native service handling:
- REST Endpoints with active Server-Sent Events (SSE) streaming capabilities.
- JWT Authentication and session state management.
- Shared Infrastructure including reusable model loading, MCP client integration, knowledge registries, and distributed session state management.
2. Multi-Agent Router
A top-level intent-classification agent built upon the Strands SDK. It evaluates incoming user prompts and dynamically routes or delegates control to the appropriate registered domain agent based on the prompt's intent.
Logical Handoff Pattern
AgentCore utilizes a Single Endpoint / Hub-and-Spoke Pattern for agent interactions. The UI only ever communicates with one physical AWS Bedrock Agent endpoint (the default router_Agent). Handoffs between domain agents (e.g., from router to playbooks) are pure logical state transitions managed entirely in Python by src/main.py.
sequenceDiagram
participant UI as Vue Frontend
participant Main as src/main.py (Endpoint)
participant Router as Global Router Agent
participant Domain as Domain Agent (e.g., Playbooks)
UI->>Main: Send prompt (e.g., "Build a playbook")
Note over Main: Session state:<br/>active_domain = "router"
Main->>Router: Forward prompt
Router-->>Main: Yield RouterDecision<br/>(action="route", target="playbooks")
Note over Main: Update session state:<br/>active_domain = "playbooks"
Main-->>UI: Emit event:<br/>{"type": "control", "action": "handoff"}
Note over UI: Intercepts event &<br/>auto-resends prompt
UI->>Main: Resend prompt
Note over Main: Session state:<br/>active_domain = "playbooks"
Main->>Domain: Forward prompt
Domain-->>Main: Generate content/tools
Main-->>UI: Stream response back to user3. Agent Registry & Manifest System
Provides a pluggable module system for creating domain agents. Each new domain agent is self-contained with its own:
manifest.py(Registry definitions, descriptions, and routing intent rules)state.py(Ephemeral and persistent state classes)agent.py(Execution and orchestration capabilities)tools/tools.py(Python tools and MCP integrations)prompts/prompt.md(Behavioral instructions)
4. Flask API Integration (app/api/agent/)
AgentCore is purposefully decoupled from direct database (ORM) access limit risk. Read and write integration with the broader OnRamp ecosystem occurs through:
- AgentCore Proxy: A Flask controller that intercepts authenticated requests from the Vue frontend and securely proxies them to the standalone AgentCore service.
- Save Callback Service: Specific internal endpoints that domain agents can invoke to trigger validated database writes.
5. Frontend Integration (app/ui-organization/, app/ui-customer/)
The Vue 3.5 frontend communicates with AgentCore through Flask via:
- An SSE transport composable (
app/onramp/composables/useAgentSse.ts) —fetch+ReadableStreamreader that parses AG-UI events and dispatches them to per-call callbacks (text deltas, tool calls, run lifecycle, custom events). - Domain composables (
useAskAIfor ORAskAI,usePortalAgentChatfor the portal copilot) that own conversation state and wire transport callbacks to chat/canvas updates. - Pinia stores for isolated chat and context state management (e.g., Playbook AI Builder).
- The Flask agent proxy controller (
app/api/agent/controllers/agent_core_proxy.py) translates each browser POST into abedrock-agentcore.invoke_agent_runtimecall and pipes the SSE response back unmodified.
6. Infrastructure & Deployment (scripts/)
AgentCore uses a static, configuration-driven deployment model. IAM roles and policies are created once in the AWS Console — no bootstrap scripts, no DuploCloud API calls, no admin tokens required.
IAM Architecture:
Two categories of IAM configuration are required:
Execution Roles (assumed by the AgentCore runtime at invocation time):
duploservices-nonprod-agentcore— used bydevandstagingduploservices-prod-agentcore— used byprod- Trust policy: allows
bedrock-agentcore.amazonaws.comto assume the role - Permissions:
BedrockAgentCoreFullAccess(AWS-managed) for runtime capabilities (model invocation, knowledge base retrieval, logging, tracing)
Deploy Policy (
AgentCoreDeploy, customer-managed):- Attached to each Duplo tenant role (
duploservices-dev01,duploservices-staging,duploservices-prod) - Grants deployer permissions:
s3:*onbedrock-agentcore-*buckets,bedrock-agentcore:*, andiam:PassRoleon the execution roles
- Attached to each Duplo tenant role (
sequenceDiagram
participant Dev as Developer
participant Scripts as scripts/deploy.py
participant Config as environments.yaml
participant S3 as S3 (Deployment Bucket)
participant AgentCore as AgentCore Runtime
Dev->>Scripts: `make agent.deploy`
Scripts->>Config: Read execution_role_name for ENVIRONMENT_NAME
Scripts->>Scripts: Compute ARN: arn:aws:iam::{account}:role/{role_name}
Scripts->>AgentCore: `agentcore configure` (inject role ARN + agent name)
Scripts->>S3: Upload deployment package
Scripts->>AgentCore: `agentcore deploy`
AgentCore-->>Dev: ✅ Agent deployedscripts/deploy.py: The sole deployment script. Readsexecution_role_namefromenvironments.yaml, configures the agent, and deploys. Invoked viamake agent.deployorbun run agent:deploy.
7. Environment Configuration (src/environments.yaml)
AgentCore uses a code-centric configuration registry to map the semantic environment (ENVIRONMENT_NAME=dev, lowercased) to its underlying structural infrastructure dependencies (e.g., tenant_name, execution_role_name, and onramp_domain_kb_id).
Deployments and runtime knowledge retrievals resolve their target identifiers dynamically from this version-controlled YAML file, centralizing configuration and eliminating .env sprawl.