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
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,10 @@ jobs:

The `review_depth` input controls which model and reasoning effort are used for code reviews. Two presets are available:

| Depth | Model | Reasoning Effort | Best For |
| ----------- | -------------- | ---------------- | ------------------------------------------------------- |
| **deep** | `gpt-5.2` | `high` | Thorough reviews catching subtle bugs and design issues |
| **shallow** | `kimi-k2-0711` | default | Fast, cost-effective reviews for straightforward PRs |
| Depth | Model | Reasoning Effort | Best For |
| ----------- | ----------- | ---------------- | ------------------------------------------------------- |
| **deep** | `gpt-5.2` | `high` | Thorough reviews catching subtle bugs and design issues |
| **shallow** | `kimi-k2.6` | default | Fast, cost-effective reviews for straightforward PRs |

**Examples:**

Expand Down Expand Up @@ -262,7 +262,7 @@ The `review_depth` input controls which model and reasoning effort are used for

> **Tip:** Setting `review_model` or `reasoning_effort` explicitly always takes priority over the depth preset. You can mix and match -- for example, use `review_depth: shallow` but override just `reasoning_effort: high` to get the shallow model with higher reasoning.

The default models (`gpt-5.2` for `deep`, `kimi-k2-0711` for `shallow`) are managed by Factory and may change over time. To pin a specific model regardless of the depth preset, set `review_model` to any model ID supported by `droid exec --model`. A few common choices:
The default models (`gpt-5.2` for `deep`, `kimi-k2.6` for `shallow`) are managed by Factory and may change over time. To pin a specific model regardless of the depth preset, set `review_model` to any model ID supported by `droid exec --model`. A few common choices:

- `claude-opus-4-7`
- `claude-sonnet-4-6`
Expand Down
3 changes: 2 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ inputs:
required: false
default: "7"
review_depth:
description: "Review depth preset: 'shallow' (fast, uses kimi-k2-0711) or 'deep' (thorough, uses gpt-5.2 with high reasoning). Defaults to deep. Setting review_model or reasoning_effort explicitly overrides the preset values."
description: "Review depth preset: 'shallow' (fast, uses kimi-k2.6) or 'deep' (thorough, uses gpt-5.2 with high reasoning). Defaults to deep. Setting review_model or reasoning_effort explicitly overrides the preset values."
required: false
default: "deep"
review_model:
Expand Down Expand Up @@ -352,6 +352,7 @@ runs:
USE_STICKY_COMMENT: ${{ inputs.use_sticky_comment }}
TRACK_PROGRESS: ${{ inputs.track_progress }}
AUTOMATIC_REVIEW: ${{ inputs.automatic_review }}
AUTOMATIC_SECURITY_REVIEW: ${{ inputs.automatic_security_review }}

- name: Collect .factory debug files
if: always() && steps.prepare.outputs.contains_trigger == 'true'
Expand Down
2 changes: 1 addition & 1 deletion review/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ inputs:
description: "ID of the tracking comment to update"
required: true
review_depth:
description: "Review depth preset: 'shallow' (fast, uses kimi-k2-0711) or 'deep' (thorough, uses gpt-5.2 with high reasoning). Defaults to deep. Setting review_model or reasoning_effort explicitly overrides the preset values."
description: "Review depth preset: 'shallow' (fast, uses kimi-k2.6) or 'deep' (thorough, uses gpt-5.2 with high reasoning). Defaults to deep. Setting review_model or reasoning_effort explicitly overrides the preset values."
required: false
default: "deep"
review_model:
Expand Down
1 change: 0 additions & 1 deletion src/create-prompt/templates/review-validator-prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ After writing \`${reviewValidatedPath}\`, post comments ONLY for \`status === "a
* Do **NOT** post comments individually — batch them all into one \`submit_review\` call.
* Do **NOT** include a \`body\` parameter in \`submit_review\`.
* Use \`github_comment___update_droid_comment\` to update the tracking comment with the review summary.
* If any approved comments contain \`[security]\` in their body, prepend a security badge to the tracking comment: \`![Security Review](https://img.shields.io/badge/security%20review-ran-blue)\`. This indicates that security analysis was performed as part of the review.
* Do **NOT** post the summary as a separate comment or as the body of \`submit_review\`.
* Do not approve or request changes.
`;
Expand Down
1 change: 1 addition & 0 deletions src/entrypoints/update-comment-link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ async function run() {
branchName: undefined,
triggerUsername,
errorDetails,
securityReviewRan: process.env.AUTOMATIC_SECURITY_REVIEW === "true",
};

const updatedBody = updateCommentBody(commentInput);
Expand Down
9 changes: 9 additions & 0 deletions src/github/operations/comment-logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ export type CommentUpdateInput = {
branchName?: string;
triggerUsername?: string;
errorDetails?: string;
securityReviewRan?: boolean;
};

export const SECURITY_REVIEW_BADGE =
"![Security Review](https://img.shields.io/badge/security%20review-ran-blue)";

export function ensureProperlyEncodedUrl(url: string): string | null {
try {
// First, try to parse the URL to see if it's already properly encoded
Expand Down Expand Up @@ -77,6 +81,7 @@ export function updateCommentBody(input: CommentUpdateInput): string {
branchName,
triggerUsername,
errorDetails,
securityReviewRan,
} = input;

// Extract content from the original comment body
Expand Down Expand Up @@ -209,6 +214,10 @@ export function updateCommentBody(input: CommentUpdateInput): string {
// Remove any existing duration info at the bottom
bodyContent = bodyContent.replace(/\n*---\n*Duration: [0-9]+m? [0-9]+s/g, "");

if (securityReviewRan && !bodyContent.includes("security%20review-ran")) {
bodyContent = `${SECURITY_REVIEW_BADGE}\n\n${bodyContent}`.trim();
}

// Add the cleaned body content
newBody += bodyContent;

Expand Down
2 changes: 1 addition & 1 deletion src/utils/review-depth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export enum ReviewDepth {
}

const SHALLOW_DEFAULTS = {
model: "kimi-k2-0711",
model: "kimi-k2.6",
reasoningEffort: undefined as string | undefined,
};

Expand Down
58 changes: 58 additions & 0 deletions test/comment-logic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,4 +441,62 @@ describe("updateCommentBody", () => {
expect(result).not.toContain("tree/droid/issue-123");
});
});

describe("security review badge", () => {
const SHIELD_URL_FRAGMENT = "security%20review-ran";

it("prepends the security badge when securityReviewRan is true", () => {
const input: CommentUpdateInput = {
...baseInput,
currentBody: "Droid is reviewing code and running a security check…",
executionDetails: { duration_ms: 60000 },
securityReviewRan: true,
};

const result = updateCommentBody(input);
expect(result).toContain(SHIELD_URL_FRAGMENT);
expect(result).toContain(
"![Security Review](https://img.shields.io/badge/security%20review-ran-blue)",
);
});

it("does not add the badge when securityReviewRan is false", () => {
const input: CommentUpdateInput = {
...baseInput,
currentBody: "Droid is working…",
executionDetails: { duration_ms: 60000 },
securityReviewRan: false,
};

const result = updateCommentBody(input);
expect(result).not.toContain(SHIELD_URL_FRAGMENT);
});

it("does not add the badge when securityReviewRan is undefined", () => {
const input: CommentUpdateInput = {
...baseInput,
currentBody: "Droid is working…",
executionDetails: { duration_ms: 60000 },
};

const result = updateCommentBody(input);
expect(result).not.toContain(SHIELD_URL_FRAGMENT);
});

it("does not double-prepend when the badge is already present", () => {
const input: CommentUpdateInput = {
...baseInput,
currentBody:
"Droid is reviewing code and running a security check…\n\n" +
"![Security Review](https://img.shields.io/badge/security%20review-ran-blue)\n\n" +
"Validator approved 2 findings.",
executionDetails: { duration_ms: 60000 },
securityReviewRan: true,
};

const result = updateCommentBody(input);
const occurrences = result.split(SHIELD_URL_FRAGMENT).length - 1;
expect(occurrences).toBe(1);
});
});
});
Loading