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]

Reply via email to