Skip to content

Commit 37b1ae6

Browse files
author
Yuriy Bezsonov
committed
Add demo scripts for step-by-step AI agent build
Incremental scripts (00-07, 10) that build the AI agent feature by feature: chat client, memory, knowledge base, tools, browser, code interpreter, MCP, and deploy to AgentCore runtime. Also fix 09-aiagent-ui.sh to write config.json to app dir instead of repo source.
1 parent 55409e2 commit 37b1ae6

11 files changed

Lines changed: 1482 additions & 1 deletion

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "=============================================="
5+
echo "00-setup.sh - Move full app to ~/demo-full/"
6+
echo "=============================================="
7+
8+
if [ -d ~/demo-full ]; then
9+
echo "~/demo-full/ already exists, skipping move"
10+
else
11+
echo "Cleaning target directories..."
12+
rm -rf ~/environment/aiagent/target
13+
rm -rf ~/environment/backoffice/target
14+
rm -rf ~/environment/currency/target
15+
16+
echo "Moving ~/environment/* to ~/demo-full/..."
17+
mkdir -p ~/demo-full
18+
mv ~/environment/* ~/demo-full/
19+
mv ~/environment/.envrc ~/demo-full/ 2>/dev/null || true
20+
fi
21+
22+
echo "Cleaning ~/environment/..."
23+
rm -rf ~/environment/aiagent ~/environment/backoffice ~/environment/currency
24+
rm -f ~/environment/.envrc
25+
mkdir -p ~/environment
26+
27+
echo ""
28+
echo "Done. Full app in ~/demo-full/, ~/environment/ is clean."
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "=============================================="
5+
echo "01-create.sh - Create Spring Boot AI Agent"
6+
echo "=============================================="
7+
8+
# Idempotency check
9+
if [ -d ~/environment/aiagent ]; then
10+
echo "~/environment/aiagent already exists, skipping creation"
11+
else
12+
cd ~/environment/
13+
14+
curl -s https://start.spring.io/starter.zip \
15+
-d type=maven-project \
16+
-d language=java \
17+
-d packaging=jar \
18+
-d javaVersion=25 \
19+
-d bootVersion=4.0.2 \
20+
-d baseDir=aiagent \
21+
-d groupId=com.example \
22+
-d artifactId=agent \
23+
-d name=agent \
24+
-d description='AI agent with Spring AI and Amazon Bedrock' \
25+
-d dependencies=spring-ai-bedrock-converse,web,webflux,actuator \
26+
-o aiagent.zip
27+
28+
unzip -q aiagent.zip
29+
rm aiagent.zip
30+
31+
cd ~/environment/aiagent
32+
git init -q
33+
git add -A
34+
git commit -q -m "Initial Spring Boot project from start.spring.io"
35+
fi
36+
37+
echo ""
38+
echo "Project created at ~/environment/aiagent"
39+
read -p "Press ENTER to continue..."
40+
41+
# --- Patch pom.xml: add agentcore BOM + runtime-starter ---
42+
43+
cd ~/environment/aiagent
44+
45+
# Add agentcore BOM to dependencyManagement (inside <dependencies>, after spring-ai-bom closing tag)
46+
if ! grep -q "spring-ai-agentcore-bom" pom.xml; then
47+
sed -i '/<artifactId>spring-ai-bom<\/artifactId>/,/<\/dependency>/{
48+
/<\/dependency>/a \
49+
\t\t\t<dependency>\n\t\t\t\t<groupId>org.springaicommunity</groupId>\n\t\t\t\t<artifactId>spring-ai-agentcore-bom</artifactId>\n\t\t\t\t<version>1.0.0</version>\n\t\t\t\t<type>pom</type>\n\t\t\t\t<scope>import</scope>\n\t\t\t</dependency>
50+
}' pom.xml
51+
fi
52+
53+
# Add runtime-starter dependency (after bedrock-converse)
54+
if ! grep -q "spring-ai-agentcore-runtime-starter" pom.xml; then
55+
sed -i '/<artifactId>spring-ai-starter-model-bedrock-converse<\/artifactId>/,/<\/dependency>/{
56+
/<\/dependency>/a \
57+
\t\t<!-- AgentCore dependencies -->\n\t\t<dependency>\n\t\t\t<groupId>org.springaicommunity</groupId>\n\t\t\t<artifactId>spring-ai-agentcore-runtime-starter</artifactId>\n\t\t</dependency>
58+
}' pom.xml
59+
fi
60+
61+
# --- Write application.properties ---
62+
63+
cat > ~/environment/aiagent/src/main/resources/application.properties << 'EOF'
64+
spring.application.name=agent
65+
# Logging
66+
logging.level.org.springframework.ai=DEBUG
67+
logging.level.org.springaicommunity.agentcore=DEBUG
68+
logging.level.com.example.agent=DEBUG
69+
logging.pattern.console=%msg%n
70+
# Amazon Bedrock Configuration
71+
spring.ai.bedrock.aws.timeout=120s
72+
spring.ai.bedrock.converse.chat.options.max-tokens=4096
73+
spring.ai.bedrock.converse.chat.options.model=global.anthropic.claude-sonnet-4-5-20250929-v1:0
74+
spring.ai.bedrock.converse.chat.options.temperature=0.7
75+
EOF
76+
77+
# --- Write ChatService.java ---
78+
79+
cat <<'EOF' > ~/environment/aiagent/src/main/java/com/example/agent/ChatService.java
80+
package com.example.agent;
81+
82+
import org.springaicommunity.agentcore.annotation.AgentCoreInvocation;
83+
import org.springframework.ai.chat.client.ChatClient;
84+
import org.springframework.stereotype.Service;
85+
import reactor.core.publisher.Flux;
86+
87+
record ChatRequest(String prompt) {}
88+
89+
@Service
90+
public class ChatService {
91+
92+
private final ChatClient chatClient;
93+
94+
private static final String SYSTEM_PROMPT = """
95+
You are a helpful AI agent for travel and expense management.
96+
Be friendly, helpful, and concise in your responses.
97+
""";
98+
99+
public ChatService(ChatClient.Builder chatClientBuilder) {
100+
this.chatClient = chatClientBuilder
101+
.defaultSystem(SYSTEM_PROMPT)
102+
.build();
103+
}
104+
105+
@AgentCoreInvocation
106+
public Flux<String> chat(ChatRequest request) {
107+
return chatClient.prompt().user(request.prompt()).stream().content();
108+
}
109+
}
110+
EOF
111+
112+
# --- Copy static UI files ---
113+
114+
mkdir -p ~/environment/aiagent/src/main/resources/static
115+
cp ~/java-on-aws/apps/java-spring-ai-agents/aiagent/src/main/resources/static/* \
116+
~/environment/aiagent/src/main/resources/static/
117+
118+
echo ""
119+
echo "Code added: ChatService + properties + UI"
120+
read -p "Press ENTER to continue..."
121+
122+
# --- Commit and run ---
123+
124+
cd ~/environment/aiagent
125+
git add -A
126+
git commit -q -m "Add chat client with system prompt and web UI"
127+
128+
cd ~/environment/aiagent && ./mvnw spring-boot:run
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "=============================================="
5+
echo "02-memory.sh - Add AgentCore Memory"
6+
echo "=============================================="
7+
8+
cd ~/environment/aiagent
9+
10+
# --- Add env vars ---
11+
12+
source ~/demo-full/.envrc 2>/dev/null || true
13+
14+
# Extract memory ID from demo-full application.properties
15+
MEMORY_ID=$(grep "agentcore.memory.memory-id" ~/demo-full/aiagent/src/main/resources/application.properties | cut -d= -f2)
16+
17+
if [ -z "$MEMORY_ID" ]; then
18+
echo "Error: Could not find memory-id in ~/demo-full/aiagent/src/main/resources/application.properties"
19+
exit 1
20+
fi
21+
22+
# --- Add memory dependency to pom.xml ---
23+
24+
if ! grep -q "spring-ai-agentcore-memory" pom.xml; then
25+
sed -i '/<artifactId>spring-ai-agentcore-runtime-starter<\/artifactId>/,/<\/dependency>/{
26+
/<\/dependency>/a \
27+
\t\t<!-- AgentCore Memory dependencies -->\n\t\t<dependency>\n\t\t\t<groupId>org.springaicommunity</groupId>\n\t\t\t<artifactId>spring-ai-agentcore-memory</artifactId>\n\t\t</dependency>
28+
}' pom.xml
29+
fi
30+
31+
# --- Add memory properties ---
32+
33+
if ! grep -q "agentcore.memory.memory-id" src/main/resources/application.properties; then
34+
cat >> src/main/resources/application.properties << EOF
35+
36+
# AgentCore Memory
37+
agentcore.memory.memory-id=${MEMORY_ID}
38+
agentcore.memory.long-term.auto-discovery=true
39+
EOF
40+
fi
41+
42+
# --- Update ChatService.java ---
43+
44+
cat <<'EOF' > src/main/java/com/example/agent/ChatService.java
45+
package com.example.agent;
46+
47+
import java.util.ArrayList;
48+
import java.util.List;
49+
50+
import org.slf4j.Logger;
51+
import org.slf4j.LoggerFactory;
52+
import org.springaicommunity.agentcore.annotation.AgentCoreInvocation;
53+
import org.springaicommunity.agentcore.context.AgentCoreContext;
54+
import org.springaicommunity.agentcore.context.AgentCoreHeaders;
55+
import org.springaicommunity.agentcore.memory.longterm.AgentCoreMemory;
56+
import org.springframework.ai.chat.client.ChatClient;
57+
import org.springframework.ai.chat.client.advisor.api.Advisor;
58+
import org.springframework.ai.chat.memory.ChatMemory;
59+
import org.springframework.stereotype.Service;
60+
import reactor.core.publisher.Flux;
61+
62+
record ChatRequest(String prompt) {}
63+
64+
@Service
65+
public class ChatService {
66+
67+
private static final Logger logger = LoggerFactory.getLogger(ChatService.class);
68+
69+
private final ChatClient chatClient;
70+
71+
private static final String SYSTEM_PROMPT = """
72+
You are a helpful AI agent for travel and expense management.
73+
Be friendly, helpful, and concise in your responses.
74+
""";
75+
76+
public ChatService(AgentCoreMemory agentCoreMemory,
77+
ChatClient.Builder chatClientBuilder) {
78+
79+
List<Advisor> advisors = new ArrayList<>();
80+
81+
// Memory (STM + LTM)
82+
advisors.addAll(agentCoreMemory.advisors);
83+
logger.info("Memory enabled: {} advisors", agentCoreMemory.advisors.size());
84+
85+
this.chatClient = chatClientBuilder
86+
.defaultSystem(SYSTEM_PROMPT)
87+
.defaultAdvisors(advisors.toArray(new Advisor[0]))
88+
.build();
89+
}
90+
91+
@AgentCoreInvocation
92+
public Flux<String> chat(ChatRequest request, AgentCoreContext context) {
93+
return chat(request.prompt(), getConversationId(context));
94+
}
95+
96+
private Flux<String> chat(String prompt, String sessionId) {
97+
return chatClient.prompt().user(prompt)
98+
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, sessionId))
99+
.stream().content();
100+
}
101+
102+
private String getConversationId(AgentCoreContext context) {
103+
return context.getHeader(AgentCoreHeaders.SESSION_ID);
104+
}
105+
}
106+
EOF
107+
108+
echo ""
109+
echo "Memory added: dependency + properties + ChatService updated"
110+
read -p "Press ENTER to continue..."
111+
112+
git add -A
113+
git commit -q -m "Add AgentCore Memory (STM + LTM)"
114+
115+
cd ~/environment/aiagent && ./mvnw spring-boot:run

0 commit comments

Comments
 (0)