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: 21 additions & 14 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ local_resource(
################################## build backend_rag image and do live update ##########################################
########################################################################################################################

IGNORE_BASE = [
"infrastructure/",
"services/frontend/",
]

# NOTE: full image names should match the one in the helm chart values.yaml!
registry = "ghcr.io/stackitcloud/rag-template"
rag_api_image_name = "rag-backend"
Expand All @@ -163,11 +168,7 @@ docker_build(
sync(core_library_context+"/rag-core-lib", "/app/libs/rag-core-lib"),
],
dockerfile=backend_context + "/Dockerfile",
ignore=[
"infrastructure/",
"services/frontend/.nx/",
"services/frontend/tmp/",
],
ignore=IGNORE_BASE
)

# Add linter trigger
Expand Down Expand Up @@ -207,11 +208,7 @@ docker_build(
sync(mcp_context, "/app/services/mcp-server"),
],
dockerfile=mcp_context + "/Dockerfile",
ignore=[
"infrastructure/",
"services/frontend/.nx/",
"services/frontend/tmp/",
],
ignore=IGNORE_BASE,
)

# Add linter trigger
Expand Down Expand Up @@ -246,7 +243,7 @@ docker_build(
sync(core_library_context + "/admin-api-lib", "/app/libs/admin-api-lib"),
],
dockerfile=admin_backend_context + "/Dockerfile",
ignore=["infrastructure/"],
ignore=IGNORE_BASE,
)

# Add linter trigger
Expand Down Expand Up @@ -290,7 +287,7 @@ docker_build(
sync(core_library_context +"/extractor-api-lib", "/app/libs/extractor-api-lib"),
],
dockerfile=extractor_context + "/Dockerfile",
ignore=["infrastructure/"],
ignore=IGNORE_BASE,
)

# Add linter trigger
Expand Down Expand Up @@ -331,7 +328,12 @@ docker_build(
sync("./services/frontend/dist/apps/chat-app", "/usr/share/nginx/html"),
sync("./services/frontend/dist/libs", "/usr/share/nginx/html/libs"),
],
ignore=["infrastructure/"],
ignore=[
"infrastructure/",
"services/frontend/.nx/",
"services/frontend/tmp/",
"services/frontend/node_modules/",
],
)

########################################################################################################################
Expand All @@ -349,7 +351,12 @@ docker_build(
sync("./services/frontend/dist/apps/admin-app", "/usr/share/nginx/html"),
sync("./services/frontend/dist/libs", "/usr/share/nginx/html/libs"),
],
ignore=["infrastructure/"],
ignore=[
"infrastructure/",
"services/frontend/.nx/",
"services/frontend/tmp/",
"services/frontend/node_modules/",
],
)


Expand Down
7 changes: 4 additions & 3 deletions infrastructure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ backend:
retriever:
RETRIEVER_THRESHOLD: 0.3
RETRIEVER_K_DOCUMENTS: 10
RETRIEVER_TOTAL_K: 7
# Canonical global cap (previously RETRIEVER_TOTAL_K / RETRIEVER_OVERALL_K_DOCUMENTS)
RETRIEVER_TOTAL_K_DOCUMENTS: 20
RETRIEVER_SUMMARY_THRESHOLD: 0.3
RETRIEVER_SUMMARY_K_DOCUMENTS: 10
RETRIEVER_TABLE_THRESHOLD: 0.3
Expand Down Expand Up @@ -489,7 +490,7 @@ Afterwards, the services are accessible from [http://rag.localhost](http://rag.l

Note: The command above has only been tested on *Ubuntu 22.04 LTS*.

On *Windows* you can adjust the hosts file as described [here](https://docs.digitalocean.com/products/paperspace/machines/how-to/edit-windows-hosts-file/).
On *Windows* you can adjust the hosts file as described in the DigitalOcean guide on [editing the Windows hosts file](https://docs.digitalocean.com/products/paperspace/machines/how-to/edit-windows-hosts-file/).

### 2.2 Production Setup Instructions

Expand All @@ -499,7 +500,7 @@ For deployment of the *NGINX Ingress Controller* and a cert-manager, the followi

[base-setup](server-setup/base-setup/Chart.yaml)

The email [here](server-setup/base-setup/templates/cert-issuer.yaml) should be changed from `<replace@me.com>` to a real email address.
The email in the [cert-issuer template](server-setup/base-setup/templates/cert-issuer.yaml) should be changed from `<replace@me.com>` to a real email address.

## 3. Contributing

Expand Down
68 changes: 58 additions & 10 deletions infrastructure/local-cluster-setup/setup-k3d-cluster.sh
Original file line number Diff line number Diff line change
@@ -1,17 +1,65 @@
#!/bin/bash
k3d cluster create rag --config k3d-cluster-config.yaml --k3s-arg "--disable=traefik@server:*"

kubectl wait --for=condition=ready node --all --timeout=120s
# Fail fast on errors, unset vars, and propagate pipe failures
set -euo pipefail

REPO_NAME="bitnami"
# Add the Helm repository if it doesn't exist
if ! helm repo list | grep -q "$REPO_NAME"; then
echo "Adding Helm repository $REPO_NAME..."
helm repo add $REPO_NAME https://charts.bitnami.com/bitnami
helm repo update
CLUSTER_NAME="rag"
K3D_CONFIG_FILE="k3d-cluster-config.yaml"

echo "Creating k3d cluster '${CLUSTER_NAME}' (if it does not already exist)..."
cluster_exists=false
if command -v jq >/dev/null 2>&1; then
if k3d cluster list -o json 2>/dev/null | jq -e --arg name "$CLUSTER_NAME" 'map(select(.name==$name)) | length > 0' >/dev/null; then
cluster_exists=true
fi
else
# Fallback without jq (less robust)
if k3d cluster list --no-headers 2>/dev/null | awk '{print $1}' | grep -qx "${CLUSTER_NAME}"; then
cluster_exists=true
fi
fi

if [ "${cluster_exists}" = true ]; then
echo "Cluster '${CLUSTER_NAME}' already exists. Skipping create."
else
echo "Helm repository $REPO_NAME already exists."
k3d cluster create "${CLUSTER_NAME}" --config "${K3D_CONFIG_FILE}" --k3s-arg "--disable=traefik@server:*"
fi

helm install nginx-ingress-controller bitnami/nginx-ingress-controller --namespace nginx-ingress --version "10.3.0" --create-namespace
echo "Waiting for all nodes to become Ready..."
kubectl wait --for=condition=ready node --all --timeout=120s || {
echo "WARNING: Some nodes did not reach Ready state within timeout." >&2
}

INGRESS_REPO_NAME="ingress-nginx"
INGRESS_REPO_URL="https://kubernetes.github.io/ingress-nginx"
INGRESS_NAMESPACE="ingress-nginx"
INGRESS_RELEASE="ingress-nginx"
INGRESS_CHART="ingress-nginx/ingress-nginx"
INGRESS_CHART_VERSION="${INGRESS_CHART_VERSION:-4.13.3}"
if ! helm repo list | awk '{print $1}' | grep -qx "$INGRESS_REPO_NAME"; then
echo "Adding Helm repository $INGRESS_REPO_NAME ($INGRESS_REPO_URL)..."
helm repo add "$INGRESS_REPO_NAME" "$INGRESS_REPO_URL"
else
echo "Helm repository $INGRESS_REPO_NAME already exists."
fi
echo "Updating Helm repository $INGRESS_REPO_NAME..."
helm repo update "$INGRESS_REPO_NAME"

echo "Installing / upgrading '$INGRESS_RELEASE' chart version ${INGRESS_CHART_VERSION}"
helm upgrade --install "$INGRESS_RELEASE" "$INGRESS_CHART" \
--namespace "$INGRESS_NAMESPACE" \
--create-namespace \
--version "$INGRESS_CHART_VERSION"
echo "Waiting for ingress controller deployment rollout..."
if kubectl rollout status deployment/${INGRESS_RELEASE}-controller -n "$INGRESS_NAMESPACE" --timeout=180s; then
echo "Ingress controller successfully rolled out."
else
echo "Rollout not complete. Recent events:" >&2
kubectl -n "$INGRESS_NAMESPACE" get events --sort-by=.lastTimestamp | tail -n 30 || true
fi

echo "Current ingress-nginx pods:"
kubectl get pods -n "$INGRESS_NAMESPACE" -l app.kubernetes.io/name=ingress-nginx || true



4 changes: 3 additions & 1 deletion infrastructure/rag/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ backend:
retriever:
RETRIEVER_THRESHOLD: 0.3
RETRIEVER_K_DOCUMENTS: 10
RETRIEVER_TOTAL_K: 7
# Canonical global cap across all retrievers. Replaces legacy RETRIEVER_TOTAL_K / RETRIEVER_OVERALL_K_DOCUMENTS
RETRIEVER_TOTAL_K_DOCUMENTS: 20
RETRIEVER_SUMMARY_THRESHOLD: 0.3
RETRIEVER_SUMMARY_K_DOCUMENTS: 10
RETRIEVER_TABLE_THRESHOLD: 0.3
Expand Down Expand Up @@ -211,6 +212,7 @@ backend:
reranker:
RERANKER_K_DOCUMENTS: 5
RERANKER_MIN_RELEVANCE_SCORE: 0.001
RERANKER_ENABLED: true
chatHistory:
CHAT_HISTORY_LIMIT: 4
CHAT_HISTORY_REVERSE: true
Expand Down
10 changes: 5 additions & 5 deletions infrastructure/server-setup/base-setup/Chart.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ dependencies:
- name: cert-manager
repository: https://charts.jetstack.io
version: v1.18.2
- name: nginx-ingress-controller
repository: https://charts.bitnami.com/bitnami
version: 11.6.27
digest: sha256:3197e71b2e91041da3bca61187bd413ea86ed7778a8cecf363182be1aaead1f0
generated: "2025-07-31T08:32:45.824521293Z"
- name: ingress-nginx
repository: https://kubernetes.github.io/ingress-nginx
version: 4.13.3
digest: sha256:2da733e46f388692106e8487aa48b1593366cc611ffac246891dbbbe0b9a7943
generated: "2025-10-07T12:41:19.535888+02:00"
8 changes: 4 additions & 4 deletions infrastructure/server-setup/base-setup/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
apiVersion: v2
name: basic
description: |
This helm chart deploys the basic nginx-ingress controller and cert-manager.
This helm chart deploys the official Kubernetes ingress-nginx controller and cert-manager.
type: application
version: 0.0.1
appVersion: "0.0.1"
dependencies:
- name: cert-manager
version: "v1.18.2"
repository: https://charts.jetstack.io
- name: nginx-ingress-controller
version: "11.6.27"
repository: https://charts.bitnami.com/bitnami
- name: ingress-nginx
version: "4.13.3"
repository: https://kubernetes.github.io/ingress-nginx
8 changes: 8 additions & 0 deletions infrastructure/server-setup/base-setup/values.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
cert-manager:
installCRDs: false

# Configuration overrides for the official ingress-nginx chart dependency.
# Pin the controller image tag to v1.13.3 (matching the script installation).
ingress-nginx:
controller:
image:
# registry and image default to the chart's defaults; only pin tag here.
tag: v1.13.3
7 changes: 6 additions & 1 deletion libs/rag-core-api/src/rag_core_api/dependency_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ class DependencyContainer(DeclarativeContainer):
vectorstore=vectorstore,
)

flashrank_reranker = Singleton(FlashrankRerank, top_n=reranker_settings.k_documents)
flashrank_reranker = Singleton(
FlashrankRerank, top_n=reranker_settings.k_documents, score_threshold=reranker_settings.min_relevance_score
)
reranker = Singleton(FlashrankReranker, flashrank_reranker)

information_pieces_uploader = Singleton(DefaultInformationPiecesUploader, vector_database)
Expand Down Expand Up @@ -166,6 +168,9 @@ class DependencyContainer(DeclarativeContainer):
CompositeRetriever,
List(image_retriever, table_retriever, text_retriever, summary_retriever),
reranker,
reranker_settings.enabled,
retriever_settings.total_k_documents,
reranker_settings.k_documents,
)

information_piece_mapper = Singleton(InformationPieceMapper)
Expand Down
7 changes: 7 additions & 0 deletions libs/rag-core-api/src/rag_core_api/impl/graph/chat_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@ async def _retrieve_node(self, state: dict) -> dict:
if document.metadata.get("type", ContentType.SUMMARY.value) != ContentType.SUMMARY.value
]

# If only summaries were retrieved (no concrete underlying documents), treat as "no documents"
if not information_pieces:
return {
self.ERROR_MESSAGES_KEY: [self._error_messages.no_documents_message],
self.FINISH_REASONS: ["No documents found"],
}

response["information_pieces"] = information_pieces
response["langchain_documents"] = retrieved_documents

Expand Down
Loading
Loading