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]