Skip to content

Commit ef6f038

Browse files
committed
Package move and add Pydantic example
1 parent 0e74acc commit ef6f038

File tree

8 files changed

+143
-1
lines changed

8 files changed

+143
-1
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Agents based on Crew AI samples

examples-java/src/main/java/com/embabel/example/bookwriter/BookWriter.java renamed to examples-java/src/main/java/com/embabel/example/crew/bookwriter/BookWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.embabel.example.bookwriter;
1+
package com.embabel.example.crew.bookwriter;
22

33
import com.embabel.agent.api.annotation.*;
44
import com.embabel.agent.api.common.OperationContext;

examples-java/src/main/java/com/embabel/example/bookwriter/README.md renamed to examples-java/src/main/java/com/embabel/example/crew/bookwriter/README.md

File renamed without changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Agents based on Pydantic AI samples
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.embabel.example.pydantic.banksupport;
2+
3+
import org.springframework.stereotype.Service;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
@Service
9+
class InMemoryCustomerRepository implements CustomerRepository {
10+
11+
private final List<Customer> customers = new ArrayList<>();
12+
13+
{
14+
// Pre-populate with customer
15+
customers.add(new Customer(123L, "John", 100.0f, 27.0f));
16+
}
17+
18+
@Override
19+
public Customer findById(Long id) {
20+
return customers.stream()
21+
.filter(customer -> customer.id().equals(id))
22+
.findFirst()
23+
.orElse(null);
24+
}
25+
26+
27+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Pydantic Bank Support Example
2+
3+
See https://ai.pydantic.dev/examples/bank-support/#running-the-example
4+
5+
Our version demonstrates:
6+
7+
- Integration with Spring Data for production-quality data access
8+
- A true domain model with LLM tools on domain objects.
9+
10+
Run within Spring Shell with:
11+
12+
```bash
13+
bank-support --id 123 --query "What's my balance?"
14+
15+
bank-support --id 123 --query "What's my balance, including pending amounts. Also, I have lost my card. Can you help?"
16+
```
17+
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.embabel.example.pydantic.banksupport;
2+
3+
4+
import com.embabel.agent.api.annotation.AchievesGoal;
5+
import com.embabel.agent.api.annotation.Action;
6+
import com.embabel.agent.api.annotation.Agent;
7+
import com.embabel.agent.api.common.OperationContext;
8+
import com.embabel.agent.config.models.OpenAiModels;
9+
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
10+
import org.springframework.ai.tool.annotation.Tool;
11+
import org.springframework.data.repository.Repository;
12+
import org.springframework.lang.Nullable;
13+
14+
record Customer(Long id, String name, float balance, float pendingAmount) {
15+
16+
@Tool(description = "Find the balance of a customer by id")
17+
float balance(boolean includePending) {
18+
return includePending ? balance + pendingAmount : balance;
19+
}
20+
}
21+
22+
interface CustomerRepository extends Repository<Customer, Long> {
23+
24+
@Nullable
25+
Customer findById(Long id);
26+
}
27+
28+
record SupportInput(
29+
@JsonPropertyDescription("Customer ID") Long customerId,
30+
@JsonPropertyDescription("Query from the customer") String query) {
31+
}
32+
33+
record SupportOutput(
34+
@JsonPropertyDescription("Advice returned to the customer") String advice,
35+
@JsonPropertyDescription("Whether to block their card or not") boolean blockCard,
36+
@JsonPropertyDescription("Risk level of query") int risk) {
37+
}
38+
39+
@Agent(description = "Customer support agent")
40+
record SupportAgent(CustomerRepository customerRepository) {
41+
42+
@AchievesGoal(description = "Help bank customer with their query")
43+
@Action
44+
SupportOutput supportCustomer(SupportInput supportInput, OperationContext context) {
45+
var customer = customerRepository.findById(supportInput.customerId());
46+
if (customer == null) {
47+
return new SupportOutput("Customer not found with this id", false, 0);
48+
}
49+
return context.ai()
50+
.withLlm(OpenAiModels.GPT_41_MINI)
51+
.withToolObject(customer)
52+
.createObject(
53+
"""
54+
You are a support agent in our bank, give the
55+
customer support and judge the risk level of their query.
56+
In some cases, you may need to block their card. In this case, explain why.
57+
Reply using the customer's name, "%s".
58+
Currencies are in $.
59+
60+
There query: [%s]
61+
""".formatted(customer.name(), supportInput.query()),
62+
SupportOutput.class);
63+
}
64+
65+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.embabel.example.pydantic.banksupport;
2+
3+
import com.embabel.agent.api.common.autonomy.AgentInvocation;
4+
import com.embabel.agent.core.AgentPlatform;
5+
import com.embabel.agent.core.ProcessOptions;
6+
import org.springframework.shell.standard.ShellComponent;
7+
import org.springframework.shell.standard.ShellMethod;
8+
import org.springframework.shell.standard.ShellOption;
9+
10+
@ShellComponent
11+
public record SupportAgentShellCommands(
12+
AgentPlatform agentPlatform
13+
) {
14+
15+
@ShellMethod("Get bank support for a customer query")
16+
public String bankSupport(
17+
@ShellOption(value = "id", help = "customer id", defaultValue = "123") Long id,
18+
@ShellOption(value = "query", help = "customer query", defaultValue = "What's my balance, including pending amounts?") String query
19+
) {
20+
var supportInput = new SupportInput(id, query);
21+
System.out.println("Support input: " + supportInput);
22+
var invocation = AgentInvocation
23+
.builder(agentPlatform)
24+
.options(ProcessOptions.builder().verbosity(v -> v.showPrompts(true)).build())
25+
.build(SupportOutput.class);
26+
var result = invocation.invoke(supportInput);
27+
return result.toString();
28+
}
29+
30+
31+
}

0 commit comments

Comments
 (0)