imbajin commented on code in PR #382:
URL: https://github.com/apache/hugegraph-ai/pull/382#discussion_r4250371427


##########
hugegraph-mcp/hugegraph_mcp/tools/refresh_vid_embeddings.py:
##########
@@ -41,7 +42,42 @@ def refresh_vid_embeddings(confirm: bool = False) -> 
dict[str, Any]:
             suggestion="Pass confirm=True to refresh VID embeddings.",
         )
 
-    ai_result = post("/vid-embeddings/refresh", json={})
+    cfg = MCPConfig.from_env()
+    capability = get("/vid-embeddings/refresh-capabilities", cfg=cfg)
+    if not capability.get("ok"):
+        error = capability.get("error") or {}
+        # Only an explicitly absent/unsupported endpoint means the protocol is
+        # unavailable. Keep transient and authentication errors retryable as
+        # reported by the client, without ever dispatching the refresh.
+        status_code = (error.get("details") or {}).get("status_code")
+        if error.get("type") in {
+            "AUTHENTICATION_FAILED",
+            "AUTHORIZATION_FAILED",
+            "FEATURE_DISABLED",
+        } or status_code not in {404, 405}:
+            return capability
+        return envelope_err(
+            ErrorType.FEATURE_DISABLED,
+            "AI refresh target-validation endpoint is unavailable; refresh was 
not sent.",
+            suggestion="Check the AI service URL and routing, or upgrade 
HugeGraph-AI to support target validation.",
+            details={"status_code": status_code},
+        )
+    support = capability.get("data")
+    if (
+        not isinstance(support, dict)
+        or type(support.get("protocol_version")) is not int
+        or support["protocol_version"] != 1
+    ):
+        return envelope_err(
+            ErrorType.FEATURE_DISABLED,
+            "AI refresh target-validation protocol is unsupported; refresh was 
not sent.",
+            suggestion="Upgrade HugeGraph-AI to a compatible target-validation 
version.",
+        )
+    ai_result = post(
+        "/vid-embeddings/refresh",
+        cfg=cfg,
+        json={"expected_graph": cfg.graph, "expected_graphspace": 
cfg.graphspace},

Review Comment:
   **[P2] Make target validation inseparable from the refresh endpoint**
   
   During a rolling AI-service upgrade, the capability GET can reach a new 
replica while this POST reaches an old replica. The old 
`/vid-embeddings/refresh` accepts an empty Pydantic model, ignores 
`expected_graph` / `expected_graphspace`, and dispatches the refresh without 
validating either. A mismatched target can therefore be refreshed after a 
successful capability probe.
   
   The included Helm Deployment/Service permits mixed replicas during rolling 
updates, and these calls use separate HTTP requests. Please use a versioned 
validated-refresh POST route that old replicas cannot execute, and add a 
mixed-version routing regression. Checking only the response would detect the 
mismatch after the index update.
   
   This is a source-confirmed gap in the new fail-closed compatibility 
guarantee; no mixed-version deployment was independently run.
   
   Sources: [new 
handshake](https://github.com/apache/hugegraph-ai/blob/bdf76543dd59cc19da4e3eb1337e2e1d1bdc8a7f/hugegraph-mcp/hugegraph_mcp/tools/refresh_vid_embeddings.py#L45-L80),
 [old request 
model](https://github.com/apache/hugegraph-ai/blob/8a7c186c6d660c7f5da723157f6714f3208923cd/hugegraph-llm/src/hugegraph_llm/api/models/rag_requests.py#L188-L189),
 [old 
dispatch](https://github.com/apache/hugegraph-ai/blob/8a7c186c6d660c7f5da723157f6714f3208923cd/hugegraph-llm/src/hugegraph_llm/api/thin_api.py#L153-L157),
 
[deployment](https://github.com/apache/hugegraph-ai/blob/bdf76543dd59cc19da4e3eb1337e2e1d1bdc8a7f/docker/charts/hg-llm/templates/deployment.yaml).



##########
hugegraph-llm/src/hugegraph_llm/operators/index_op/gremlin_example_index_query.py:
##########
@@ -56,16 +55,12 @@ def _get_match_result(self, context: Dict[str, Any], query: 
str) -> List[Dict[st
 
     def _build_default_example_index(self):
         properties = pd.read_csv(os.path.join(resource_path, "demo", 
"text2gremlin.csv")).to_dict(orient="records")
-        from concurrent.futures import ThreadPoolExecutor
-
-        # TODO: reuse the logic in build_semantic_index.py (consider extract 
the batch-embedding method)
-        with ThreadPoolExecutor() as executor:
-            embeddings = list(
-                tqdm(
-                    executor.map(self.embedding.get_text_embedding, 
[row["query"] for row in properties]),
-                    total=len(properties),
-                )
-            )
+        # Some supported services accept at most 10 texts, regardless of the 
adapter default.
+        # Complete each batch sequentially and only publish the index after 
all batches succeed.
+        embeddings = []
+        for start in range(0, len(properties), 10):
+            texts = [row["query"] for row in properties[start : start + 10]]
+            embeddings.extend(self.embedding.get_texts_embeddings(texts))

Review Comment:
   **[P2] Preserve LiteLLM retries when switching the example builder to 
batches**
   
   This changes the cold example-index path from 
`LiteLLMEmbedding.get_text_embedding`, which retries `RateLimitError` / 
`APIConnectionError` / `APIError` up to three times with backoff, to 
`get_texts_embeddings`, which logs and immediately re-raises those errors. A 
transient 429 can now abort example-index construction and the Text2Gremlin 
request where the previous path could recover.
   
   This is reachable with LiteLLM's `hosted_vllm` embedding provider: version 
1.61.20 installed in CI performs one HTTP POST, maps 429 to `RateLimitError`, 
and supplies no embedding-level retry on that path. OpenAI's separate SDK retry 
behavior does not cover this provider.
   
   Please retain bounded retries per batch and add a deterministic 
429-then-success regression, preserving the ten-text limit, ordering, and the 
existing no-save-on-terminal-failure guarantee. This finding is source-derived, 
not a live-provider reproduction.
   
   Sources: [changed 
call](https://github.com/apache/hugegraph-ai/blob/bdf76543dd59cc19da4e3eb1337e2e1d1bdc8a7f/hugegraph-llm/src/hugegraph_llm/operators/index_op/gremlin_example_index_query.py#L56-L65),
 [repository retry 
implementations](https://github.com/apache/hugegraph-ai/blob/bdf76543dd59cc19da4e3eb1337e2e1d1bdc8a7f/hugegraph-llm/src/hugegraph_llm/models/embeddings/litellm.py#L47-L97),
 [provider 
dispatch](https://github.com/BerriAI/litellm/blob/v1.61.20-stable/litellm/main.py#L3481-L3512),
 [single-request 
handler](https://github.com/BerriAI/litellm/blob/v1.61.20-stable/litellm/llms/openai_like/embedding/handler.py#L125-L146),
 [429 
mapping](https://github.com/BerriAI/litellm/blob/v1.61.20-stable/litellm/litellm_core_utils/exception_mapping_utils.py#L424-L432).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to