Skip to content

Commit 0430f95

Browse files
mpk-droidclaude
andcommitted
Upgrade Langfuse v2 to v3 and broaden agent scope
- Replace single Langfuse v2 container with v3 multi-service architecture (langfuse-web, langfuse-worker, ClickHouse, MinIO, Redis) - Add Langfuse health check to deploy script (warning-only, non-blocking) - Broaden agent system prompt to handle general outdoor activities, not just national park queries - Update README to reflect v3 services and broader agent scope Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e530dea commit 0430f95

4 files changed

Lines changed: 138 additions & 17 deletions

File tree

agents/langflow/simple_tool_calling_agent/README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88

99
## What this agent does
1010

11-
Outdoor activity planning agent built with Langflow. It recommends the best day and time for outdoor activities by reasoning across weather forecasts, air quality, and National Park Service data.
11+
Outdoor activity assistant built with Langflow. It helps you decide whether conditions are good for any outdoor activity — walking, hiking, cycling, picnics, park visits, or anything else outside. It reasons across weather forecasts and National Park Service data to give a clear recommendation.
1212

13-
**Example query:** *"I want to go hiking near Denver this weekend. What day is best?"*
13+
**Example queries:**
14+
- *"Can I go walking in Boston tomorrow at 3 PM?"*
15+
- *"I want to go hiking near Denver this weekend. What day is best?"*
16+
- *"Is it a good day for a picnic in San Francisco?"*
1417

1518
### Tools
1619
| Tool | API | Description |
@@ -52,9 +55,9 @@ chmod +x deploy-local.sh cleanup-local.sh
5255

5356
This starts:
5457
- **Langflow** on http://localhost:7860 — the agent UI
55-
- **PostgreSQL** — shared database server. Hosts two databases: `langflow` (flows, users, settings) and `langfuse` (traces). The `langflow` database is created automatically by PostgreSQL; the `langfuse` database is created by `local/init-db.sh` on first startup
58+
- **PostgreSQL** — shared database server. Hosts two databases: `langflow` (flows, users, settings) and `langfuse` (metadata). The `langflow` database is created automatically by PostgreSQL; the `langfuse` database is created by `local/init-db.sh` on first startup
5659
- **Ollama** on http://localhost:11434 — local LLM (qwen2.5:7b), runs natively on host for GPU acceleration
57-
- **Langfuse v2** on http://localhost:3000 — tracing (admin@langflow.local / admin123)
60+
- **Langfuse v3** on http://localhost:3000 — tracing (admin@langflow.local / admin123), backed by ClickHouse, MinIO, and Redis
5861

5962
### Import and configure the flow
6063

@@ -102,8 +105,9 @@ On the cluster, replace `localhost:7860` with your cluster's Langflow route URL.
102105
|------|---------------------|----------------------------|
103106
| Downloaded Ollama models (e.g., qwen2.5:7b) | Kept | Kept (stored on host, not in containers) |
104107
| Imported Langflow flows | Kept | **Deleted** (re-import needed) |
105-
| Langfuse traces | Kept | **Deleted** |
108+
| Langfuse traces (ClickHouse + MinIO) | Kept | **Deleted** |
106109
| PostgreSQL data | Kept | **Deleted** |
110+
| Redis cache | Kept | **Deleted** |
107111
| `.env` and `.ollama-enabled` config | Kept | **Deleted** |
108112

109113
---

agents/langflow/simple_tool_calling_agent/deploy-local.sh

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ cd "$LOCAL_DIR" || { echo "ERROR: Directory $LOCAL_DIR not found."; exit 1; }
8181

8282
# Start containerized services (Langflow, PostgreSQL, Langfuse)
8383
echo ""
84-
echo "Starting local stack (Langflow + PostgreSQL + Langfuse)..."
84+
echo "Starting local stack (Langflow + PostgreSQL + Langfuse v3 + ClickHouse + MinIO + Redis)..."
8585
podman-compose up -d
8686

8787
echo ""
88-
echo "Waiting for Langflow to start (this may take a minute)..."
88+
echo "Waiting for Langflow to start (this may take a few minutes)..."
8989
LANGFLOW_READY=false
9090
for i in $(seq 1 60); do
9191
if curl -s http://localhost:7860/health >/dev/null 2>&1; then
@@ -102,6 +102,23 @@ if [ "$LANGFLOW_READY" = false ]; then
102102
exit 1
103103
fi
104104

105+
echo ""
106+
echo "Waiting for Langfuse to start (this may take several minutes)..."
107+
LANGFUSE_READY=false
108+
for i in $(seq 1 60); do
109+
if curl -s http://localhost:3000/api/public/health >/dev/null 2>&1; then
110+
LANGFUSE_READY=true
111+
echo "Langfuse is ready!"
112+
break
113+
fi
114+
sleep 10
115+
done
116+
117+
if [ "$LANGFUSE_READY" = false ]; then
118+
echo "WARNING: Langfuse did not start within 10 minutes. Tracing and logging will not work until it is up."
119+
echo "Check logs: podman logs local_langfuse-web_1"
120+
fi
121+
105122
echo ""
106123
echo "=== Local environment is ready ==="
107124
echo ""

agents/langflow/simple_tool_calling_agent/flows/outdoor-activity-agent.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,7 @@
995995
"trace_as_input": true,
996996
"trace_as_metadata": true,
997997
"type": "str",
998-
"value": "You are a national park trip planner and weather assistant. You MUST use the available tools to get real data for every question - never guess or make up information about alerts, weather, or park details.\n\nIMPORTANT: For every question about a park, call the appropriate tool. Do not answer from memory.\n\nTools:\nNPS Search Parks \u2014 find parks by state code and activity keyword\nNPS Park Alerts \u2014 get active closures/hazards for a park (uses four-letter park code)\nOpen-Meteo Forecast \u2014 get weather forecast for coordinates (latitude, longitude)\n\nWorkflow:\n\nParse the request. Identify: state(s), activity/interest, travel dates (if given), and group needs (e.g., kids, accessibility).\n\nSearch parks. Call NPS Search Parks with the state code and activity. Extract the park code, coordinates, and description from results. If the user mentions a specific park by name, still search to confirm its park code and coordinates.\n\nCheck alerts for each candidate park. Call NPS Park Alerts using the park code. Classify alerts as:\n\nBlocking (closure, danger): disqualifies the park unless the closure is partial and doesn't affect the user's activity.\nInformational (caution, info): mention but don't disqualify.\nCheck weather. Call Open-Meteo Forecast using the park's latitude and longitude. Evaluate conditions against the user's planned activity \u2014 e.g., rain matters more for hiking than museum visits. If the user provided travel dates, focus on that date range.\n\nRecommend. Pick the best park considering all three factors. If the top choice has blocking alerts or severe weather, suggest an alternative from the search results.\n\nShortcuts:\n\nWeather-only question \u2192 skip NPS tools, forecast directly.\nAlert-only question \u2192 skip weather tool.\nUser names a specific park \u2192 still check alerts and weather, skip search only if you already have the park code and coordinates.\n\nResponse format:\n\nProvide your recommendation in this structure:\n\nPark: name, location, and why it fits the activity\n\nAlerts: any active alerts (or \"No active alerts\")\n\nWeather Outlook: conditions for the travel dates, with a note on suitability for the activity\n\nTips: 1-2 practical tips (best trails, gear, timing, alternatives if weather turns)"
998+
"value": "You are an outdoor activity assistant. You help people decide whether conditions are good for outdoor activities — walking, hiking, cycling, picnics, park visits, or anything else outside. You MUST use the available tools to get real data — never guess or make up weather, alerts, or park details.\n\nIMPORTANT: Always call the appropriate tool. Do not answer from memory.\n\nTools:\nOpen-Meteo Forecast — get weather forecast for coordinates (latitude, longitude)\nNPS Search Parks — find national parks by state code and activity keyword\nNPS Park Alerts — get active closures/hazards for a park (uses four-letter park code)\n\nHow to decide which tools to use:\n\n1. Every question gets a weather check. Look up the coordinates for the location the user mentioned (city, park, area) and call Open-Meteo Forecast.\n\n2. Only use NPS tools when the user asks about national parks, hiking trails, or outdoor activities near nature areas. If someone asks about walking in a city, cycling to work, or having a picnic in a city park, skip the NPS tools — they only cover national parks.\n\n3. When you do use NPS tools: search for parks first, then check alerts for each candidate. Classify alerts as blocking (closure, danger) or informational (caution, info).\n\nWorkflow:\n\nParse the request. Identify: location, activity, and dates/times (if given).\n\nCheck weather. Call Open-Meteo Forecast for the location. Evaluate conditions for the specific activity — rain matters more for a picnic than for a museum visit, wind matters for cycling, UV matters for a beach day.\n\nIf relevant, search parks. Only if the user is asking about hiking, national parks, or nature activities near a region. Call NPS Search Parks, then NPS Park Alerts for candidates.\n\nGive a clear answer. Lead with a direct yes/no/maybe recommendation, then explain why based on the data.\n\nResponse format:\n\nAdapt your response to the question. For simple weather checks, keep it short and direct. For park trip planning, include more detail. Always include:\n\n- A clear recommendation (good day for it, not ideal, or avoid)\n- Weather conditions that matter for the activity\n- Alerts or park info only if NPS tools were used\n- 1-2 practical tips if helpful"
999999
},
10001000
"tools": {
10011001
"_input_type": "HandleInput",

agents/langflow/simple_tool_calling_agent/local/podman-compose.yml

Lines changed: 109 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ services:
1515
OPENAI_API_KEY: "not-needed"
1616
OLLAMA_BASE_URL: "http://host.containers.internal:11434"
1717
# Langfuse tracing
18-
LANGFUSE_HOST: "http://langfuse:3000"
18+
LANGFUSE_HOST: "http://langfuse-web:3000"
1919
LANGFUSE_PUBLIC_KEY: "pk-lf-local-dev"
2020
LANGFUSE_SECRET_KEY: "sk-lf-local-dev"
2121
volumes:
2222
- langflow_data:/var/lib/langflow:Z
2323
depends_on:
2424
postgres:
2525
condition: service_healthy
26-
langfuse:
26+
langfuse-web:
2727
condition: service_started
2828

2929
# ── PostgreSQL (shared by Langflow and Langfuse) ────────────────────
@@ -33,6 +33,8 @@ services:
3333
POSTGRES_USER: ${POSTGRES_USER:-langflow}
3434
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-langflow}
3535
POSTGRES_DB: ${POSTGRES_DB:-langflow}
36+
TZ: UTC
37+
PGTZ: UTC
3638
volumes:
3739
- postgres_data:/var/lib/postgresql/data:Z
3840
- ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh:Z
@@ -42,16 +44,54 @@ services:
4244
timeout: 5s
4345
retries: 5
4446

45-
# ── Langfuse v2 (Tracing) ──────────────────────────────────────────
46-
langfuse:
47-
image: docker.io/langfuse/langfuse:2
47+
# ── Langfuse v3 (Tracing) ────────────────────────────────────────
48+
49+
langfuse-web:
50+
image: docker.io/langfuse/langfuse:3
51+
restart: always
4852
ports:
4953
- "3000:3000"
50-
environment:
54+
depends_on: &langfuse-depends-on
55+
postgres:
56+
condition: service_healthy
57+
clickhouse:
58+
condition: service_healthy
59+
minio:
60+
condition: service_healthy
61+
redis:
62+
condition: service_healthy
63+
environment: &langfuse-env
5164
DATABASE_URL: "postgresql://${POSTGRES_USER:-langflow}:${POSTGRES_PASSWORD:-langflow}@postgres:5432/langfuse"
5265
NEXTAUTH_URL: "http://localhost:3000"
5366
NEXTAUTH_SECRET: "local-dev-secret"
5467
SALT: "local-dev-salt"
68+
ENCRYPTION_KEY: "0000000000000000000000000000000000000000000000000000000000000000"
69+
TELEMETRY_ENABLED: "false"
70+
# ClickHouse
71+
CLICKHOUSE_MIGRATION_URL: "clickhouse://clickhouse:9000"
72+
CLICKHOUSE_URL: "http://clickhouse:8123"
73+
CLICKHOUSE_USER: "clickhouse"
74+
CLICKHOUSE_PASSWORD: "clickhouse"
75+
CLICKHOUSE_CLUSTER_ENABLED: "false"
76+
# Redis
77+
REDIS_HOST: "redis"
78+
REDIS_PORT: "6379"
79+
REDIS_AUTH: "localredis"
80+
# MinIO (S3-compatible object storage)
81+
LANGFUSE_S3_EVENT_UPLOAD_BUCKET: "langfuse"
82+
LANGFUSE_S3_EVENT_UPLOAD_REGION: "auto"
83+
LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID: "minio"
84+
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY: "miniosecret"
85+
LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT: "http://minio:9000"
86+
LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE: "true"
87+
LANGFUSE_S3_EVENT_UPLOAD_PREFIX: "events/"
88+
LANGFUSE_S3_MEDIA_UPLOAD_BUCKET: "langfuse"
89+
LANGFUSE_S3_MEDIA_UPLOAD_REGION: "auto"
90+
LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID: "minio"
91+
LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY: "miniosecret"
92+
LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT: "http://minio:9000"
93+
LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE: "true"
94+
LANGFUSE_S3_MEDIA_UPLOAD_PREFIX: "media/"
5595
# Headless init — auto-creates org, project, user, and API keys
5696
LANGFUSE_INIT_ORG_ID: "langflow-org"
5797
LANGFUSE_INIT_ORG_NAME: "Langflow Agent"
@@ -62,10 +102,70 @@ services:
62102
LANGFUSE_INIT_USER_EMAIL: "admin@langflow.local"
63103
LANGFUSE_INIT_USER_NAME: "admin"
64104
LANGFUSE_INIT_USER_PASSWORD: "admin123"
65-
depends_on:
66-
postgres:
67-
condition: service_healthy
105+
106+
langfuse-worker:
107+
image: docker.io/langfuse/langfuse-worker:3
108+
restart: always
109+
depends_on: *langfuse-depends-on
110+
environment:
111+
<<: *langfuse-env
112+
113+
# ── ClickHouse (Langfuse analytics DB) ──────────────────────────────
114+
clickhouse:
115+
image: docker.io/clickhouse/clickhouse-server
116+
restart: always
117+
user: "101:101"
118+
environment:
119+
CLICKHOUSE_DB: default
120+
CLICKHOUSE_USER: clickhouse
121+
CLICKHOUSE_PASSWORD: clickhouse
122+
volumes:
123+
- clickhouse_data:/var/lib/clickhouse:Z
124+
- clickhouse_logs:/var/log/clickhouse-server:Z
125+
healthcheck:
126+
test: wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1
127+
interval: 5s
128+
timeout: 5s
129+
retries: 10
130+
start_period: 1s
131+
132+
# ── MinIO (Langfuse S3-compatible object storage) ───────────────────
133+
minio:
134+
image: docker.io/minio/minio
135+
restart: always
136+
entrypoint: sh
137+
command: -c 'mkdir -p /data/langfuse && minio server --address ":9000" --console-address ":9001" /data'
138+
environment:
139+
MINIO_ROOT_USER: minio
140+
MINIO_ROOT_PASSWORD: miniosecret
141+
volumes:
142+
- minio_data:/data:Z
143+
healthcheck:
144+
test: ["CMD", "mc", "ready", "local"]
145+
interval: 5s
146+
timeout: 5s
147+
retries: 5
148+
start_period: 1s
149+
150+
# ── Redis (Langfuse caching + job queue) ────────────────────────────
151+
redis:
152+
image: docker.io/redis:7
153+
restart: always
154+
command: >
155+
--requirepass localredis
156+
--maxmemory-policy noeviction
157+
volumes:
158+
- redis_data:/data:Z
159+
healthcheck:
160+
test: ["CMD", "redis-cli", "-a", "localredis", "ping"]
161+
interval: 3s
162+
timeout: 10s
163+
retries: 10
68164

69165
volumes:
70166
langflow_data:
71167
postgres_data:
168+
clickhouse_data:
169+
clickhouse_logs:
170+
minio_data:
171+
redis_data:

0 commit comments

Comments
 (0)