diff --git a/genai-function-calling/README.md b/genai-function-calling/README.md
index a8776cc..41d6a53 100644
--- a/genai-function-calling/README.md
+++ b/genai-function-calling/README.md
@@ -78,5 +78,27 @@ http://localhost:5601/app/apm/traces?rangeFrom=now-15m&rangeTo=now

+## Prerequisites
+
+Docker or Podman is required. You'll also need an OpenAI API compatible
+inference platform and an OpenTelemetry collector.
+
+First of all, you need to be in a directory that contains this repository. If
+you haven't yet, you get one like this:
+```bash
+curl -L https://github.com/elastic/observability-examples/archive/refs/heads/main.tar.gz | tar -xz
+cd observability-examples-main/genai-function-calling/
+```
+
+### Podman
+
+If you are using [Podman](https://podman.io/) to run docker containers, export
+`HOST_IP`. If you don't you'll get this error running exercises:
+> unable to upgrade to tcp, received 500
+
+Here's how to export your `HOST_IP`:
+ * If macOS: `export HOST_IP=$(ipconfig getifaddr en0)`
+ * If Ubuntu: `export HOST_IP=$(hostname -I | awk '{print $1}')`
+
---
-[native]: https://opentelemetry.io/docs/languages/java/instrumentation/#native-instrumentation
\ No newline at end of file
+[native]: https://opentelemetry.io/docs/languages/java/instrumentation/#native-instrumentation
diff --git a/genai-function-calling/openai-agents/Dockerfile b/genai-function-calling/openai-agents/Dockerfile
index 4b534df..de8d87b 100644
--- a/genai-function-calling/openai-agents/Dockerfile
+++ b/genai-function-calling/openai-agents/Dockerfile
@@ -1,12 +1,6 @@
# Use glibc-based image with pre-compiled wheels for psutil
FROM python:3.12-slim
-# TODO: temporary until openai-agents 0.0.5
-RUN apt-get update \
- && apt-get install -y --no-install-recommends git \
- && apt-get clean \
- && rm -rf /var/lib/apt/lists/*
-
RUN --mount=type=cache,target=/root/.cache/pip python -m pip install --upgrade pip
COPY requirements.txt /tmp
@@ -15,4 +9,4 @@ RUN --mount=type=cache,target=/root/.cache/pip edot-bootstrap --action=install
COPY main.py /
-CMD [ "python", "main.py" ]
+CMD [ "opentelemetry-instrument", "python", "main.py" ]
diff --git a/genai-function-calling/openai-agents/docker-compose.yml b/genai-function-calling/openai-agents/docker-compose.yml
index 3c4e195..c5812d8 100644
--- a/genai-function-calling/openai-agents/docker-compose.yml
+++ b/genai-function-calling/openai-agents/docker-compose.yml
@@ -6,4 +6,4 @@ services:
env_file:
- .env
extra_hosts: # send localhost traffic to the docker host, e.g. your laptop
- - "localhost:host-gateway"
+ - "localhost:${HOST_IP:-host-gateway}"
diff --git a/genai-function-calling/openai-agents/env.example b/genai-function-calling/openai-agents/env.example
index 4e8b1f0..a643de9 100644
--- a/genai-function-calling/openai-agents/env.example
+++ b/genai-function-calling/openai-agents/env.example
@@ -8,6 +8,13 @@ OPENAI_API_KEY=
# # leave it out, you need to update this to qwen2.5:3b to proceed the tool call.
# CHAT_MODEL=qwen2.5:0.5b
+# Uncomment to use RamaLama instead of OpenAI
+# OPENAI_BASE_URL=http://localhost:8080/v1
+# OPENAI_API_KEY=unused
+# # This works when you supply a major_version parameter in your prompt. If you
+# # leave it out, you need to update this to qwen2.5:3b to proceed the tool call.
+# CHAT_MODEL=qwen2.5:0.5b
+
# Uncomment and complete if you want to use Azure OpenAI Service
## "Azure OpenAI Endpoint" in https://oai.azure.com/resource/overview
# AZURE_OPENAI_ENDPOINT=https://YOUR_RESOURCE_NAME.openai.azure.com/
diff --git a/genai-function-calling/openai-agents/requirements.txt b/genai-function-calling/openai-agents/requirements.txt
index 6bdeb3c..61132a4 100644
--- a/genai-function-calling/openai-agents/requirements.txt
+++ b/genai-function-calling/openai-agents/requirements.txt
@@ -1,5 +1,4 @@
-# TODO: temporary until openai-agents 0.0.5
-openai-agents @ git+https://github.com/openai/openai-agents-python.git@main
+openai-agents~=0.0.5
httpx~=0.28.1
elastic-opentelemetry~=0.8.0
diff --git a/genai-function-calling/semantic-kernel-dotnet/Dockerfile b/genai-function-calling/semantic-kernel-dotnet/Dockerfile
index 138a273..6a79487 100644
--- a/genai-function-calling/semantic-kernel-dotnet/Dockerfile
+++ b/genai-function-calling/semantic-kernel-dotnet/Dockerfile
@@ -1,7 +1,7 @@
ARG DOTNET_VERSION=9.0
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-alpine AS edot
-ARG EDOT_VERSION=1.0.0-beta.1
+ARG EDOT_VERSION=1.0.0-beta.2
ARG EDOT_INSTALL=https://github.com/elastic/elastic-otel-dotnet/releases/download/${EDOT_VERSION}/elastic-dotnet-auto-install.sh
ENV OTEL_DOTNET_AUTO_HOME=/edot
WORKDIR /edot
diff --git a/genai-function-calling/semantic-kernel-dotnet/app.csproj b/genai-function-calling/semantic-kernel-dotnet/app.csproj
index 26b69d1..8604489 100644
--- a/genai-function-calling/semantic-kernel-dotnet/app.csproj
+++ b/genai-function-calling/semantic-kernel-dotnet/app.csproj
@@ -11,9 +11,9 @@
-
-
-
+
+
+
diff --git a/genai-function-calling/semantic-kernel-dotnet/docker-compose.yml b/genai-function-calling/semantic-kernel-dotnet/docker-compose.yml
index 3c4e195..c5812d8 100644
--- a/genai-function-calling/semantic-kernel-dotnet/docker-compose.yml
+++ b/genai-function-calling/semantic-kernel-dotnet/docker-compose.yml
@@ -6,4 +6,4 @@ services:
env_file:
- .env
extra_hosts: # send localhost traffic to the docker host, e.g. your laptop
- - "localhost:host-gateway"
+ - "localhost:${HOST_IP:-host-gateway}"
diff --git a/genai-function-calling/semantic-kernel-dotnet/env.example b/genai-function-calling/semantic-kernel-dotnet/env.example
index c617aa3..a6aae3b 100644
--- a/genai-function-calling/semantic-kernel-dotnet/env.example
+++ b/genai-function-calling/semantic-kernel-dotnet/env.example
@@ -8,6 +8,13 @@ OPENAI_API_KEY=
# # leave it out, you need to update this to qwen2.5:3b to proceed the tool call.
# CHAT_MODEL=qwen2.5:0.5b
+# Uncomment to use RamaLama instead of OpenAI
+# OPENAI_BASE_URL=http://localhost:8080/v1
+# OPENAI_API_KEY=unused
+# # This works when you supply a major_version parameter in your prompt. If you
+# # leave it out, you need to update this to qwen2.5:3b to proceed the tool call.
+# CHAT_MODEL=qwen2.5:0.5b
+
# Uncomment and complete if you want to use Azure OpenAI Service
## "Azure OpenAI Endpoint" in https://oai.azure.com/resource/overview
# AZURE_OPENAI_ENDPOINT=https://YOUR_RESOURCE_NAME.openai.azure.com/
diff --git a/genai-function-calling/spring-ai/.mvn/wrapper/maven-wrapper.properties b/genai-function-calling/spring-ai/.mvn/wrapper/maven-wrapper.properties
index 8f96f52..d58dfb7 100644
--- a/genai-function-calling/spring-ai/.mvn/wrapper/maven-wrapper.properties
+++ b/genai-function-calling/spring-ai/.mvn/wrapper/maven-wrapper.properties
@@ -6,7 +6,7 @@
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
-# https://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
@@ -16,4 +16,4 @@
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
diff --git a/genai-function-calling/spring-ai/docker-compose.yml b/genai-function-calling/spring-ai/docker-compose.yml
index 330ec80..d9c4a59 100644
--- a/genai-function-calling/spring-ai/docker-compose.yml
+++ b/genai-function-calling/spring-ai/docker-compose.yml
@@ -6,4 +6,4 @@ services:
env_file:
- .env
extra_hosts: # send localhost traffic to the docker host, e.g. your laptop
- - "localhost:host-gateway"
+ - "localhost:${HOST_IP:-host-gateway}"
diff --git a/genai-function-calling/spring-ai/env.example b/genai-function-calling/spring-ai/env.example
index 2689c41..659ba8b 100644
--- a/genai-function-calling/spring-ai/env.example
+++ b/genai-function-calling/spring-ai/env.example
@@ -8,6 +8,13 @@ OPENAI_API_KEY=
# # leave it out, you need to update this to qwen2.5:3b to proceed the tool call.
# CHAT_MODEL=qwen2.5:0.5b
+# Uncomment to use RamaLama instead of OpenAI
+# OPENAI_BASE_URL=http://localhost:8080/v1
+# OPENAI_API_KEY=unused
+# # This works when you supply a major_version parameter in your prompt. If you
+# # leave it out, you need to update this to qwen2.5:3b to proceed the tool call.
+# CHAT_MODEL=qwen2.5:0.5b
+
# Uncomment and complete if you want to use Azure OpenAI Service
## "Azure OpenAI Endpoint" in https://oai.azure.com/resource/overview
# AZURE_OPENAI_ENDPOINT=https://YOUR_RESOURCE_NAME.openai.azure.com/
diff --git a/genai-function-calling/spring-ai/mvnw b/genai-function-calling/spring-ai/mvnw
index d7c358e..19529dd 100755
--- a/genai-function-calling/spring-ai/mvnw
+++ b/genai-function-calling/spring-ai/mvnw
@@ -8,7 +8,7 @@
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
-# https://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
diff --git a/genai-function-calling/spring-ai/mvnw.cmd b/genai-function-calling/spring-ai/mvnw.cmd
index 6f779cf..b150b91 100644
--- a/genai-function-calling/spring-ai/mvnw.cmd
+++ b/genai-function-calling/spring-ai/mvnw.cmd
@@ -1,149 +1,149 @@
-<# : batch portion
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM https://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.3.2
-@REM
-@REM Optional ENV vars
-@REM MVNW_REPOURL - repo url base for downloading maven distribution
-@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
-@REM ----------------------------------------------------------------------------
-
-@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
-@SET __MVNW_CMD__=
-@SET __MVNW_ERROR__=
-@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
-@SET PSModulePath=
-@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
- IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
-)
-@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
-@SET __MVNW_PSMODULEP_SAVE=
-@SET __MVNW_ARG0_NAME__=
-@SET MVNW_USERNAME=
-@SET MVNW_PASSWORD=
-@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
-@echo Cannot start maven from wrapper >&2 && exit /b 1
-@GOTO :EOF
-: end batch / begin powershell #>
-
-$ErrorActionPreference = "Stop"
-if ($env:MVNW_VERBOSE -eq "true") {
- $VerbosePreference = "Continue"
-}
-
-# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
-$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
-if (!$distributionUrl) {
- Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
-}
-
-switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
- "maven-mvnd-*" {
- $USE_MVND = $true
- $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
- $MVN_CMD = "mvnd.cmd"
- break
- }
- default {
- $USE_MVND = $false
- $MVN_CMD = $script -replace '^mvnw','mvn'
- break
- }
-}
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/
-if ($env:MVNW_REPOURL) {
- $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
- $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
-}
-$distributionUrlName = $distributionUrl -replace '^.*/',''
-$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
-$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
-if ($env:MAVEN_USER_HOME) {
- $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
-}
-$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
-$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
-
-if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
- Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
- Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
- exit $?
-}
-
-if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
- Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
-}
-
-# prepare tmp dir
-$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
-$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
-$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
-trap {
- if ($TMP_DOWNLOAD_DIR.Exists) {
- try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
- catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
- }
-}
-
-New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
-
-# Download and Install Apache Maven
-Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-Write-Verbose "Downloading from: $distributionUrl"
-Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-$webclient = New-Object System.Net.WebClient
-if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
- $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
-}
-[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
-if ($distributionSha256Sum) {
- if ($USE_MVND) {
- Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
- }
- Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
- if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
- Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
- }
-}
-
-# unzip and move
-Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
-Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
-try {
- Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
-} catch {
- if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
- Write-Error "fail to move MAVEN_HOME"
- }
-} finally {
- try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
- catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-}
-
-Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+<# : batch portion
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.3.2
+@REM
+@REM Optional ENV vars
+@REM MVNW_REPOURL - repo url base for downloading maven distribution
+@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
+@REM ----------------------------------------------------------------------------
+
+@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
+@SET __MVNW_CMD__=
+@SET __MVNW_ERROR__=
+@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
+@SET PSModulePath=
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
+ IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
+)
+@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
+@SET __MVNW_PSMODULEP_SAVE=
+@SET __MVNW_ARG0_NAME__=
+@SET MVNW_USERNAME=
+@SET MVNW_PASSWORD=
+@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
+@echo Cannot start maven from wrapper >&2 && exit /b 1
+@GOTO :EOF
+: end batch / begin powershell #>
+
+$ErrorActionPreference = "Stop"
+if ($env:MVNW_VERBOSE -eq "true") {
+ $VerbosePreference = "Continue"
+}
+
+# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
+$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
+if (!$distributionUrl) {
+ Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
+}
+
+switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
+ "maven-mvnd-*" {
+ $USE_MVND = $true
+ $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
+ $MVN_CMD = "mvnd.cmd"
+ break
+ }
+ default {
+ $USE_MVND = $false
+ $MVN_CMD = $script -replace '^mvnw','mvn'
+ break
+ }
+}
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/
+if ($env:MVNW_REPOURL) {
+ $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
+ $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
+}
+$distributionUrlName = $distributionUrl -replace '^.*/',''
+$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
+$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
+if ($env:MAVEN_USER_HOME) {
+ $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
+}
+$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
+$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
+
+if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
+ Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+ Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+ exit $?
+}
+
+if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
+ Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
+}
+
+# prepare tmp dir
+$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
+$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
+$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
+trap {
+ if ($TMP_DOWNLOAD_DIR.Exists) {
+ try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+ catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+ }
+}
+
+New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
+
+# Download and Install Apache Maven
+Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+Write-Verbose "Downloading from: $distributionUrl"
+Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+$webclient = New-Object System.Net.WebClient
+if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
+ $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
+}
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
+if ($distributionSha256Sum) {
+ if ($USE_MVND) {
+ Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
+ }
+ Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
+ if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
+ Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
+ }
+}
+
+# unzip and move
+Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
+Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
+try {
+ Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
+} catch {
+ if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
+ Write-Error "fail to move MAVEN_HOME"
+ }
+} finally {
+ try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+ catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+}
+
+Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
diff --git a/genai-function-calling/spring-ai/pom.xml b/genai-function-calling/spring-ai/pom.xml
index efb9aba..f310052 100644
--- a/genai-function-calling/spring-ai/pom.xml
+++ b/genai-function-calling/spring-ai/pom.xml
@@ -41,7 +41,7 @@
co.elastic.otel
elastic-otel-javaagent
- 1.2.1
+ 1.3.0
optional
diff --git a/genai-function-calling/vercel-ai/docker-compose.yml b/genai-function-calling/vercel-ai/docker-compose.yml
index 330ec80..d9c4a59 100644
--- a/genai-function-calling/vercel-ai/docker-compose.yml
+++ b/genai-function-calling/vercel-ai/docker-compose.yml
@@ -6,4 +6,4 @@ services:
env_file:
- .env
extra_hosts: # send localhost traffic to the docker host, e.g. your laptop
- - "localhost:host-gateway"
+ - "localhost:${HOST_IP:-host-gateway}"
diff --git a/genai-function-calling/vercel-ai/env.example b/genai-function-calling/vercel-ai/env.example
index d61250a..ed3ee6a 100644
--- a/genai-function-calling/vercel-ai/env.example
+++ b/genai-function-calling/vercel-ai/env.example
@@ -7,6 +7,12 @@ OPENAI_API_KEY=
# # This needs qwen2.5:3b, as qwen2.5:0.5b doesn't process the tool call
# CHAT_MODEL=qwen2.5:3b
+# Uncomment to use RamaLama instead of OpenAI
+# OPENAI_BASE_URL=http://localhost:8080/v1
+# OPENAI_API_KEY=unused
+# # This needs qwen2.5:3b, as qwen2.5:0.5b doesn't process the tool call
+# CHAT_MODEL=qwen2.5:3b
+
# Uncomment and complete if you want to use Azure OpenAI Service
## "Azure OpenAI Endpoint" in https://oai.azure.com/resource/overview
# AZURE_OPENAI_ENDPOINT=https://YOUR_RESOURCE_NAME.openai.azure.com/
diff --git a/genai-function-calling/vercel-ai/package.json b/genai-function-calling/vercel-ai/package.json
index 81d3335..e344c57 100644
--- a/genai-function-calling/vercel-ai/package.json
+++ b/genai-function-calling/vercel-ai/package.json
@@ -4,15 +4,15 @@
"private": true,
"type": "commonjs",
"engines": {
- "node": ">=20"
+ "node": ">=22"
},
"scripts": {
"start": "node --env-file .env -r @elastic/opentelemetry-node index.js"
},
"dependencies": {
- "ai": "^4.1.46",
- "@ai-sdk/azure": "^1.2.1",
- "@ai-sdk/openai": "^1.1.15",
+ "ai": "^4.1.63",
+ "@ai-sdk/azure": "^1.2.6",
+ "@ai-sdk/openai": "^1.2.6",
"@elastic/opentelemetry-node": "*"
},
"_comment": "Override to avoid punycode warnings in recent versions of Node.JS",