Skip to content

run stylecheck #191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 4, 2025
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: 1 addition & 1 deletion .github/workflows/ekline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
permissions: write-all
jobs:
test-pr-review:
if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'No EkLine') == false
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'No EkLine') && !contains(github.event.pull_request.labels.*.name, 'stylecheck')
name: runner / EkLine Reviewer (github-pr-review)
runs-on: ubuntu-latest
steps:
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,18 @@ fern docs dev
### Troubleshooting

If you run into errors, you can add the ` --log-level debug` flag to get more information.

## Stylecheck (Beta)

The `stylecheck.py` script sends a markdown file to Claude Sonnet for revision according to defined style, structure, and terminology rules.

### GitHub action
If a PR has the label `stylecheck` and not the label `stylecheck-complete`, the `stylecheck.py` script runs on any `.md(x)` files changed in the PR. A summary of changes is posted as a comment on the timeline. Suggestions for the diff context are added. If there are any proposed revisions outside the diff context, the full text of the revision is included in the summary comment.

When the action completes, it adds the `stylecheck-complete` tag. If you want stylecheck to run on new changes on a PR where it has already run, remove the `stylecheck-complete` label before pushing the new changes.

### Local execution
To run the script locally and not as part of a PR, set your environment variable `LLM_TOKEN` to your PAT from [OpenWebUI](https://openwebui.dev.devrev-eng.ai/) > **Settings** > **Account** > API Keys. Include the supplemental developer style rules with the `--style` option.
```
python stylecheck.py --style=style/developer.md <path/to/file.mdx>
```
2 changes: 1 addition & 1 deletion llm_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

def get_response(prompt):

auth = os.environ.get('LLM_JWT')
auth = os.environ.get('LLM_TOKEN')
if auth:
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {auth}"}
payload = {
Expand Down
4 changes: 2 additions & 2 deletions style/sample-common.mdx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# DataDog Snap-in

This integration links Datadog's monitoring system with Devrev's incident management, simplifying the process of managing RevOrg incidents triggered by Datadog alerts. It automatically generates new incidents and updates existing incidents in DevRev using data from Datadog, allowing your organisation to address issues efficiently without manual tracking.
This integration links Datadog's monitoring system with Devrev's incident management, simplifying the process of managing RevOrg incidents triggered by Datadog alerts e.g. system failures etc. It automatically generates new incidents and updates existing incidents in DevRev using data from Datadog, allowing your organisation to address issues efficiently without manual tracking.

### System Features

- Automated Incident Creation: When an incident is triggered in Datadog, the snap-in automatically creates a corresponding incident in DevRev.
- Automated Incident Creation: When an incident is triggered in Datadog, the snap-in will automatically create a corresponding incident in DevRev.
- Automated Incident Updation: When an incident is updated in Datadog, the changes are reflected in DevRev.
- Real-time Synchronization: The snap-in ensures that incidents are created or updated in real-time, reducing delays between detection and resolution. DevRev captures the necessary incident details from the Datadog payload, allowing teams to address and mitigate issues.
- Seamless integration: The snap-in is built to streamline workflows, minimizing the need for manual intervention.
Expand Down
11 changes: 6 additions & 5 deletions style/style-common.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Rules

For the writing style, apply the following descriptive keywords to analyzing the draft document:
For the writing style, apply the following descriptive keywords to revising the draft document:

- Writing style: authoritative, comprehensive, helpful
- Sentence structure: varied, complex, cohesive
Expand All @@ -14,13 +14,14 @@ There are also some very specific style rules that need to be followed:
- Use sentence case (only capitalize the first word and proper nouns) in any type of heading, including in two-level lists.
- Ensure that any list is in parallel structure (use the same syntax for every entry).
- Instructions or how-to guides:
- They may use two levels; both should be ordered (numbered) lists, not unordered (bulleted).
- They may use two levels; both should be ordered (numbered) lists, not unordered (bulleted) lists.
- Instructions should be in imperative mood.
- If there is a location or condition in a step, it should be at the front of the sentence, which must still be in imperative.
- Steps should be more than a single click; combine steps if needed to make them more meaningful.
- If there is a location or condition in a step, it should be at the front of the main clause, which must still be in imperative mood.
- Steps should be more than a single "click"; combine steps if needed to make them more meaningful. If there is an outcome of the step stated, it should be part of the same step, not a new step.
- End each list item with a period or other appropriate sentence-ending punctuation, except in the following cases:
- If the item consists of a single word, don't add end punctuation.
- If the item doesn't include a verb, don't add end punctuation.
- If the item is entirely in code font, don't add end punctuation.
- If the item is entirely link text or a document title, don't add end punctuation.
- Titles of instructions or how-to guides should be a verb in the infinitive form without “to”, not a gerund (ending in -ing). Titles of any other type of section should be noun phrases.
- Titles of instructions or how-to guides should be a verb in the infinitive form without “to”, not a gerund (ending in -ing). Titles of any other type of section should be noun phrases.
- Avoid future tense when describing the behavior of the product. Use simple present instead.
28 changes: 20 additions & 8 deletions stylecheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ def gen_prompt(args):
prompt += "\n\n"

with open('style/term-common.csv', 'r', encoding="utf-8") as infile:
prompt += "\n\n<terminology>\n"
prompt += infile.read()
prompt += "\n\n<terminology>\n"
prompt += infile.read()

if args.term and os.path.exists(args.term):
with open(args.style, 'r', encoding="utf-8") as infile:
Expand Down Expand Up @@ -172,10 +172,18 @@ def main(args):
print(f"Checking style for {args.doc}")
doc_name, ext = os.path.splitext(os.path.basename(args.doc))

required_vars = ['REPO_OWNER', 'REPO_NAME', 'PR_NUMBER']
missing_vars = [var for var in required_vars if not os.environ.get(var)]
if args.suggest and missing_vars:
print(f"Skipping pull request suggestions. Missing required environment variables: {', '.join(missing_vars)}")
args.suggest = False

prompt = gen_prompt(args)
my_writer(prompt, f"temp/{doc_name}_prompt.md", 'prompt')

response_file = f"temp/{doc_name}_response.md"
if args.llm:
print("Requesting revision from LLM.")
response = llm_client.get_response(prompt)
my_writer(response, response_file, 'response')
else:
Expand All @@ -190,15 +198,19 @@ def main(args):
comment_text = "✨ Comment from AI reviewer ✨\n\n" + comment_text
revision = llm_client.get_lines_between_tags(response, 'document')
revision = restore_title(args.doc, revision)
revision_file = f"temp/{doc_name}_revision{ext}"

if args.suggest:
revision_file = f"temp/{doc_name}_revision{ext}"
else:
revision_file = args.doc
my_writer(revision, revision_file, 'revision')
diff = create_line_diff(args.doc, revision_file)
my_writer(diff, f"temp/{doc_name}.diff", 'diff')

suggestions = parse_diff_hunks(diff)
my_writer(suggestions, f"temp/{doc_name}_suggestions.json", 'suggestions')
failures = 0
if (args.suggest):
diff = create_line_diff(args.doc, revision_file)
my_writer(diff, f"temp/{doc_name}.diff", 'diff')
suggestions = parse_diff_hunks(diff)
my_writer(suggestions, f"temp/{doc_name}_suggestions.json", 'suggestions')
failures = 0
for suggestion in suggestions:
time.sleep(1)
failures += post_review_comment(suggestion)
Expand Down
Loading