Ma77Ball commented on code in PR #6436:
URL: https://github.com/apache/texera/pull/6436#discussion_r3633773365


##########
agent-service/src/recommender/hardcoded-rules.ts:
##########
@@ -0,0 +1,211 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Hardcoded "what usually comes next" table for the Version 1 operator
+ * recommender (apache/texera#5240). Kept deliberately small and readable: a
+ * coarse category per operator, a ranked successor list per category, plus a
+ * handful of specific overrides for the most common dataflow patterns.
+ *
+ * Operator type strings here must match the `@JsonSubTypes` names registered 
on
+ * `LogicalOp` (the catalog the frontend and compiler use). Suggestions are
+ * validated against the live operator catalog before being returned, so a 
stale
+ * entry here degrades to "not suggested" rather than to a broken suggestion.
+ */
+
+export type OperatorCategory = "source" | "transform" | "aggregate" | "join" | 
"order" | "udf" | "ml" | "sink";
+
+/**
+ * Explicit category for operators whose successors don't follow from a naming
+ * heuristic. Operators absent here fall back to {@link inferCategory}.
+ */
+const OPERATOR_CATEGORY: Record<string, OperatorCategory> = {
+  // Sources — read data into the workflow.
+  CSVFileScan: "source",
+  CSVOldFileScan: "source",
+  ParallelCSVFileScan: "source",
+  JSONLFileScan: "source",
+  FileScan: "source",
+  ArrowSource: "source",
+  TextInput: "source",
+  URLFetcher: "source",
+  FileLister: "source",
+  PostgreSQLSource: "source",
+  MySQLSource: "source",
+  AsterixDBSource: "source",
+  SQLSource: "source",
+  TwitterSearch: "source",
+  TwitterFullArchiveSearch: "source",
+  RedditSearch: "source",
+  PythonUDFSourceV2: "source",
+  RUDFSource: "source",
+
+  // Transforms — reshape rows/columns.
+  Filter: "transform",
+  Projection: "transform",
+  TypeCasting: "transform",
+  Regex: "transform",
+  KeywordSearch: "transform",
+  SubstringSearch: "transform",
+  DictionaryMatcher: "transform",
+  UnnestString: "transform",
+  Split: "transform",
+
+  // Aggregations / reducers.
+  Aggregate: "aggregate",
+  PythonTableReducer: "aggregate",
+  Scorer: "aggregate",
+
+  // Joins and set operations (multi-input).
+  HashJoin: "join",
+  IntervalJoin: "join",
+  CartesianProduct: "join",
+  Union: "join",
+  Intersect: "join",
+  Difference: "join",
+  SymmetricDifference: "join",
+
+  // Ordering / sampling / row-count operators.
+  Sort: "order",
+  SortPartitions: "order",
+  StableMergeSort: "order",
+  Limit: "order",
+  Distinct: "order",
+  RandomKSampling: "order",
+  ReservoirSampling: "order",
+
+  // User-defined functions.
+  PythonUDFV2: "udf",
+  DualInputPortsPythonUDFV2: "udf",
+  PythonLambdaFunction: "udf",
+  JavaUDF: "udf",
+  RUDF: "udf",
+};
+
+/** Ranked successor list per category, most-likely first. */
+const CATEGORY_SUCCESSORS: Record<OperatorCategory, string[]> = {
+  source: ["Filter", "Projection", "TypeCasting", "KeywordSearch"],
+  transform: ["Aggregate", "Projection", "Sort", "PythonUDFV2"],
+  aggregate: ["BarChart", "LineChart", "Sort"],
+  join: ["Projection", "Aggregate", "Filter"],
+  order: ["Aggregate", "Projection", "BarChart"],
+  udf: ["Filter", "Projection", "Aggregate"],
+  ml: ["Scorer", "PythonUDFV2"],
+  // Sinks (charts / visualizers) are terminal: no successor is suggested.
+  sink: [],
+};
+
+/**
+ * Per-operator overrides for the highest-value flows. Takes precedence over 
the
+ * category successors above.
+ */
+const SPECIFIC_SUCCESSORS: Record<string, string[]> = {
+  CSVFileScan: ["Filter", "Projection", "KeywordSearch"],
+  JSONLFileScan: ["Projection", "Filter", "UnnestString"],
+  Filter: ["Aggregate", "Projection", "Sort"],
+  Projection: ["Aggregate", "Filter", "Sort"],
+  Aggregate: ["BarChart", "LineChart", "Sort"],

Review Comment:
   `SPECIFIC_SUCCESSORS.Aggregate` is byte-identical to the `aggregate` 
category successors (line 105), so this override is a no-op. Delete it and let 
the category rule apply.
   
   ```suggestion
   ```



-- 
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]

Reply via email to