Skip to content

Commit e0a7fc3

Browse files
committed
pushing up work
0 parents  commit e0a7fc3

File tree

820 files changed

+2493
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

820 files changed

+2493
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
debug/
2+
.env
3+
Cargo.lock

CODE_OF_CONDUCT.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
6+
7+
## Our Standards
8+
9+
Examples of behavior that contributes to creating a positive environment include:
10+
11+
* Using welcoming and inclusive language
12+
* Being respectful of differing viewpoints and experiences
13+
* Gracefully accepting constructive criticism
14+
* Focusing on what is best for the community
15+
* Showing empathy towards other community members
16+
17+
Examples of unacceptable behavior by participants include:
18+
19+
* The use of sexualized language or imagery and unwelcome sexual attention or advances
20+
* Trolling, insulting/derogatory comments, and personal or political attacks
21+
* Public or private harassment
22+
* Publishing others' private information, such as a physical or electronic address, without explicit permission
23+
* Other conduct which could reasonably be considered inappropriate in a professional setting
24+
25+
## Our Responsibilities
26+
27+
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28+
29+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30+
31+
## Scope
32+
33+
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34+
35+
## Enforcement
36+
37+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38+
39+
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40+
41+
## Attribution
42+
43+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html)

CONTRIBUTING.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Contributing to ChatGPT Language Check GitHub Action
2+
3+
We appreciate your interest in contributing to GPT Language Check GitHub Action! This document provides guidelines and instructions for contributing to the project.
4+
5+
## Code of Conduct
6+
7+
By participating in this project, you agree to abide by our [Code of Conduct](CODE_OF_CONDUCT.md). Please read it before contributing.
8+
9+
## Reporting Issues
10+
11+
If you find a bug, have a question, or want to request a new feature, please [create an issue](https://github.com/bencgreenberg/github-action-gpt-language-check/issues/new) in the project repository. When reporting a bug, please include:
12+
13+
- A clear and descriptive title
14+
- Steps to reproduce the issue
15+
- The expected behavior
16+
- The actual behavior you observed
17+
- Any relevant error messages or screenshots
18+
19+
## Submitting Changes
20+
21+
To contribute to this project, please follow these steps:
22+
23+
1. Fork the repository on GitHub.
24+
2. Create a new branch for your changes. Use a descriptive name, such as `fix-bug-xyz` or `add-new-feature-abc`.
25+
3. Make your changes in the new branch.
26+
4. Ensure your changes do not break any tests or introduce new issues by running tests and linters.
27+
5. Commit your changes, using clear and descriptive commit messages.
28+
6. Push your changes to your fork on GitHub.
29+
7. Create a [pull request](https://github.com/bencgreenberg/github-action-gpt-language-check/compare) to the main repository.
30+
31+
Please keep your pull request focused on a single issue or feature. If you have multiple unrelated changes, create separate pull requests for each.
32+
33+
## Code Style and Conventions
34+
35+
Please follow the code style and conventions used throughout the project. This may include:
36+
37+
- Indentation and whitespace
38+
- Naming conventions for variables, functions, and classes
39+
- Code organization and structure
40+
- Comments and documentation
41+
42+
If the project uses any linters or formatters, please ensure your changes conform to the configuration provided.
43+
44+
## Testing
45+
46+
If your changes include new functionality or fix a bug, please include tests that cover the new or updated code. Tests should be clear, comprehensive, and pass on all supported platforms.
47+
48+
## Documentation
49+
50+
When you make changes that affect how the project is used or configured, please update the relevant documentation, such as README files, API documentation, or user guides.
51+
52+
## Getting Help
53+
54+
If you have questions or need help with contributing, please [create an issue](https://github.com/bencgreenberg/github-action-gpt-language-check/issues/new) or reach out to the project maintainers through the preferred communication channels.
55+
56+
Thank you for contributing to ChatGPT Language Check GitHub Action!

Cargo.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "github-action-gpt-language-check"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
reqwest = { version = "0.11", features = ["json"] }
10+
tokio = { version = "1", features = ["full"] }
11+
serde = { version = "1.0", features = ["derive"] }
12+
serde_json = "1.0"
13+
14+
[dev-dependencies]
15+
mockito = "0.30"

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Ben Greenberg
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# GitHub Action: GPT Language Check
2+
3+
This GitHub action reviews markdown files in your pull requests for potentially discriminatory language, including but not limited to ableism, ageism, racism, antisemitism, Islamophobia, and similar issues. It uses the OpenAI GPT-4 language model to detect discriminatory language and provides suggestions for alternative language.
4+
5+
## Usage
6+
7+
To use this action in your repository, follow these steps:
8+
9+
1. Set up the `OPENAI_API_KEY` secret in your GitHub repository. You can find more information about setting up secrets in the [GitHub documentation](https://docs.github.com/en/actions/security-guides/encrypted-secrets).
10+
11+
2. Create a new file named `review_markdown.yml` in the `.github/workflows` directory of your repository.
12+
13+
3. Copy the contents of the [sample `review_markdown.yml` file](docs/review_markdown.yml) into the newly created file.
14+
15+
4. Commit and push your changes to the repository.
16+
17+
When a pull request is created or updated with changes to markdown files, this action will review them for potentially discriminatory language and add a comment to the pull request with suggestions for alternative language if any issues are found.
18+
19+
## Contributing
20+
21+
If you would like to contribute to this project, please read the [contributing guidelines](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md).
22+
23+
## License
24+
25+
This project is licensed under the [MIT License](LICENSE).

docs/review_markdown.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Review Markdown
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- '**/*.md'
7+
8+
jobs:
9+
review_markdown:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout repository
14+
uses: actions/checkout@v2
15+
16+
- name: Get the latest release URL
17+
id: get_latest_release
18+
uses: actions/github-script@v5
19+
with:
20+
script: |
21+
const response = await github.rest.repos.getLatestRelease({
22+
owner: 'bencgreenberg',
23+
repo: 'github-action-gpt-language-check'
24+
});
25+
const asset = response.data.assets.find(asset => asset.name === 'github-action-gpt-language-check');
26+
if (!asset) {
27+
throw new Error('Binary not found in the latest release');
28+
}
29+
return { url: asset.browser_download_url };
30+
env:
31+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32+
33+
34+
- name: Download pre-built Rust script from remote repository
35+
run: |
36+
wget "${{ steps.get_latest_release.outputs.url }}" -O github-action-gpt-language-check
37+
chmod +x github-action-gpt-language-check
38+
39+
- name: Run Rust script for each markdown file
40+
env:
41+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
42+
run: |
43+
suggestions=""
44+
for file in $(find . -type f -iname "*.md"); do
45+
echo "Reviewing: $file"
46+
suggestion=$(./github-action-gpt-language-check "$file")
47+
if [[ ! -z "$suggestion" ]]; then
48+
suggestions+="- $file: $suggestion\n"
49+
echo "Suggestion found"
50+
echo "SUGGESTION_FOUND=true" >> $GITHUB_ENV
51+
fi
52+
done
53+
echo "SUGGESTIONS=$suggestions" >> $GITHUB_ENV
54+
55+
56+
57+
- name: Add a comment to the pull request
58+
if: ${{ env.SUGGESTION_FOUND == 'true' }}
59+
uses: actions/github-script@v5
60+
with:
61+
script: |
62+
const suggestions = `Suggested changes: ${process.env.SUGGESTIONS}`
63+
github.rest.issues.createComment({
64+
issue_number: context.issue.number,
65+
owner: context.repo.owner,
66+
repo: context.repo.repo,
67+
body: suggestions
68+
});
69+

src/main.rs

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
use reqwest::Client;
2+
use serde::{Serialize};
3+
use serde_json::Value;
4+
use std::error::Error;
5+
use std::fmt;
6+
7+
#[derive(Debug)]
8+
struct SuggestionError(String);
9+
10+
impl fmt::Display for SuggestionError {
11+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
12+
write!(f, "{}", self.0)
13+
}
14+
}
15+
16+
impl Error for SuggestionError {}
17+
18+
#[tokio::main]
19+
async fn main() -> Result<(), Box<dyn Error>> {
20+
let review = review_text().await?;
21+
println!("{}", review);
22+
23+
Ok(())
24+
}
25+
26+
#[derive(Serialize)]
27+
struct Prompt {
28+
prompt: String,
29+
max_tokens: u32,
30+
}
31+
32+
// Review text for potentially discriminatory language
33+
async fn review_text() -> Result<String, Box<dyn Error>> {
34+
// Get the path to the markdown file from the command line
35+
let args: Vec<String> = std::env::args().collect();
36+
// Check that the user provided a path to a markdown file
37+
if args.len() != 2 {
38+
println!("Usage: {} <path_to_markdown_file>", args[0]);
39+
std::process::exit(1);
40+
}
41+
// Read the markdown file
42+
let file_path = &args[1];
43+
let text = std::fs::read_to_string(file_path)?;
44+
// Get the OpenAI API key from the environment
45+
let api_key = std::env::var("OPENAI_API_KEY")?;
46+
// Call the OpenAI API
47+
let review = call_openai_api(&api_key, &text, "https://api.openai.com").await?;
48+
println!("{}", review);
49+
50+
Ok(review)
51+
}
52+
53+
async fn call_openai_api(api_key: &str, text: &str, base_url: &str) -> Result<String, Box<dyn Error>> {
54+
// Create a new HTTP client
55+
let client = Client::new();
56+
// Define the prompt text
57+
let prompt = format!(
58+
"Review the following text for potentially discriminatory language, including but not limited to ableism, ageism, racism, antisemitism, islamophobia, and likewise: {}",
59+
text
60+
);
61+
62+
// Define the request body with the model parameter and prompt text
63+
let request_body = serde_json::json!({
64+
"model": "gpt-3.5-turbo",
65+
"messages": [{"role": "user", "content": prompt}],
66+
"max_tokens": 100
67+
});
68+
69+
// Send the request to the OpenAI API
70+
let response = client
71+
.post(&format!("{}/v1/chat/completions", base_url))
72+
.header("Authorization", format!("Bearer {}", api_key))
73+
.json(&request_body)
74+
.send()
75+
.await?
76+
.json::<Value>()
77+
.await?;
78+
79+
// Extract the suggestion from the response
80+
let choices = response["choices"].as_array().ok_or(SuggestionError("Missing choices field".to_string()))?;
81+
let suggestion = choices
82+
.get(0)
83+
.and_then(|choice| choice["message"]["content"].as_str()) // Updated path to extract content
84+
.ok_or(SuggestionError("Missing suggestion text".to_string()))?
85+
.trim()
86+
.to_owned();
87+
88+
Ok(suggestion)
89+
}
90+
91+
#[cfg(test)]
92+
mod tests {
93+
use super::call_openai_api;
94+
use mockito::{mock, server_url};
95+
96+
#[tokio::test]
97+
async fn test_review_without_discriminatory_language() {
98+
let _m = mock("POST", "/v1/chat/completions")
99+
.with_status(200)
100+
.with_body(r#"{
101+
"choices": [
102+
{
103+
"finish_reason": "stop",
104+
"index": 0,
105+
"message": {
106+
"content": "There does not appear to be any discriminatory language in this text.",
107+
"role": "assistant"
108+
}
109+
}
110+
]
111+
}"#)
112+
.create();
113+
114+
let api_key = "fake_api_key";
115+
let text = "This is a normal sentence without any discriminatory language.";
116+
let review = call_openai_api(api_key, text, &server_url()).await.expect("API call failed");
117+
assert_eq!(review, "There does not appear to be any discriminatory language in this text.");
118+
}
119+
120+
#[tokio::test]
121+
async fn test_review_with_discriminatory_language() {
122+
let _m = mock("POST", "/v1/chat/completions")
123+
.with_status(200)
124+
.with_body(r#"{
125+
"choices": [
126+
{
127+
"finish_reason": "stop",
128+
"index": 0,
129+
"message": {
130+
"content": "The text contains discriminatory language. Suggested alternative: newcomers",
131+
"role": "assistant"
132+
}
133+
}
134+
]
135+
}"#)
136+
.create();
137+
138+
let api_key = "fake_api_key";
139+
let text = "This is an example sentence with discriminatory language: stupid beginners";
140+
let review = call_openai_api(api_key, text, &server_url()).await.expect("API call failed");
141+
let expected_result = "The text contains discriminatory language. Suggested alternative: newcomers";
142+
assert_eq!(review, expected_result);
143+
}
144+
}
145+

target/.rustc_info.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"rustc_fingerprint":13152440231236138976,"outputs":{"1185988223601034215":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/bengreenberg/.rustup/toolchains/stable-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\nfeature=\"cargo-clippy\"\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"vh\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.68.2 (9eb3afe9e 2023-03-27)\nbinary: rustc\ncommit-hash: 9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0\ncommit-date: 2023-03-27\nhost: aarch64-apple-darwin\nrelease: 1.68.2\nLLVM version: 15.0.6\n","stderr":""}},"successes":{}}

target/CACHEDIR.TAG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Signature: 8a477f597d28d172789f06886806bc55
2+
# This file is a cache directory tag created by cargo.
3+
# For information about cache directory tags see https://bford.info/cachedir/

0 commit comments

Comments
 (0)