Rifqi Hafizuddin Claude Opus 4.8 commited on
Commit
272a186
·
1 Parent(s): 6d46ba5

[NOTICKET][AI] Planner: drop parallelizable_with from Task

Browse files

Remove the unused parallelizable_with field and its validator check (5).
TaskRunner derives parallelism from depends_on alone, so the field was
redundant. Strips it from schema, validator, all few-shots (A-D), and the
planner prompt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

src/agents/planner/examples.py CHANGED
@@ -1,7 +1,7 @@
1
  """Few-shot examples for the planner prompt.
2
 
3
  Two illustrative (question -> TaskList) pairs that teach the OUTPUT SHAPE:
4
- stages, dependency edges, parallelism, ordered tool-call chains, inline QueryIR,
5
  "${t<id>}" placeholders, and the assumed data-flow convention — `query_structured`
6
  pulls rows, then a composite `analyze_*` tool consumes them via a `data` placeholder
7
  referencing the upstream result's column aliases (Pattern A; the tool team may
@@ -40,7 +40,6 @@ _EXAMPLE_A = TaskList(
40
  expected_output="source_shape",
41
  success_criteria="Produced the orders table schema; the 3 needed columns are present.",
42
  depends_on=[],
43
- parallelizable_with=[],
44
  estimated_cost="low",
45
  ),
46
  Task(
@@ -74,7 +73,6 @@ _EXAMPLE_A = TaskList(
74
  expected_output="quarter_rows",
75
  success_criteria="Produced last quarter's order rows with category and revenue.",
76
  depends_on=["t1"],
77
- parallelizable_with=[],
78
  estimated_cost="medium",
79
  ),
80
  Task(
@@ -95,7 +93,6 @@ _EXAMPLE_A = TaskList(
95
  expected_output="category_contribution",
96
  success_criteria="Produced each category's revenue share, ranked high to low.",
97
  depends_on=["t2"],
98
- parallelizable_with=[],
99
  estimated_cost="low",
100
  ),
101
  ],
@@ -120,7 +117,6 @@ _EXAMPLE_B = TaskList(
120
  expected_output="source_shape",
121
  success_criteria="Produced the orders table schema; the needed columns are present.",
122
  depends_on=[],
123
- parallelizable_with=[],
124
  estimated_cost="low",
125
  ),
126
  Task(
@@ -159,7 +155,6 @@ _EXAMPLE_B = TaskList(
159
  expected_output="ytd_rows",
160
  success_criteria="Produced this year's order-level rows with date, revenue, region.",
161
  depends_on=["t1"],
162
- parallelizable_with=[],
163
  estimated_cost="medium",
164
  ),
165
  Task(
@@ -184,7 +179,6 @@ _EXAMPLE_B = TaskList(
184
  "flag months above/below the typical level."
185
  ),
186
  depends_on=["t2"],
187
- parallelizable_with=[],
188
  estimated_cost="low",
189
  ),
190
  ],
@@ -215,7 +209,6 @@ _EXAMPLE_C = TaskList(
215
  expected_output="source_shape",
216
  success_criteria="Produced the orders table schema; date and revenue columns present.",
217
  depends_on=[],
218
- parallelizable_with=["t4"],
219
  estimated_cost="low",
220
  ),
221
  Task(
@@ -253,7 +246,6 @@ _EXAMPLE_C = TaskList(
253
  expected_output="q1_rows",
254
  success_criteria="Produced Q1 order rows with date and revenue.",
255
  depends_on=["t1"],
256
- parallelizable_with=[],
257
  estimated_cost="medium",
258
  ),
259
  Task(
@@ -275,7 +267,6 @@ _EXAMPLE_C = TaskList(
275
  expected_output="q1_trend",
276
  success_criteria="Produced a per-month revenue series showing where revenue fell.",
277
  depends_on=["t2"],
278
- parallelizable_with=[],
279
  estimated_cost="low",
280
  ),
281
  Task(
@@ -294,7 +285,6 @@ _EXAMPLE_C = TaskList(
294
  expected_output="q1_context_chunks",
295
  success_criteria="Produced relevant document chunks about Q1 operations.",
296
  depends_on=[],
297
- parallelizable_with=["t1"],
298
  estimated_cost="low",
299
  ),
300
  ],
@@ -324,7 +314,6 @@ _EXAMPLE_D = TaskList(
324
  expected_output="source_shape",
325
  success_criteria="Produced the orders table schema; region and revenue present.",
326
  depends_on=[],
327
- parallelizable_with=[],
328
  estimated_cost="low",
329
  ),
330
  Task(
@@ -350,7 +339,6 @@ _EXAMPLE_D = TaskList(
350
  expected_output="region_rows",
351
  success_criteria="Produced order rows with region and revenue.",
352
  depends_on=["t1"],
353
- parallelizable_with=[],
354
  estimated_cost="medium",
355
  ),
356
  Task(
@@ -370,7 +358,6 @@ _EXAMPLE_D = TaskList(
370
  expected_output="region_aggregates",
371
  success_criteria="Produced one row per region with mean and total revenue.",
372
  depends_on=["t2"],
373
- parallelizable_with=[],
374
  estimated_cost="low",
375
  ),
376
  ],
 
1
  """Few-shot examples for the planner prompt.
2
 
3
  Two illustrative (question -> TaskList) pairs that teach the OUTPUT SHAPE:
4
+ stages, dependency edges, ordered tool-call chains, inline QueryIR,
5
  "${t<id>}" placeholders, and the assumed data-flow convention — `query_structured`
6
  pulls rows, then a composite `analyze_*` tool consumes them via a `data` placeholder
7
  referencing the upstream result's column aliases (Pattern A; the tool team may
 
40
  expected_output="source_shape",
41
  success_criteria="Produced the orders table schema; the 3 needed columns are present.",
42
  depends_on=[],
 
43
  estimated_cost="low",
44
  ),
45
  Task(
 
73
  expected_output="quarter_rows",
74
  success_criteria="Produced last quarter's order rows with category and revenue.",
75
  depends_on=["t1"],
 
76
  estimated_cost="medium",
77
  ),
78
  Task(
 
93
  expected_output="category_contribution",
94
  success_criteria="Produced each category's revenue share, ranked high to low.",
95
  depends_on=["t2"],
 
96
  estimated_cost="low",
97
  ),
98
  ],
 
117
  expected_output="source_shape",
118
  success_criteria="Produced the orders table schema; the needed columns are present.",
119
  depends_on=[],
 
120
  estimated_cost="low",
121
  ),
122
  Task(
 
155
  expected_output="ytd_rows",
156
  success_criteria="Produced this year's order-level rows with date, revenue, region.",
157
  depends_on=["t1"],
 
158
  estimated_cost="medium",
159
  ),
160
  Task(
 
179
  "flag months above/below the typical level."
180
  ),
181
  depends_on=["t2"],
 
182
  estimated_cost="low",
183
  ),
184
  ],
 
209
  expected_output="source_shape",
210
  success_criteria="Produced the orders table schema; date and revenue columns present.",
211
  depends_on=[],
 
212
  estimated_cost="low",
213
  ),
214
  Task(
 
246
  expected_output="q1_rows",
247
  success_criteria="Produced Q1 order rows with date and revenue.",
248
  depends_on=["t1"],
 
249
  estimated_cost="medium",
250
  ),
251
  Task(
 
267
  expected_output="q1_trend",
268
  success_criteria="Produced a per-month revenue series showing where revenue fell.",
269
  depends_on=["t2"],
 
270
  estimated_cost="low",
271
  ),
272
  Task(
 
285
  expected_output="q1_context_chunks",
286
  success_criteria="Produced relevant document chunks about Q1 operations.",
287
  depends_on=[],
 
288
  estimated_cost="low",
289
  ),
290
  ],
 
314
  expected_output="source_shape",
315
  success_criteria="Produced the orders table schema; region and revenue present.",
316
  depends_on=[],
 
317
  estimated_cost="low",
318
  ),
319
  Task(
 
339
  expected_output="region_rows",
340
  success_criteria="Produced order rows with region and revenue.",
341
  depends_on=["t1"],
 
342
  estimated_cost="medium",
343
  ),
344
  Task(
 
358
  expected_output="region_aggregates",
359
  success_criteria="Produced one row per region with mean and total revenue.",
360
  depends_on=["t2"],
 
361
  estimated_cost="low",
362
  ),
363
  ],
src/agents/planner/schemas.py CHANGED
@@ -42,7 +42,6 @@ class Task(BaseModel):
42
  expected_output: str # named result this task produces
43
  success_criteria: str # REPORTING signal, not a control trigger
44
  depends_on: list[str] = Field(default_factory=list) # task ids
45
- parallelizable_with: list[str] = Field(default_factory=list)
46
  estimated_cost: Literal["low", "medium", "high"] = "low"
47
 
48
 
 
42
  expected_output: str # named result this task produces
43
  success_criteria: str # REPORTING signal, not a control trigger
44
  depends_on: list[str] = Field(default_factory=list) # task ids
 
45
  estimated_cost: Literal["low", "medium", "high"] = "low"
46
 
47
 
src/agents/planner/validator.py CHANGED
@@ -113,9 +113,6 @@ class PlannerValidator:
113
  # Check 4 — DAG: edges resolve, placeholders resolve, no cycles.
114
  self._validate_dag(tasks_by_id, id_set)
115
 
116
- # Check 5 — parallelizable_with is consistent with the dependency graph.
117
- self._validate_parallelism(tasks_by_id, id_set)
118
-
119
  def _validate_inline_ir(self, task_id: str, args: dict, catalog: Catalog) -> None:
120
  raw_ir = args.get("ir")
121
  if not isinstance(raw_ir, dict):
@@ -170,26 +167,6 @@ class PlannerValidator:
170
  f"not a (transitive) dependency — add it to depends_on"
171
  )
172
 
173
- @staticmethod
174
- def _validate_parallelism(tasks_by_id: dict, id_set: set[str]) -> None:
175
- ancestors = _all_ancestors(tasks_by_id)
176
- for task in tasks_by_id.values():
177
- for other in task.parallelizable_with:
178
- if other not in id_set:
179
- raise PlannerValidationError(
180
- f"task {task.id}: parallelizable_with references unknown task "
181
- f"{other!r}"
182
- )
183
- if other == task.id:
184
- raise PlannerValidationError(
185
- f"task {task.id}: parallelizable_with includes itself"
186
- )
187
- if other in ancestors[task.id] or task.id in ancestors[other]:
188
- raise PlannerValidationError(
189
- f"task {task.id}: parallelizable_with {other!r} conflicts with a "
190
- f"(transitive) depends_on relationship between them"
191
- )
192
-
193
 
194
  def _is_placeholder(value: str) -> bool:
195
  return bool(_PLACEHOLDER_RE.fullmatch(value.strip()))
 
113
  # Check 4 — DAG: edges resolve, placeholders resolve, no cycles.
114
  self._validate_dag(tasks_by_id, id_set)
115
 
 
 
 
116
  def _validate_inline_ir(self, task_id: str, args: dict, catalog: Catalog) -> None:
117
  raw_ir = args.get("ir")
118
  if not isinstance(raw_ir, dict):
 
167
  f"not a (transitive) dependency — add it to depends_on"
168
  )
169
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
  def _is_placeholder(value: str) -> bool:
172
  return bool(_PLACEHOLDER_RE.fullmatch(value.strip()))
src/config/prompts/planner.md CHANGED
@@ -41,8 +41,6 @@ only a `TaskList` object that conforms to the provided schema.
41
  (referencing the upstream result's column aliases).
42
  - **Mixing structured + unstructured.** If qualitative context helps, add a
43
  `retrieve_documents` task against an unstructured source listed in the catalog.
44
- - **Parallelism.** List sibling tasks that have no data dependency on each other
45
- in `parallelizable_with` (must be mutually consistent with `depends_on`).
46
  - **CRISP-DM stages.** Tag each task with the stage it serves:
47
  `data_understanding`, `data_preparation`, or `evaluation`. (Never `modeling`.)
48
  - **success_criteria is a reporting signal**, not a control trigger. State, in
 
41
  (referencing the upstream result's column aliases).
42
  - **Mixing structured + unstructured.** If qualitative context helps, add a
43
  `retrieve_documents` task against an unstructured source listed in the catalog.
 
 
44
  - **CRISP-DM stages.** Tag each task with the stage it serves:
45
  `data_understanding`, `data_preparation`, or `evaluation`. (Never `modeling`.)
46
  - **success_criteria is a reporting signal**, not a control trigger. State, in