diff --git a/.github/workflows/ai-revision.yaml b/.github/workflows/ai-revision.yaml new file mode 100644 index 0000000..58eb0d3 --- /dev/null +++ b/.github/workflows/ai-revision.yaml @@ -0,0 +1,69 @@ +name: ai-revision +on: + workflow_dispatch: + inputs: + branch: + description: 'Branch to revise' + required: true + type: string + default: 'main' + file_names: + description: 'File names to revise' + required: false + type: string + default: '' + model: + description: 'Language model' + required: true + type: string + default: 'text-davinci-003' + branch_name: + description: 'Output branch' + required: true + type: string + default: 'ai-revision-davinci' + +jobs: + ai-revise: + name: AI Revise + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + defaults: + run: + shell: bash --login {0} + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.branch }} + - name: Install environment + uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Install Manubot AI revision dependencies + run: | + # install using the same URL used for manubot in build/environment.yml + manubot_line=$(grep "github.com/manubot/manubot" build/environment.yml) + manubot_url=$(echo "$manubot_line" | awk -F"- " '{print $2}') + + pip install ${manubot_url}#egg=manubot[ai-rev] + - name: Revise manuscript + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + AI_EDITOR_LANGUAGE_MODEL: ${{ inputs.model }} + AI_EDITOR_FILENAMES_TO_REVISE: ${{ inputs.file_names }} + # More variables can be specified to control the behavior of the model: + # https://github.com/manubot/manubot-ai-editor/blob/main/libs/manubot_ai_editor/env_vars.py + run: manubot ai-revision --content-directory content/ + - name: Create Pull Request + uses: peter-evans/create-pull-request@v4 + with: + commit-message: 'revise using AI model\n\nUsing the OpenAI model ${{ inputs.model }}' + title: 'AI-based revision using ${{ inputs.model }}' + author: OpenAI model ${{ inputs.model }} + add-paths: | + content/*.md + branch: ${{ inputs.branch_name }} + draft: true diff --git a/.github/workflows/manubot.yaml b/.github/workflows/manubot.yaml index a386328..1ef5e98 100644 --- a/.github/workflows/manubot.yaml +++ b/.github/workflows/manubot.yaml @@ -38,6 +38,8 @@ jobs: manubot: name: Manubot runs-on: ubuntu-latest + permissions: + contents: write env: GITHUB_PULL_REQUEST_SHA: ${{ github.event.pull_request.head.sha }} # Set SPELLCHECK to true/false for whether to check spelling in this action. @@ -82,7 +84,9 @@ jobs: activate-environment: manubot environment-file: build/environment.yml auto-activate-base: false + miniforge-variant: Mambaforge miniforge-version: 'latest' + use-mamba: true - name: Install Spellcheck if: env.SPELLCHECK == 'true' run: bash ci/install-spellcheck.sh diff --git a/USAGE.md b/USAGE.md index b5478e7..5ce07a5 100644 --- a/USAGE.md +++ b/USAGE.md @@ -265,6 +265,8 @@ name: Daniel S. Himmelstein # mandatory initials: DSH # optional orcid: 0000-0002-3012-7446 # mandatory twitter: dhimmel # optional +mastodon: dhimmel # optional: mastodon username +mastodon-server: genomic.social # optional: mastodon server (instance) email: daniel.himmelstein@gmail.com # suggested corresponding: true # optional, if set to true displays author's email for correspondence affiliations: # as a list, strongly suggested @@ -320,6 +322,8 @@ metadata: csl: https://github.com/citation-style-language/styles/raw/906cd6d43d0c136190ecfbb12f6af0ca794e3c5b/peerj.csl ``` +Instructions for generating additional manuscript output formats such as DOCX can be found in [`build/README.md`](build/README.md). + ## Spellchecking When the `SPELLCHECK` environment variable is `true`, the pandoc [spellcheck filter](https://github.com/pandoc/lua-filters/tree/master/spellcheck) is run. @@ -327,6 +331,32 @@ Potential spelling errors will be printed in the continuous integration log alon Words in `build/assets/custom-dictionary.txt` are ignored during spellchecking. Spellchecking is currently only supported for English language manuscripts. +## AI-assisted authoring + +The workflow [`ai-revision`](.github/workflows/ai-revision.yaml) is available to assist authors in writing their manuscripts. +It uses large language models to revise the manuscript text, fixing spelling and grammar errors, and improving the sentence structure and the writing style with section-specific prompts. +It is manually triggered by the user (it never runs automatically), and it generates a pull request with suggested revisions. +Then the user can review these changes and merge the pull request if they are acceptable. +More information about this tool is available in [this manuscript](https://greenelab.github.io/manubot-gpt-manuscript/). + +You need to change your repository settings to 1) provide a secret with name `OPENAI_API_KEY` containing your OpenAI API token, and 2) allow workflows to create pull requests. +For 1), go to the settings page and, within "Secrets and variables," select "Actions." +Next, create a repository secret with the name `OPENAI_API_KEY` and the value of the API token (you can also do this using "Organization secrets" if available). +For 2), go to "Actions", "General", "Workflow permissions", and activate the checkbox "Allow GitHub Actions to create and approve pull requests." + +By default, the tool uses the model `text-davinci-003`. +Make sure to check the [pricing](https://openai.com/api/pricing/) of the OpenAI API. +With $0.02 per 1000 tokens using the most powerful AI models, the cost for a revision of a standard manuscript (around 35 paragraphs) should be around $0.50. +The workflow allows specifying the branch and file names (in the `content/` directory) to revise, the language model to use, and the output branch name. +Internally, the workflow uses the tool [Manubot AI Editor](https://github.com/manubot/manubot-ai-editor) to revise the manuscript. +For more advanced users, the behavior of the Manubot AI Editor or the parameters used for the language model can be changed using environment variables. +These variables can be changed in the workflow file (`ai-revision.yaml`). + +It is important to note that using language models in scientific writing is a matter of debate among researchers and journal editors. +Therefore, it's advisable to follow the guidelines that journals and the research community propose. +For example, the *Nature* journal has published [rules about using language models in scholarly writing](https://www.nature.com/articles/d41586-023-00191-1), such as not listing the tools as authors and documenting how they were used. +Since a Manubot-based manuscript uses GitHub, one approach consists of linking the AI-generated pull request, which will transparently show the changes suggested by the AI tool. + ## Manubot feedback If you experience any issues with the Manubot or would like to contribute to its source code, please visit [`manubot/manubot`](https://github.com/manubot/manubot) or [`manubot/rootstock`](https://github.com/manubot/rootstock). @@ -342,6 +372,14 @@ DOI: [10.1371/journal.pcbi.1007128](https://doi.org/10.1371/journal.pcbi.1007128 The Manubot version of this manuscript is available at . +To cite the Manubot AI Editor or for more information on its design, see `@doi:10.1101/2023.01.21.525030`: + +> **A publishing infrastructure for AI-assisted academic authoring**
+Milton Pividori, Casey S. Greene
+*bioRxiv* (2023)
+DOI: [10.1101/2023.01.21.525030](https://doi.org/10.1101/2023.01.21.525030) + + ## Acknowledgments We would like to thank the contributors and funders whose support makes the Manubot project possible. diff --git a/build/README.md b/build/README.md index 28893ab..3c09035 100644 --- a/build/README.md +++ b/build/README.md @@ -7,8 +7,19 @@ However, setting the `BUILD_PDF` environment variable to `false` will suppress P For example, run local builds using the command `BUILD_PDF=false bash build/build.sh`. To build a DOCX file of the manuscript, set the `BUILD_DOCX` environment variable to `true`. -For example, use the command `BUILD_DOCX=true bash build/build.sh`. -To export DOCX for all CI builds, set an environment variable (see docs for [GitHub Actions](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables)). +For example, use the command `BUILD_DOCX=true bash build/build.sh` locally. +To export DOCX for all CI builds, set an environment variable in the CI configuration file. +For GitHub Actions, set the variable in `.github\workflows\manubot.yaml` (see [docs](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables)): + +```yaml +name: Manubot +env: + BUILD_DOCX: true +``` + +To generate a single DOCX output of the latest manuscript with GitHub Actions, click the "Actions" tab at the top of the repository. +Select the "Manubot" workflow, then the "Run workflow" button and check "generate DOCX output" before clicking the green "Run workflow" button. + Currently, equation numbers via `pandoc-eqnos` are not supported for DOCX output. Format conversion is done using [Pandoc](https://pandoc.org/MANUAL.html). @@ -20,12 +31,17 @@ To change the options, either edit the YAML files directly or add additional `-- Note: currently, **Windows is not supported**. -Install the [conda](https://conda.io) environment specified in [`environment.yml`](environment.yml) by running the following commands +The Manubot environment is managed with [conda](https://conda.io). +If you do not have `conda` installed, we recommend using the Miniforge3 (includes `conda`) or Mambaforge (includes `conda` and `mamba`) installers from [miniforge](https://github.com/conda-forge/miniforge). +Install the environment from [`environment.yml`](environment.yml) by running one of following commands (from the repository's root directory): ```sh -# Install the environment +# Install the environment using conda conda env create --file build/environment.yml + +# Install the environment using mamba (faster) +mamba env create --file build/environment.yml ``` If the `manubot` environment is already installed, but needs to be updated to reflect changes to `environment.yml`, use one of the following options: @@ -38,6 +54,9 @@ conda env update --file build/environment.yml # Slower than option 1, but guarantees a fresh environment. conda env remove --name manubot conda env create --file build/environment.yml + +# option 3: reinstall the manubot environment faster using mamba. +mamba env create --force --file build/environment.yml ``` Activate with `conda activate manubot` (assumes `conda` version of [at least](https://github.com/conda/conda/blob/9d759d8edeb86569c25f6eb82053f09581013a2a/CHANGELOG.md#440-2017-12-20) 4.4). diff --git a/build/environment.yml b/build/environment.yml index 75d8e13..30fb360 100644 --- a/build/environment.yml +++ b/build/environment.yml @@ -4,34 +4,34 @@ channels: dependencies: - cairo=1.16.0 - cairocffi=1.2.0 - - ghp-import=2.0.2 - - jinja2=3.0.3 - - jsonschema=4.2.1 - - pandoc=2.17.0.1 + - ghp-import=2.1.0 + - jinja2=3.1.2 + - jsonschema=4.17.0 + - librsvg=2.52.5 + - pandoc=2.19.2 - pango=1.48.10 - - pip=21.3.1 - - python=3.10.0 - - requests-cache=0.8.1 - - requests=2.26.0 + - pip=22.3.1 + - python=3.11.0 + - requests-cache=0.9.6 + - requests=2.28.1 - tomli=2.0.1 - - watchdog==2.1.6 + - watchdog==2.1.9 - weasyprint=53.4 - - yamllint=1.26.3 + - yamllint=1.28.0 - pip: - cffi==1.15.0 - errorhandler==2.0.1 - - git+https://github.com/manubot/manubot@35178e6e561ae9778ab26123654b567526236c32 - - isbnlib==3.10.9 - - opentimestamps-client==0.7.0 - - opentimestamps==0.4.1 + - git+https://github.com/manubot/manubot@d4242ffa4194e4a13a68c5f6466feff559d3f9d5 + - isbnlib==3.10.10 + - opentimestamps-client==0.7.1 + - opentimestamps==0.4.3 - pandoc-eqnos==2.5.0 - pandoc-fignos==2.4.0 - pandoc-tablenos==2.3.0 - pandoc-xnos==2.5.0 - pandocfilters==1.5.0 - - panflute==2.1.0 - - psutil==5.8.0 - - pybase62==0.4.3 - - pysha3==1.0.2 - - python-bitcoinlib==0.10.2 - - pyyaml==5.4.1 + - panflute==2.2.3 + - psutil==5.9.4 + - pybase62==0.5.0 + - python-bitcoinlib==0.11.2 + - pyyaml==6.0 diff --git a/ci/install.sh b/ci/install.sh index c264b08..6b20f0e 100755 --- a/ci/install.sh +++ b/ci/install.sh @@ -7,7 +7,7 @@ set -o errexit \ -o pipefail -wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge-pypy3-$(uname)-$(uname -m).sh \ +wget https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-$(uname)-$(uname -m).sh \ --output-document miniforge.sh bash miniforge.sh -b -p $HOME/miniconda source $HOME/miniconda/etc/profile.d/conda.sh @@ -15,8 +15,8 @@ hash -r conda config \ --set always_yes yes \ --set changeps1 no -conda env create --quiet --file build/environment.yml -conda list --name manubot +mamba env create --quiet --file build/environment.yml +mamba list --name manubot conda activate manubot # Install Spellcheck filter for Pandoc diff --git a/content/00.front-matter.md b/content/00.front-matter.md index 4bd92f9..e13e1ba 100644 --- a/content/00.front-matter.md +++ b/content/00.front-matter.md @@ -48,6 +48,11 @@ Published: {{manubot.date_long}} · ![Twitter icon](images/twitter.svg){.inline_icon width=16 height=16} [{{author.twitter}}](https://twitter.com/{{author.twitter}}) {%- endif %} + {%- if author.mastodon is defined and author.mastodon is not none and author["mastodon-server"] is defined and author["mastodon-server"] is not none %} + {%- set has_ids = true %} + · ![Mastodon icon](images/mastodon.svg){.inline_icon width=16 height=16} + [\@{{author.mastodon}}@{{author["mastodon-server"]}}](https://{{author["mastodon-server"]}}/@{{author.mastodon}}) + {%- endif %} {%- if has_ids %}
{%- endif %} diff --git a/content/images/github.svg b/content/images/github.svg index 2c77c4c..5f377da 100644 --- a/content/images/github.svg +++ b/content/images/github.svg @@ -1,4 +1,4 @@ - - + + diff --git a/content/images/mastodon.svg b/content/images/mastodon.svg new file mode 100644 index 0000000..261cb0e --- /dev/null +++ b/content/images/mastodon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/content/images/orcid.svg b/content/images/orcid.svg index efc939b..2a635df 100644 --- a/content/images/orcid.svg +++ b/content/images/orcid.svg @@ -1,4 +1,4 @@ - - - + + + diff --git a/content/images/twitter.svg b/content/images/twitter.svg index 7f676e3..7bfb686 100644 --- a/content/images/twitter.svg +++ b/content/images/twitter.svg @@ -1,4 +1,4 @@ - - + + diff --git a/setup.bash b/setup.bash index 4319cc3..6278299 100755 --- a/setup.bash +++ b/setup.bash @@ -15,7 +15,7 @@ echo "OWNER and REPO refer to the details of your manuscript repo location:" echo "i.e. https://github.com/OWNER/REPO." echo echo "Options:" -echo " -o --owner GitHub user or organisation name." +echo " -o --owner GitHub user or organization name." echo " -r --repo Name of the repository for your new manuscript." echo " -y --yes Non-interactive mode. Continue script without asking for confirmation that the repo exists." echo " -s --ssh Use SSH to authenticate GitHub account. HTTPS is used by default." @@ -104,7 +104,7 @@ if [ -z "${OWNER}" ] || [ -z "${REPO}" ]; then echo "First, we need to specify where to create the GitHub repo for your manuscript." echo echo "The URL will take this format: https://github.com/OWNER/REPO." - echo "OWNER is your username or organisation" + echo "OWNER is your username or organization" echo "REPO is the name of your repository" echo read -r -p "Type in the OWNER now:" input @@ -188,13 +188,13 @@ fi case $AUTH in 0) echo - echo "Seting origin URL using its https web address" + echo "Setting origin URL using its https web address" echo git remote set-url origin https://github.com/${OWNER}/${REPO}.git ;; 1) echo - echo "Seting origin URL using SSH" + echo "Setting origin URL using SSH" echo git remote set-url origin git@github.com:$OWNER/$REPO.git ;;