Copilot commented on code in PR #351:
URL: https://github.com/apache/hugegraph-ai/pull/351#discussion_r3338474345
##########
hugegraph-llm/src/hugegraph_llm/api/models/rag_requests.py:
##########
@@ -164,3 +165,67 @@ def validate_prompt_placeholders(cls, v):
if missing:
raise ValueError(f"Prompt template is missing required
placeholders: {', '.join(missing)}")
return v
+
+
+class GraphExtractRequest(BaseModel):
+ model_config = ConfigDict(populate_by_name=True)
+
+ texts: Union[str, List[str]] = Field(..., description="Text or list of
texts to extract a graph from.")
+ graph_schema: Union[str, Dict[str, Any]] = Field(
+ ...,
+ alias="schema",
+ description="Graph schema as a JSON string/object, or an existing
graph name.",
+ )
+ example_prompt: Optional[str] = Query(None, description="Optional graph
extraction prompt header.")
+ extract_type: Literal["triples", "property_graph"] =
Query("property_graph", description="Extraction type.")
+ language: Literal["zh", "en"] = Query("zh", description="Language for
chunk splitting.")
+ split_type: Literal["document", "paragraph", "sentence"] =
Query("document", description="Chunk split granularity.")
+ include_meta: bool = Query(False, description="Include vertex/edge/text
counts in the response.")
+ client_config: Optional[GraphConfigRequest] = Field(None,
description="hugegraph server config.")
+
+ @field_validator("texts")
+ @classmethod
+ def normalize_texts(cls, v):
+ items = [v] if isinstance(v, str) else list(v)
+ items = [t for t in items if t and t.strip()]
+ if not items:
+ raise ValueError("texts must not be empty.")
+ return items
+
+ @field_validator("graph_schema")
+ @classmethod
+ def normalize_schema(cls, v):
+ def validate_schema_obj(schema_obj):
+ if not isinstance(schema_obj, dict):
+ raise ValueError("schema JSON must be an object.")
+ if "vertexlabels" not in schema_obj or "edgelabels" not in
schema_obj:
+ raise ValueError("schema must contain 'vertexlabels' and
'edgelabels'.")
+ if not isinstance(schema_obj["vertexlabels"], list) or not
isinstance(schema_obj["edgelabels"], list):
+ raise ValueError("'vertexlabels' and 'edgelabels' must be
lists.")
+
+ if isinstance(v, dict):
+ validate_schema_obj(v)
+ return json.dumps(v, ensure_ascii=False)
+ v = v.strip()
+ if not v:
+ raise ValueError("schema must not be empty.")
+ if v.startswith("{"):
+ try:
+ validate_schema_obj(json.loads(v))
+ except json.JSONDecodeError as e:
+ raise ValueError(f"Invalid JSON schema: {e}") from e
+ return v
+ return v
+
+ @model_validator(mode="after")
+ def require_client_config_for_named_schema(self):
+ # A named-graph schema needs request-scoped connection settings;
inline JSON
+ # schemas (starting with "{") are self-contained and never hit
HugeGraph.
+ schema = self.graph_schema
+ is_named_schema = isinstance(schema, str) and not
schema.strip().startswith("{")
+ if is_named_schema and self.client_config is None:
+ raise ValueError(
+ "client_config is required when 'schema' refers to an existing
graph name; "
+ "provide inline schema JSON instead to extract without a
HugeGraph connection."
+ )
+ return self
Review Comment:
When `schema` is a named graph (e.g. `"custom_graph"`), it is used as both
the schema identifier and the HugeGraph `graph_name` passed to `SchemaManager`
(see `SchemaNode._import_schema` / `schema.py:42-48`). The
`client_config.graph` field provided by the client is never consulted on this
code path — only `url`, `user`, `pwd`, and `gs` are read in
`GraphExtractFlow.prepare` (`graph_extract.py:50-55`). If a caller submits
`schema="custom_graph"` with `client_config.graph="other_graph"`, the mismatch
is silently ignored and the request hits `custom_graph`.
Consider either (a) using `client_config.graph` as the graph name and
treating `schema` purely as a schema reference, or (b) adding a model validator
that rejects requests where `schema` is a name and `client_config.graph` is set
to a different value, so the contract is unambiguous.
--
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]