Skip to content

Commit c2e11ea

Browse files
committed
Add VoyageAI integration to Elasticsearch
- Add text, multimodal, and contextual embeddings support - Add rerank functionality - All code in services/voyageai directory - Includes comprehensive test coverage - Removed 3 files from external/voyageai directory - Removed 3 files from external/http/sender directory - All VoyageAI code now in services/voyageai directory only
1 parent cd926f1 commit c2e11ea

33 files changed

+1999
-313
lines changed

test-voyageai-e2e.sh

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
#!/bin/bash
2+
3+
# VoyageAI End-to-End Test Script
4+
# This script tests the VoyageAI integration with real API calls
5+
6+
set -e # Exit on error
7+
8+
# Color codes for output
9+
RED='\033[0;31m'
10+
GREEN='\033[0;32m'
11+
YELLOW='\033[1;33m'
12+
NC='\033[0m' # No Color
13+
14+
# Configuration
15+
ES_URL="${ES_URL:-http://localhost:9200}"
16+
ES_USER="${ES_USER:-elastic}"
17+
ES_PASSWORD="${ES_PASSWORD:-changeme}"
18+
VOYAGE_API_KEY="${VOYAGE_API_KEY}"
19+
20+
# Check prerequisites
21+
if [ -z "$VOYAGE_API_KEY" ]; then
22+
echo -e "${RED}Error: VOYAGE_API_KEY environment variable is not set${NC}"
23+
echo "Usage: export VOYAGE_API_KEY='your-api-key' && ./test-voyageai-e2e.sh"
24+
exit 1
25+
fi
26+
27+
echo -e "${YELLOW}=== VoyageAI End-to-End Test Suite ===${NC}"
28+
echo "ES URL: $ES_URL"
29+
echo "ES User: $ES_USER"
30+
echo ""
31+
32+
# Test counter
33+
TESTS_RUN=0
34+
TESTS_PASSED=0
35+
TESTS_FAILED=0
36+
37+
# Function to run a test
38+
run_test() {
39+
local test_name="$1"
40+
local test_command="$2"
41+
local expected_pattern="$3"
42+
43+
TESTS_RUN=$((TESTS_RUN + 1))
44+
echo -e "${YELLOW}[TEST $TESTS_RUN] $test_name${NC}"
45+
46+
if output=$(eval "$test_command" 2>&1); then
47+
if [ -n "$expected_pattern" ]; then
48+
if echo "$output" | grep -q "$expected_pattern"; then
49+
echo -e "${GREEN}✓ PASSED${NC}"
50+
TESTS_PASSED=$((TESTS_PASSED + 1))
51+
return 0
52+
else
53+
echo -e "${RED}✗ FAILED - Expected pattern not found: $expected_pattern${NC}"
54+
echo "Output: $output"
55+
TESTS_FAILED=$((TESTS_FAILED + 1))
56+
return 1
57+
fi
58+
else
59+
echo -e "${GREEN}✓ PASSED${NC}"
60+
TESTS_PASSED=$((TESTS_PASSED + 1))
61+
return 0
62+
fi
63+
else
64+
echo -e "${RED}✗ FAILED${NC}"
65+
echo "Error: $output"
66+
TESTS_FAILED=$((TESTS_FAILED + 1))
67+
return 1
68+
fi
69+
}
70+
71+
# Cleanup function
72+
cleanup() {
73+
echo -e "\n${YELLOW}Cleaning up test endpoints...${NC}"
74+
curl -s -X DELETE "${ES_URL}/_inference/text_embedding/voyage-text-test" -u "${ES_USER}:${ES_PASSWORD}" > /dev/null 2>&1 || true
75+
curl -s -X DELETE "${ES_URL}/_inference/text_embedding/voyage-multimodal-test" -u "${ES_USER}:${ES_PASSWORD}" > /dev/null 2>&1 || true
76+
curl -s -X DELETE "${ES_URL}/_inference/text_embedding/voyage-contextual-test" -u "${ES_USER}:${ES_PASSWORD}" > /dev/null 2>&1 || true
77+
curl -s -X DELETE "${ES_URL}/_inference/rerank/voyage-rerank-test" -u "${ES_USER}:${ES_PASSWORD}" > /dev/null 2>&1 || true
78+
curl -s -X DELETE "${ES_URL}/_inference/text_embedding/voyage-35-test" -u "${ES_USER}:${ES_PASSWORD}" > /dev/null 2>&1 || true
79+
}
80+
81+
# Trap to ensure cleanup on exit
82+
trap cleanup EXIT
83+
84+
# Initial cleanup
85+
cleanup
86+
87+
echo -e "\n${YELLOW}=== Test Suite 1: Text Embeddings (voyage-3) ===${NC}\n"
88+
89+
run_test "Create text embeddings endpoint" \
90+
"curl -s -X PUT '${ES_URL}/_inference/text_embedding/voyage-text-test' \
91+
-u '${ES_USER}:${ES_PASSWORD}' \
92+
-H 'Content-Type: application/json' \
93+
-d '{
94+
\"service\": \"voyageai\",
95+
\"service_settings\": {
96+
\"api_key\": \"${VOYAGE_API_KEY}\",
97+
\"model_id\": \"voyage-3\"
98+
}
99+
}'" \
100+
'"model_id":"voyage-3"'
101+
102+
run_test "Get text embeddings endpoint configuration" \
103+
"curl -s -X GET '${ES_URL}/_inference/text_embedding/voyage-text-test' \
104+
-u '${ES_USER}:${ES_PASSWORD}'" \
105+
'"model_id":"voyage-3"'
106+
107+
run_test "Inference with text embeddings" \
108+
"curl -s -X POST '${ES_URL}/_inference/text_embedding/voyage-text-test' \
109+
-u '${ES_USER}:${ES_PASSWORD}' \
110+
-H 'Content-Type: application/json' \
111+
-d '{
112+
\"input\": [\"Hello world\", \"This is a test\"]
113+
}'" \
114+
'"text_embedding"'
115+
116+
run_test "Inference with INGEST input type" \
117+
"curl -s -X POST '${ES_URL}/_inference/text_embedding/voyage-text-test' \
118+
-u '${ES_USER}:${ES_PASSWORD}' \
119+
-H 'Content-Type: application/json' \
120+
-d '{
121+
\"input\": [\"Document for indexing\"],
122+
\"task_settings\": {
123+
\"input_type\": \"ingest\"
124+
}
125+
}'" \
126+
'"text_embedding"'
127+
128+
run_test "Inference with SEARCH input type" \
129+
"curl -s -X POST '${ES_URL}/_inference/text_embedding/voyage-text-test' \
130+
-u '${ES_USER}:${ES_PASSWORD}' \
131+
-H 'Content-Type: application/json' \
132+
-d '{
133+
\"input\": [\"Search query\"],
134+
\"task_settings\": {
135+
\"input_type\": \"search\"
136+
}
137+
}'" \
138+
'"text_embedding"'
139+
140+
echo -e "\n${YELLOW}=== Test Suite 2: Multimodal Embeddings (voyage-multimodal-3) ===${NC}\n"
141+
142+
run_test "Create multimodal embeddings endpoint" \
143+
"curl -s -X PUT '${ES_URL}/_inference/text_embedding/voyage-multimodal-test' \
144+
-u '${ES_USER}:${ES_PASSWORD}' \
145+
-H 'Content-Type: application/json' \
146+
-d '{
147+
\"service\": \"voyageai\",
148+
\"service_settings\": {
149+
\"api_key\": \"${VOYAGE_API_KEY}\",
150+
\"model_id\": \"voyage-multimodal-3\"
151+
}
152+
}'" \
153+
'"model_id":"voyage-multimodal-3"'
154+
155+
run_test "Get multimodal embeddings configuration" \
156+
"curl -s -X GET '${ES_URL}/_inference/text_embedding/voyage-multimodal-test' \
157+
-u '${ES_USER}:${ES_PASSWORD}'" \
158+
'"model_id":"voyage-multimodal-3"'
159+
160+
run_test "Inference with multimodal embeddings" \
161+
"curl -s -X POST '${ES_URL}/_inference/text_embedding/voyage-multimodal-test' \
162+
-u '${ES_USER}:${ES_PASSWORD}' \
163+
-H 'Content-Type: application/json' \
164+
-d '{
165+
\"input\": [\"Multimodal test text\"]
166+
}'" \
167+
'"text_embedding"'
168+
169+
echo -e "\n${YELLOW}=== Test Suite 3: Contextual Embeddings (voyage-context-3) ===${NC}\n"
170+
171+
run_test "Create contextual embeddings endpoint" \
172+
"curl -s -X PUT '${ES_URL}/_inference/text_embedding/voyage-contextual-test' \
173+
-u '${ES_USER}:${ES_PASSWORD}' \
174+
-H 'Content-Type: application/json' \
175+
-d '{
176+
\"service\": \"voyageai\",
177+
\"service_settings\": {
178+
\"api_key\": \"${VOYAGE_API_KEY}\",
179+
\"model_id\": \"voyage-context-3\"
180+
}
181+
}'" \
182+
'"model_id":"voyage-context-3"'
183+
184+
run_test "Get contextual embeddings configuration" \
185+
"curl -s -X GET '${ES_URL}/_inference/text_embedding/voyage-contextual-test' \
186+
-u '${ES_USER}:${ES_PASSWORD}'" \
187+
'"model_id":"voyage-context-3"'
188+
189+
run_test "Inference with contextual embeddings" \
190+
"curl -s -X POST '${ES_URL}/_inference/text_embedding/voyage-contextual-test' \
191+
-u '${ES_USER}:${ES_PASSWORD}' \
192+
-H 'Content-Type: application/json' \
193+
-d '{
194+
\"input\": [\"Contextual test sentence\", \"Another test\"]
195+
}'" \
196+
'"text_embedding"'
197+
198+
echo -e "\n${YELLOW}=== Test Suite 4: v3.5 Models ===${NC}\n"
199+
200+
run_test "Create voyage-3.5 embeddings endpoint" \
201+
"curl -s -X PUT '${ES_URL}/_inference/text_embedding/voyage-35-test' \
202+
-u '${ES_USER}:${ES_PASSWORD}' \
203+
-H 'Content-Type: application/json' \
204+
-d '{
205+
\"service\": \"voyageai\",
206+
\"service_settings\": {
207+
\"api_key\": \"${VOYAGE_API_KEY}\",
208+
\"model_id\": \"voyage-3.5\"
209+
}
210+
}'" \
211+
'"model_id":"voyage-3.5"'
212+
213+
run_test "Inference with voyage-3.5" \
214+
"curl -s -X POST '${ES_URL}/_inference/text_embedding/voyage-35-test' \
215+
-u '${ES_USER}:${ES_PASSWORD}' \
216+
-H 'Content-Type: application/json' \
217+
-d '{
218+
\"input\": [\"Test with v3.5 model\"]
219+
}'" \
220+
'"text_embedding"'
221+
222+
echo -e "\n${YELLOW}=== Test Suite 5: Rerank (Regression Test) ===${NC}\n"
223+
224+
run_test "Create rerank endpoint" \
225+
"curl -s -X PUT '${ES_URL}/_inference/rerank/voyage-rerank-test' \
226+
-u '${ES_USER}:${ES_PASSWORD}' \
227+
-H 'Content-Type: application/json' \
228+
-d '{
229+
\"service\": \"voyageai\",
230+
\"service_settings\": {
231+
\"api_key\": \"${VOYAGE_API_KEY}\",
232+
\"model_id\": \"rerank-2\"
233+
}
234+
}'" \
235+
'"model_id":"rerank-2"'
236+
237+
run_test "Rerank inference" \
238+
"curl -s -X POST '${ES_URL}/_inference/rerank/voyage-rerank-test' \
239+
-u '${ES_USER}:${ES_PASSWORD}' \
240+
-H 'Content-Type: application/json' \
241+
-d '{
242+
\"query\": \"What is the capital of France?\",
243+
\"input\": [
244+
\"Paris is the capital of France\",
245+
\"London is the capital of England\",
246+
\"Berlin is the capital of Germany\"
247+
]
248+
}'" \
249+
'"rerank"'
250+
251+
# Print summary
252+
echo -e "\n${YELLOW}=== Test Summary ===${NC}"
253+
echo -e "Total tests run: $TESTS_RUN"
254+
echo -e "${GREEN}Tests passed: $TESTS_PASSED${NC}"
255+
if [ $TESTS_FAILED -gt 0 ]; then
256+
echo -e "${RED}Tests failed: $TESTS_FAILED${NC}"
257+
exit 1
258+
else
259+
echo -e "${GREEN}All tests passed!${NC}"
260+
exit 0
261+
fi

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/voyageai/VoyageAIAccount.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/voyageai/VoyageAIResponseHandler.java

Lines changed: 0 additions & 62 deletions
This file was deleted.

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/voyageai/VoyageAIModel.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public abstract class VoyageAIModel extends RateLimitGroupingModel {
3434
Map<String, String> tempMap = new HashMap<>();
3535
tempMap.put("voyage-3.5", "embed_medium");
3636
tempMap.put("voyage-3.5-lite", "embed_small");
37+
tempMap.put("voyage-context-3", "embed_context");
3738
tempMap.put("voyage-multimodal-3", "embed_multimodal");
3839
tempMap.put("voyage-3-large", "embed_large");
3940
tempMap.put("voyage-code-3", "embed_large");

0 commit comments

Comments
 (0)