Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `review_depth: lightweight` annotation for review blocks in `job.yml` step outputs and `.deepreview` rules — when set, the workflow's `common_job_info` preamble is omitted from review instruction files, reducing token overhead for trivial or reversible intermediate steps (closes #86)

### Changed

### Fixed
Expand Down
5 changes: 5 additions & 0 deletions src/deepwork/jobs/job.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@
"description": "If true, includes matching files that were not produced as outputs but exist on disk. Useful for document freshness reviews where the reviewer needs to see the doc even when only source files changed."
}
}
},
"review_depth": {
"type": "string",
"enum": ["lightweight"],
"description": "Optional review depth hint. When set to 'lightweight', the workflow's common_job_info preamble is omitted from the review instruction file, reducing token usage for low-risk or reversible intermediate steps. Step inputs and review criteria are always included. Omit this field for standard depth (default)."
}
}
},
Expand Down
25 changes: 18 additions & 7 deletions src/deepwork/jobs/mcp/quality_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,23 @@ def _build_preamble(
job: JobDefinition,
workflow: Workflow,
input_values: dict[str, ArgumentValue],
review_depth: str | None = None,
) -> str:
"""Build the preamble prefixed to every dynamic review's instructions.

Combines workflow ``common_job_info`` and the rendered step inputs.
Returns an empty string when neither is available.

When ``review_depth`` is ``"lightweight"``, the ``## Job Context`` block
(common_job_info) is omitted to reduce token usage for low-risk steps.
Step inputs are always included regardless of depth.
"""
input_context = _build_input_context(step, job, input_values)
common_info = workflow.common_job_info or ""
preamble_parts: list[str] = []
if common_info:
preamble_parts.append(f"## Job Context\n\n{common_info}")
if review_depth != "lightweight":
common_info = workflow.common_job_info or ""
if common_info:
preamble_parts.append(f"## Job Context\n\n{common_info}")
if input_context:
preamble_parts.append(input_context)
return "\n\n".join(preamble_parts)
Expand Down Expand Up @@ -160,7 +166,6 @@ def build_dynamic_review_rules(
targets.
"""
rules: list[ReviewRule] = []
preamble = _build_preamble(step, job, workflow, input_values)

# Process each output
for output_name, output_ref in step.outputs.items():
Expand Down Expand Up @@ -191,6 +196,9 @@ def build_dynamic_review_rules(
file_paths = []

for i, review_block in enumerate(review_blocks):
# Build preamble, respecting review_depth on this block
preamble = _build_preamble(step, job, workflow, input_values, review_block.review_depth)

# Build full instructions with preamble
full_instructions = (
f"{preamble}\n\n{review_block.instructions}"
Expand Down Expand Up @@ -225,10 +233,11 @@ def build_dynamic_review_rules(
source_dir=project_root,
source_file=job.job_dir / "job.yml",
source_line=0,
review_depth=review_block.review_depth,
)
rules.append(rule)

# Process requirements review
# Process requirements review — always uses standard preamble (no review_depth suppression)
if step.process_requirements and work_summary is not None:
attrs_list = "\n".join(
f"- **{name}**: {statement}" for name, statement in step.process_requirements.items()
Expand All @@ -249,7 +258,8 @@ def build_dynamic_review_rules(

output_context = "\n".join(output_context_parts)

pqa_instructions = f"""{preamble}
pqa_preamble = _build_preamble(step, job, workflow, input_values)
pqa_instructions = f"""{pqa_preamble}

## Process Requirements Review

Expand Down Expand Up @@ -315,7 +325,6 @@ def build_string_output_review_tasks(
``_arg`` to distinguish it (matching the file_path rule naming).
"""
tasks: list[ReviewTask] = []
preamble = _build_preamble(step, job, workflow, input_values)

try:
source_rel = (job.job_dir / "job.yml").relative_to(project_root)
Expand Down Expand Up @@ -345,6 +354,7 @@ def build_string_output_review_tasks(
inline_value = value if isinstance(value, str) else str(value)

for i, review_block in enumerate(review_blocks):
preamble = _build_preamble(step, job, workflow, input_values, review_block.review_depth)
full_instructions = (
f"{preamble}\n\n{review_block.instructions}"
if preamble
Expand All @@ -364,6 +374,7 @@ def build_string_output_review_tasks(
agent_name=agent_name,
source_location=source_location,
inline_content=inline_value,
review_depth=review_block.review_depth,
)
)

Expand Down
2 changes: 2 additions & 0 deletions src/deepwork/jobs/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ReviewBlock:
instructions: str
agent: dict[str, str] | None = None
additional_context: dict[str, bool] | None = None
review_depth: str | None = None # "lightweight" | None (standard)

@classmethod
def from_dict(cls, data: dict[str, Any]) -> "ReviewBlock":
Expand All @@ -35,6 +36,7 @@ def from_dict(cls, data: dict[str, Any]) -> "ReviewBlock":
instructions=data["instructions"],
agent=data.get("agent"),
additional_context=data.get("additional_context"),
review_depth=data.get("review_depth"),
)


Expand Down
5 changes: 5 additions & 0 deletions src/deepwork/review/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class ReviewRule:
source_file: Path # Path to the .deepreview file
source_line: int # Line number of the rule name in the .deepreview file
reference_files: list[ReferenceFile] = field(default_factory=list)
review_depth: str | None = None # "lightweight" | None (standard)


@dataclass
Expand All @@ -65,6 +66,7 @@ class ReviewTask:
precomputed_info_bash_command: str | None = None # Resolved command to run
inline_content: str | None = None # Inline string value for type: string outputs
reference_files: list[ReferenceFile] = field(default_factory=list)
review_depth: str | None = None # "lightweight" | None (standard)


def parse_deepreview_file(filepath: Path) -> list[ReviewRule]:
Expand Down Expand Up @@ -150,6 +152,8 @@ def _parse_rule(

reference_files = _parse_reference_files(review_data.get("reference_files", []), source_dir)

review_depth = review_data.get("review_depth")

return ReviewRule(
name=name,
description=description,
Expand All @@ -165,6 +169,7 @@ def _parse_rule(
source_file=source_file,
source_line=source_line,
reference_files=reference_files,
review_depth=review_depth,
)


Expand Down
3 changes: 3 additions & 0 deletions src/deepwork/review/matcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ def match_files_to_rules(
all_changed_filenames=all_filenames,
precomputed_info_bash_command=precompute_cmd,
reference_files=task_refs,
review_depth=rule.review_depth,
)
)

Expand All @@ -264,6 +265,7 @@ def match_files_to_rules(
all_changed_filenames=all_filenames,
precomputed_info_bash_command=precompute_cmd,
reference_files=rule.reference_files,
review_depth=rule.review_depth,
)
)

Expand All @@ -278,6 +280,7 @@ def match_files_to_rules(
all_changed_filenames=all_filenames,
precomputed_info_bash_command=precompute_cmd,
reference_files=rule.reference_files,
review_depth=rule.review_depth,
)
)

Expand Down
5 changes: 5 additions & 0 deletions src/deepwork/schemas/deepreview_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@
"description": "If true, pulls the full contents of files that match the include patterns even if they weren't modified in this diff."
}
}
},
"review_depth": {
"type": "string",
"enum": ["lightweight"],
"description": "Optional review depth hint. When set to 'lightweight' on a job.yml review block, the workflow's common_job_info preamble is omitted from the review instruction file, reducing token usage for low-risk or reversible intermediate steps. Note: this field has no effect in .deepreview rules — those rules are not associated with a workflow and do not receive common_job_info. Omit for standard depth (default)."
}
}
}
Expand Down
Loading
Loading