From 78fba310b345989ee97650219ae4061555ca161a Mon Sep 17 00:00:00 2001 From: Rishav Dhar <19497993+rdhar@users.noreply.github.com> Date: Mon, 9 Jun 2025 00:15:40 +0100 Subject: [PATCH 1/7] replace line-by-line message inputs with bulk payload Signed-off-by: Rishav Dhar <19497993+rdhar@users.noreply.github.com> --- .github/workflows/ci.yml | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9985a6f..6498416 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,13 +29,27 @@ jobs: id: prompt uses: ./ with: - messages: '[{"role": "user", "content": "What is the capital of France?"}]' - model: openai/o4-mini - org: ${{ github.repository_owner}} - max-tokens: 100 + payload: | + model: openai/gpt-4.1-mini + messages: + - role: system + content: You are a helpful assistant + - role: user + content: What is the capital of France + max_tokens: 100 + temperature: 0.9 + top_p: 0.9 - name: Echo outputs - continue-on-error: true run: | - echo "response: ${{ steps.prompt.outputs.response }}" - echo "response-raw: ${{ steps.prompt.outputs.response-raw }}" + echo "response:" + echo "${{ steps.prompt.outputs.response }}" + + echo "response-file:" + echo "${{ steps.prompt.outputs.response-file }}" + + echo "response-file contents:" + cat "${{ steps.prompt.outputs.response-file }}" | jq + + echo "payload:" + echo "${{ steps.prompt.outputs.payload }}" From 7d45ebb5bc28b18f3ca9ef40bab07a08c76f36a9 Mon Sep 17 00:00:00 2001 From: Rishav Dhar <19497993+rdhar@users.noreply.github.com> Date: Mon, 9 Jun 2025 00:16:32 +0100 Subject: [PATCH 2/7] re-architect from multiple separate inputs to a single payload via in-line or file input Signed-off-by: Rishav Dhar <19497993+rdhar@users.noreply.github.com> --- action.yml | 93 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 29 deletions(-) diff --git a/action.yml b/action.yml index ec5bf41..79cd9df 100644 --- a/action.yml +++ b/action.yml @@ -1,32 +1,36 @@ --- name: AI Inference Request via GitHub Action author: Rishav Dhar (https://rdhar.dev) -description: AI inference request GitHub Models with this GitHub Action. +description: AI inference request GitHub Models via this GitHub Action. inputs: github-api-version: default: "2022-11-28" - description: "GitHub API version (e.g., `2022-11-28`)." + description: GitHub API version (e.g., `2022-11-28`) required: false github-token: - default: ${{ github.token }} - description: "GitHub token (e.g., `github.token`)." + default: "${{ github.token }}" + description: GitHub token (e.g., `github.token`) required: false - max-tokens: + org: default: "" - description: "Maximum number of tokens to generate in the completion (e.g., `1000`)." + description: Organization for request attribution (e.g., `github.repository_owner`) required: false - messages: - default: "" - description: 'Messages to send to the model in JSON format (e.g., `[{"role": "user", "content": "Hello!"}]`).' - required: true - model: + payload: default: "" - description: "Model to use for inference (e.g., `openai/o4-mini`)." - required: true - org: + description: Body parameters of the inference request in YAML format + required: false + payload-file: default: "" - description: "Organization to which the request should be attributed (e.g., `github.repository_owner`)." + description: Path to a file containing the body parameters of the inference request (e.g., `./payload.[json\|yml]`) + required: false + show-payload: + default: "true" + description: Whether to show the payload in the logs (e.g., `true`) + required: false + show-response: + default: "true" + description: Whether to show the response content in the logs (e.g., `true`) required: false runs: @@ -38,31 +42,62 @@ runs: API_VERSION: ${{ inputs.github-api-version }} GH_TOKEN: ${{ inputs.github-token }} ORG: ${{ inputs.org != '' && format('orgs/{0}/', inputs.org) || '' }} + PAYLOAD: ${{ inputs.payload }} + PAYLOAD_FILE: ${{ inputs.payload-file }} + SHOW_PAYLOAD: ${{ inputs.show-payload }} + SHOW_RESPONSE: ${{ inputs.show-response }} run: | - GH_HOST=$(echo $GITHUB_SERVER_URL | sed 's/.*:\/\///') + # AI inference request + if [[ -n "$PAYLOAD_FILE" ]]; then + # Check if the file exists + if [[ ! -f "$PAYLOAD_FILE" ]]; then + echo "Error: Payload file '$PAYLOAD_FILE' does not exist." >&2 + exit 1 + fi + # Determine whether the format is JSON (starts with '{') or YAML (default) + first_char=$(sed -n 's/^[[:space:]]*\(.\).*/\1/p; q' "$PAYLOAD_FILE") + if [[ "$first_char" == '{' ]]; then + body=$(cat "$PAYLOAD_FILE") + else + body=$(yq --output-format json "$PAYLOAD_FILE") + fi + else + body=$(echo "$PAYLOAD" | yq --output-format json) + fi + echo "payload_json=$(echo $body)" >> $GITHUB_OUTPUT + if [[ "${SHOW_PAYLOAD,,}" == "true" ]]; then echo "$body"; fi + + # Create a temporary file to store the response + temp_file=$(mktemp) - response_raw=$(curl --request POST --location https://models.github.ai/${ORG}inference/chat/completions \ + # Send the AI inference request via GitHub API + curl \ + --request POST \ + --no-progress-meter \ + --location "https://models.github.ai/${ORG}inference/chat/completions" \ --header "Accept: application/vnd.github+json" \ --header "Authorization: Bearer $GH_TOKEN" \ --header "Content-Type: application/json" \ --header "X-GitHub-Api-Version: $API_VERSION" \ - --data '{ - "messages": ${{ inputs.messages }}, - "model": "${{ inputs.model }}" - }' - ) + --data "$(echo $body | jq --compact-output --exit-status)" \ + &> "$temp_file" - echo $response_raw - echo "response_raw=$response_raw" >> $GITHUB_OUTPUT - echo "response=$response_raw | jq --raw-output '.choices[0].message.content'" >> $GITHUB_OUTPUT + # In addition to the temporary file containing the full response, + # return the first 2**18 bytes of the response content (GitHub's limit) + echo "response_file=$temp_file" >> $GITHUB_OUTPUT + echo "response=$(cat $temp_file | jq --raw-output '.choices[0].message.content' | head --bytes 262144 --silent)" >> $GITHUB_OUTPUT + if [[ "${SHOW_RESPONSE,,}" == "true" ]]; then cat "$temp_file" | jq --raw-output '.choices[0].message.content' || true; fi outputs: + payload: + description: Body parameters of the inference request in JSON format. + value: ${{ steps.request.outputs.payload_json }} response: - description: "Response content from the inference request." + description: Response content from the inference request. value: ${{ steps.request.outputs.response }} - response-raw: - description: "Raw, complete response in JSON format." - value: ${{ steps.request.outputs.response_raw }} + response-file: + description: File path containing the complete, raw response in JSON format. + value: ${{ steps.request.outputs.response_file }} branding: color: white From f04eaa581a29b171c13758aa60d4800d7a0d8ae0 Mon Sep 17 00:00:00 2001 From: Rishav Dhar <19497993+rdhar@users.noreply.github.com> Date: Mon, 9 Jun 2025 00:16:45 +0100 Subject: [PATCH 3/7] update example and parameters Signed-off-by: Rishav Dhar <19497993+rdhar@users.noreply.github.com> --- README.md | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 8e57d58..f6bc0f1 100644 --- a/README.md +++ b/README.md @@ -33,15 +33,18 @@ jobs: payload: | model: openai/gpt-4.1-mini messages: + - role: system + content: You are a helpful assistant running within GitHub CI. - role: user content: Concisely summarize this GitHub issue titled ${{ github.event.issue.title }}: ${{ github.event.issue.body }} + max_tokens: 100 temperature: 0.9 top_p: 0.9 - name: Comment summary run: gh issue comment $NUMBER --body "$SUMMARY" env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ github.token }} NUMBER: ${{ github.event.issue.number }} SUMMARY: ${{ steps.prompt.outputs.response }} ``` @@ -50,23 +53,29 @@ jobs: ## Inputs -Only `messages` and `model` are required inputs. [Compare available AI models](https://docs.github.com/en/copilot/using-github-copilot/ai-models/choosing-the-right-ai-model-for-your-task "Comparison of AI models for GitHub.") to choose the best one for your use-case. +Either `payload` or `payload-file` is required. [Compare available AI models](https://docs.github.com/en/copilot/using-github-copilot/ai-models/choosing-the-right-ai-model-for-your-task "Comparison of AI models for GitHub.") to choose the best one for your use-case. -| Name | Description | -| -------------------- | ---------------------------------------------------------------------------------------------------- | -| `github-api-version` | GitHub API version.
Default: `2022-11-28` | -| `github-token` | GitHub token.
Default: `github.token` | -| `max-tokens` | Maximum number of tokens to generate in the completion.
Example: `1000` | -| `messages` | Messages to send to the model in JSON format.
Example: `[{"role": "user", "content": "Hello!"}]` | -| `model` | Model to use for inference.
Example: `openai/o4-mini` | -| `org` | Organization to which the request should be attributed.
Example: `github.repository_owner` | +| Type | Name | Description | +| ------ | -------------------- | ------------------------------------------------------------------------------------------------------------ | +| Data | `payload` | Body parameters of the inference request in YAML format.
Example: `model:…` | +| Data | `payload-file` | Path to a file containing the body parameters of the inference request.
Example: `./payload.[json\|yml]` | +| Config | `show-payload` | Whether to show the payload in the logs.
Default: `true` | +| Config | `show-response` | Whether to show the response content in the logs.
Default: `true` | +| Admin | `github-api-version` | GitHub API version.
Default: `2022-11-28` | +| Admin | `github-token` | GitHub token.
Default: `github.token` | +| Admin | `org` | Organization for request attribution.
Example: `github.repository_owner` | + +
## Outputs -| Name | Description | -| -------------- | -------------------------------------------- | -| `response` | Response content from the inference request. | -| `response-raw` | Raw, complete response in JSON format. | +| Name | Description | +| -------------- | --------------------------------------------------------------- | +| `response` | Response content from the inference request. | +| `response-raw` | File path containing the complete, raw response in JSON format. | +| `payload` | Body parameters of the inference request in JSON format. | + +
## Security From 48e46095927a5bfab8f74fa12be30b235a6f1ce8 Mon Sep 17 00:00:00 2001 From: Rishav Dhar <19497993+rdhar@users.noreply.github.com> Date: Mon, 9 Jun 2025 00:18:33 +0100 Subject: [PATCH 4/7] wording Signed-off-by: Rishav Dhar <19497993+rdhar@users.noreply.github.com> --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f6bc0f1..43bf360 100644 --- a/README.md +++ b/README.md @@ -69,11 +69,11 @@ Either `payload` or `payload-file` is required. [Compare available AI models](ht ## Outputs -| Name | Description | -| -------------- | --------------------------------------------------------------- | -| `response` | Response content from the inference request. | -| `response-raw` | File path containing the complete, raw response in JSON format. | -| `payload` | Body parameters of the inference request in JSON format. | +| Name | Description | +| -------------- | -------------------------------------------------------- | +| `response` | Response content from the inference request. | +| `response-raw` | File path containing the complete, raw response. | +| `payload` | Body parameters of the inference request in JSON format. |
From c5a2fec0973b3a3f314bec6db0df2e840c97ad4a Mon Sep 17 00:00:00 2001 From: Rishav Dhar <19497993+rdhar@users.noreply.github.com> Date: Mon, 9 Jun 2025 00:20:00 +0100 Subject: [PATCH 5/7] update security email address Signed-off-by: Rishav Dhar <19497993+rdhar@users.noreply.github.com> --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 754f224..35aa759 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -17,4 +17,4 @@ Integrating security in your CI/CD pipeline is critical to practicing DevSecOps. ## Reporting a Vulnerability -You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead, sensitive bugs must be sent by email to or reported via [Security Advisory](https://github.com/op5dev/ai-inference-request/security/advisories/new "Create a new security advisory."). +You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead, sensitive bugs must be sent by email to or reported via [Security Advisory](https://github.com/op5dev/ai-inference-request/security/advisories/new "Create a new security advisory."). From 4ea91de4afdb6c2a5ba4d32271d1e0aa5fa19665 Mon Sep 17 00:00:00 2001 From: Rishav Dhar <19497993+rdhar@users.noreply.github.com> Date: Mon, 9 Jun 2025 00:24:48 +0100 Subject: [PATCH 6/7] formatting Signed-off-by: Rishav Dhar <19497993+rdhar@users.noreply.github.com> --- README.md | 18 +++++++++--------- action.yml | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 43bf360..a979b3f 100644 --- a/README.md +++ b/README.md @@ -55,15 +55,15 @@ jobs: Either `payload` or `payload-file` is required. [Compare available AI models](https://docs.github.com/en/copilot/using-github-copilot/ai-models/choosing-the-right-ai-model-for-your-task "Comparison of AI models for GitHub.") to choose the best one for your use-case. -| Type | Name | Description | -| ------ | -------------------- | ------------------------------------------------------------------------------------------------------------ | -| Data | `payload` | Body parameters of the inference request in YAML format.
Example: `model:…` | -| Data | `payload-file` | Path to a file containing the body parameters of the inference request.
Example: `./payload.[json\|yml]` | -| Config | `show-payload` | Whether to show the payload in the logs.
Default: `true` | -| Config | `show-response` | Whether to show the response content in the logs.
Default: `true` | -| Admin | `github-api-version` | GitHub API version.
Default: `2022-11-28` | -| Admin | `github-token` | GitHub token.
Default: `github.token` | -| Admin | `org` | Organization for request attribution.
Example: `github.repository_owner` | +| Type | Name | Description | +| ------ | -------------------- | ----------------------------------------------------------------------------------------------------------- | +| Data | `payload` | Body parameters of the inference request in YAML format.
Example: `model…` | +| Data | `payload-file` | Path to a file containing the body parameters of the inference request.
Example: `./payload.{json,yml}` | +| Config | `show-payload` | Whether to show the payload in the logs.
Default: `true` | +| Config | `show-response` | Whether to show the response content in the logs.
Default: `true` | +| Admin | `github-api-version` | GitHub API version.
Default: `2022-11-28` | +| Admin | `github-token` | GitHub token.
Default: `github.token` | +| Admin | `org` | Organization for request attribution.
Example: `github.repository_owner` |
diff --git a/action.yml b/action.yml index 79cd9df..5fdc321 100644 --- a/action.yml +++ b/action.yml @@ -18,11 +18,11 @@ inputs: required: false payload: default: "" - description: Body parameters of the inference request in YAML format + description: Body parameters of the inference request in YAML format (e.g., `model…`) required: false payload-file: default: "" - description: Path to a file containing the body parameters of the inference request (e.g., `./payload.[json\|yml]`) + description: Path to a file containing the body parameters of the inference request (e.g., `./payload.{json,yml}`) required: false show-payload: default: "true" From e50a1940b6f814b74127ef22430e48a254f56ee2 Mon Sep 17 00:00:00 2001 From: Rishav Dhar <19497993+rdhar@users.noreply.github.com> Date: Mon, 9 Jun 2025 00:25:46 +0100 Subject: [PATCH 7/7] reorder wording Signed-off-by: Rishav Dhar <19497993+rdhar@users.noreply.github.com> --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a979b3f..7600852 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ ## Usage Examples +[Compare available AI models](https://docs.github.com/en/copilot/using-github-copilot/ai-models/choosing-the-right-ai-model-for-your-task "Comparison of AI models for GitHub.") to choose the best one for your use-case. + ```yml on: issues: @@ -53,7 +55,7 @@ jobs: ## Inputs -Either `payload` or `payload-file` is required. [Compare available AI models](https://docs.github.com/en/copilot/using-github-copilot/ai-models/choosing-the-right-ai-model-for-your-task "Comparison of AI models for GitHub.") to choose the best one for your use-case. +Either `payload` or `payload-file` is required. | Type | Name | Description | | ------ | -------------------- | ----------------------------------------------------------------------------------------------------------- |