Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
AWS_ACCESS_KEY_ID=TODO
AWS_SECRET_ACCESS_KEY=TODO
AWS_SESSION_TOKEN=TODO

AWS_REGION=us-east-2
AWS_S3_BUCKET_NAME=bitovi-ai-agents-workshop

AWS_MODEL_ARN=arn:aws:bedrock:us-east-2:755521597925:inference-profile/us.anthropic.claude-3-7-sonnet-20250219-v1:0
AWS_MODEL_ID=us.anthropic.claude-3-7-sonnet-20250219-v1:0

AWS_EMBEDDING_MODEL_ARN=arn:aws:bedrock:us-east-2::foundation-model/amazon.titan-embed-text-v2:0
AWS_EMBEDDING_MODEL_ID=amazon.titan-embed-text-v2:0

POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DATABASE=workshop
POSTGRES_USERNAME=dbuser
POSTGRES_PASSWORD=dbpassword

QDRANT_HOST=localhost
QDRANT_PORT_HTTP=6333
QDRANT_PORT_GRPC=6334

TEMPORAL_HOST_PORT=localhost:7233
TEMPORAL_NAMESPACE=default
TEMPORAL_TASK_QUEUE=bitovi-ai-agents-workshop

MCP_SERVER_BASE_URL=http://localhost:8090
MCP_SERVER_SSE_URL=http://localhost:8090/sse

OPENAI_API_KEY=TODO
OPENAI_MODEL=gpt-4o
OPENAI_API_BASE=https://api.openai.com/v1

USER_ID=TODO
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
**/*/target/
**/*/bin/
**/*/config.properties
**/*.class
**/*.log
**/*.tmp
**/*.swp
**/*.bak
**/*.jar
config.properties
.DS_Store
node_modules
.env
.env
*.pem
*.key
*.crt
26 changes: 13 additions & 13 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"request": "launch",
"mainClass": "bitovi.EnvironmentSetupWorker",
"projectName": "environment-setup",
"cwd": "${workspaceFolder}/0-environment-setup/",
"cwd": "${workspaceFolder}/0-environment-setup/java/",
"preLaunchTask": "Exercise 0 Maven Build"
},
{
Expand All @@ -16,15 +16,15 @@
"request": "launch",
"mainClass": "bitovi.EnvironmentSetupClient",
"projectName": "environment-setup",
"cwd": "${workspaceFolder}/0-environment-setup/"
"cwd": "${workspaceFolder}/0-environment-setup/java/"
},
{
"type": "java",
"name": "Exercise 1 - Worker",
"request": "launch",
"mainClass": "bitovi.PromptEngineeringWorker",
"projectName": "prompt-engineering",
"cwd": "${workspaceFolder}/1-prompt-engineering/",
"cwd": "${workspaceFolder}/1-prompt-engineering/java/",
"preLaunchTask": "Exercise 1 Maven Build"
},
{
Expand All @@ -33,15 +33,15 @@
"request": "launch",
"mainClass": "bitovi.PromptEngineeringClient",
"projectName": "prompt-engineering",
"cwd": "${workspaceFolder}/1-prompt-engineering/"
"cwd": "${workspaceFolder}/1-prompt-engineering/java/"
},
{
"type": "java",
"name": "Exercise 2 - Worker",
"request": "launch",
"mainClass": "bitovi.RagWorker",
"projectName": "rag",
"cwd": "${workspaceFolder}/2-rag/",
"cwd": "${workspaceFolder}/2-rag/java/",
"preLaunchTask": "Exercise 2 Maven Build"
},
{
Expand All @@ -50,16 +50,16 @@
"request": "launch",
"mainClass": "bitovi.RagClient",
"projectName": "rag",
"cwd": "${workspaceFolder}/2-rag/",
"args": "${workspaceFolder}/2-rag/documents/"
"cwd": "${workspaceFolder}/2-rag/java/",
"args": "${workspaceFolder}/2-rag/java/documents/"
},
{
"type": "java",
"name": "Exercise 3 - Worker",
"request": "launch",
"mainClass": "bitovi.ToolCallingWorker",
"projectName": "tool-calling",
"cwd": "${workspaceFolder}/3-tool-calling/",
"cwd": "${workspaceFolder}/3-tool-calling/java/",
"preLaunchTask": "Exercise 3 Maven Build"
},
{
Expand All @@ -68,15 +68,15 @@
"request": "launch",
"mainClass": "bitovi.ToolCallingClient",
"projectName": "tool-calling",
"cwd": "${workspaceFolder}/3-tool-calling/"
"cwd": "${workspaceFolder}/3-tool-calling/java/"
},
{
"type": "java",
"name": "Exercise 4 - Worker",
"request": "launch",
"mainClass": "bitovi.McpWorker",
"projectName": "mcp",
"cwd": "${workspaceFolder}/4-mcp/",
"cwd": "${workspaceFolder}/4-mcp/java/",
"preLaunchTask": "Exercise 4 Maven Build"
},
{
Expand All @@ -85,23 +85,23 @@
"request": "launch",
"mainClass": "bitovi.McpClient",
"projectName": "mcp",
"cwd": "${workspaceFolder}/4-mcp/"
"cwd": "${workspaceFolder}/4-mcp/java/"
},
{
"type": "java",
"name": "Exercise 5 - Worker",
"request": "launch",
"mainClass": "bitovi.AgentWorkflowWorker",
"projectName": "agent-workflow",
"cwd": "${workspaceFolder}/5-agent-workflow/"
"cwd": "${workspaceFolder}/5-agent-workflow/java/"
},
{
"type": "java",
"name": "Exercise 5 - Client",
"request": "launch",
"mainClass": "bitovi.AgentWorkflowClient",
"projectName": "agent-workflow",
"cwd": "${workspaceFolder}/5-agent-workflow/",
"cwd": "${workspaceFolder}/5-agent-workflow/java/",
"preLaunchTask": "Exercise 5 Maven Build"
}
]
Expand Down
12 changes: 6 additions & 6 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"type": "shell",
"command": "mvn compile",
"options": {
"cwd": "${workspaceFolder}/0-environment-setup"
"cwd": "${workspaceFolder}/0-environment-setup/java"
},
"group": {
"kind": "build",
Expand All @@ -73,7 +73,7 @@
"type": "shell",
"command": "mvn compile",
"options": {
"cwd": "${workspaceFolder}/1-prompt-engineering"
"cwd": "${workspaceFolder}/1-prompt-engineering/java"
},
"group": {
"kind": "build",
Expand All @@ -87,7 +87,7 @@
"type": "shell",
"command": "mvn compile",
"options": {
"cwd": "${workspaceFolder}/2-rag"
"cwd": "${workspaceFolder}/2-rag/java"
},
"group": {
"kind": "build",
Expand All @@ -101,7 +101,7 @@
"type": "shell",
"command": "mvn compile",
"options": {
"cwd": "${workspaceFolder}/3-tool-calling"
"cwd": "${workspaceFolder}/3-tool-calling/java"
},
"group": {
"kind": "build",
Expand All @@ -115,7 +115,7 @@
"type": "shell",
"command": "mvn compile",
"options": {
"cwd": "${workspaceFolder}/4-mcp"
"cwd": "${workspaceFolder}/4-mcp/java"
},
"group": {
"kind": "build",
Expand All @@ -129,7 +129,7 @@
"type": "shell",
"command": "mvn compile",
"options": {
"cwd": "${workspaceFolder}/5-agent-workflow"
"cwd": "${workspaceFolder}/5-agent-workflow/java"
},
"group": {
"kind": "build",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ There are a few external systems being used by the exercises in this repo:
1. AWS S3 - used for document storage
1. Postgres - used for structured data storage

To correctly connect to these, copy the `config.properties-example` file to `config.properties` and replace the `TODO` property.
To correctly connect to these, copy the `.env.example` file to `.env` and replace the `TODO` property.

## Local Systems / Mocks

Expand All @@ -50,6 +50,6 @@ After making code changes, be sure to restart the worker:

## Solution

When you have the `config.properties` set up correctly and launch `Exercise 0 - Worker` and then `Exercise 0 - Client` you should be able to visit the [Temporal UI](http://localhost:8233) and see the workflow executed successfully:
When you have the `.env` set up correctly and launch `Exercise 0 - Worker` and then `Exercise 0 - Client` you should be able to visit the [Temporal UI](http://localhost:8233) and see the workflow executed successfully:

![image](https://github.com/user-attachments/assets/4d497e90-f245-4108-8f72-03ca1c9602e7)
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package bitovi;

import bitovi.common.TemporalClient;

import java.io.FileNotFoundException;

import javax.net.ssl.SSLException;

import bitovi.common.Config;

import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;

public class EnvironmentSetupClient {

public static void main(String[] args) {
public static void main(String[] args) throws SSLException, FileNotFoundException {
Config config = new Config();
String taskQueue = config.getProperty("TEMPORAL_TASK_QUEUE");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
import bitovi.activities.Qdrant;
import io.temporal.workflow.Workflow;
import io.temporal.activity.ActivityOptions;
import io.temporal.common.RetryOptions;

public class EnvironmentSetupWorkflowImpl implements EnvironmentSetupWorkflow {
private final ActivityOptions defaultActivityOptions = ActivityOptions
.newBuilder()
.setStartToCloseTimeout(Duration.ofSeconds(120))
.setRetryOptions(RetryOptions.newBuilder().setMaximumAttempts(3).build())
.build();

private final Bedrock bedrockActivities = Workflow.newActivityStub(Bedrock.class, defaultActivityOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
public interface Bedrock {

@ActivityMethod
void checkBedrockConnection() throws ApplicationFailure;
String checkBedrockConnection() throws ApplicationFailure;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

public class BedrockImpl implements Bedrock {
@Override
public void checkBedrockConnection() throws ApplicationFailure {
public String checkBedrockConnection() throws ApplicationFailure {
Config config = new Config();

String AWS_ACCESS_KEY_ID = config.getProperty("AWS_ACCESS_KEY_ID");
Expand All @@ -30,9 +30,9 @@ public void checkBedrockConnection() throws ApplicationFailure {
String AWS_MODEL_ID = config.getProperty("AWS_MODEL_ID");
String AWS_EMBEDDING_MODEL_ID = config.getProperty("AWS_EMBEDDING_MODEL_ID");

try {
StaticCredentialsProvider credentialsProvider;
StaticCredentialsProvider credentialsProvider;

try {
if (AWS_SESSION_TOKEN == null || AWS_SESSION_TOKEN.isEmpty()) {
credentialsProvider = StaticCredentialsProvider.create(
AwsBasicCredentials.create(
Expand All @@ -45,12 +45,27 @@ public void checkBedrockConnection() throws ApplicationFailure {
AWS_SECRET_ACCESS_KEY,
AWS_SESSION_TOKEN));
}
} catch (Exception e) {
throw ApplicationFailure.newNonRetryableFailure(
"Failed to create AWS credentials: " + e.getMessage(),
"AWSCredentialsError");
}

BedrockRuntimeClient bedrockRuntimeClient = BedrockRuntimeClient.builder()
BedrockRuntimeClient bedrockRuntimeClient;

try {
bedrockRuntimeClient = BedrockRuntimeClient.builder()
.credentialsProvider(credentialsProvider)
.region(Region.of(AWS_REGION))
.build();

} catch (Exception e) {
throw ApplicationFailure.newNonRetryableFailure(
"Failed to create Bedrock client: " + e.getMessage(),
"BedrockClientError");
}

try {
ConverseRequest converseRequest = ConverseRequest.builder()
.modelId(AWS_MODEL_ID)
.messages(Message.builder()
Expand All @@ -63,7 +78,13 @@ public void checkBedrockConnection() throws ApplicationFailure {
.build())
.build();
bedrockRuntimeClient.converse(converseRequest);
} catch (Exception e) {
throw ApplicationFailure.newNonRetryableFailure(
"Failed to converse with Bedrock: " + e.getMessage(),
"BedrockError");
}

try {
InvokeModelRequest embedRequest = InvokeModelRequest.builder()
.modelId(AWS_EMBEDDING_MODEL_ID)
.contentType("application/json")
Expand All @@ -72,10 +93,13 @@ public void checkBedrockConnection() throws ApplicationFailure {
.put("inputText", "Hello").toString()))
.build();
bedrockRuntimeClient.invokeModel(embedRequest);

} catch (Exception e) {
throw ApplicationFailure.newNonRetryableFailure(
"Failed to connect to Bedrock: " + e.getMessage(),
"Failed to embed with Bedrock: " + e.getMessage(),
"BedrockError");
}

return "Bedrock connection successful.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
public interface Postgres {

@ActivityMethod
void checkPostgresConnection() throws ApplicationFailure;
String checkPostgresConnection() throws ApplicationFailure;
}
Loading