42 Commits
v2.0.6 ... main

Author SHA1 Message Date
Johan Jansson
af6ad2c4ac Merge pull request #154 from actions/dependabot/github_actions/actions-minor-06987af645
Some checks failed
CodeQL / Analyze (TypeScript, actions) (push) Has been cancelled
Check Transpiled JavaScript / Check dist/ (push) Has been cancelled
Continuous Integration / TypeScript Tests (push) Has been cancelled
Continuous Integration / GitHub Actions Test (push) Has been cancelled
Continuous Integration / GitHub Actions Test with Prompt File (push) Has been cancelled
Licensed / Check Licenses (push) Has been cancelled
Lint Codebase / Lint Codebase (push) Has been cancelled
chore(deps): bump the actions-minor group across 1 directory with 3 updates
2026-03-13 11:42:13 -10:00
dependabot[bot]
9446d602a4 chore(deps): bump the actions-minor group across 1 directory with 3 updates
Bumps the actions-minor group with 3 updates in the / directory: [ruby/setup-ruby](https://github.com/ruby/setup-ruby), [super-linter/super-linter](https://github.com/super-linter/super-linter) and [actions/publish-action](https://github.com/actions/publish-action).


Updates `ruby/setup-ruby` from 1.268.0 to 1.269.0
- [Release notes](https://github.com/ruby/setup-ruby/releases)
- [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb)
- [Commits](8aeb6ff803...d697be2f83)

Updates `super-linter/super-linter` from 8.0.0 to 8.3.0
- [Release notes](https://github.com/super-linter/super-linter/releases)
- [Changelog](https://github.com/super-linter/super-linter/blob/main/CHANGELOG.md)
- [Commits](5119dcd801...502f4fe48a)

Updates `actions/publish-action` from 0.3.0 to 0.4.0
- [Commits](https://github.com/actions/publish-action/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: ruby/setup-ruby
  dependency-version: 1.269.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor
- dependency-name: super-linter/super-linter
  dependency-version: 8.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor
- dependency-name: actions/publish-action
  dependency-version: 0.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-13 21:41:23 +00:00
Johan Jansson
9739430845 Merge pull request #191 from actions/dependabot/npm_and_yarn/npm-development-f6b51a9a0a
chore(deps-dev): bump the npm-development group across 1 directory with 11 updates
2026-03-13 11:37:33 -10:00
Johan Jansson
e105a5ce41 make it work with new eslint 2026-03-13 11:35:29 -10:00
dependabot[bot]
65a8d298fc chore(deps-dev): bump the npm-development group across 1 directory with 11 updates
Bumps the npm-development group with 10 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/HEAD/packages/node-resolve) | `16.0.1` | `16.0.3` |
| [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) | `12.1.2` | `12.3.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `24.1.0` | `24.12.0` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.34.0` | `8.57.0` |
| [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) | `10.1.5` | `10.1.8` |
| [eslint-import-resolver-typescript](https://github.com/import-js/eslint-import-resolver-typescript) | `4.4.3` | `4.4.4` |
| [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import) | `2.31.0` | `2.32.0` |
| [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) | `5.4.1` | `5.5.5` |
| [prettier](https://github.com/prettier/prettier) | `3.5.3` | `3.8.1` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.8.3` | `5.9.3` |



Updates `@rollup/plugin-node-resolve` from 16.0.1 to 16.0.3
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/node-resolve-v16.0.3/packages/node-resolve)

Updates `@rollup/plugin-typescript` from 12.1.2 to 12.3.0
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/typescript/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/typescript-v12.3.0/packages/typescript)

Updates `@types/node` from 24.1.0 to 24.12.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@typescript-eslint/eslint-plugin` from 8.34.0 to 8.57.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.57.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.34.0 to 8.57.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.57.0/packages/parser)

Updates `eslint-config-prettier` from 10.1.5 to 10.1.8
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v10.1.5...v10.1.8)

Updates `eslint-import-resolver-typescript` from 4.4.3 to 4.4.4
- [Release notes](https://github.com/import-js/eslint-import-resolver-typescript/releases)
- [Changelog](https://github.com/import-js/eslint-import-resolver-typescript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-import-resolver-typescript/compare/v4.4.3...v4.4.4)

Updates `eslint-plugin-import` from 2.31.0 to 2.32.0
- [Release notes](https://github.com/import-js/eslint-plugin-import/releases)
- [Changelog](https://github.com/import-js/eslint-plugin-import/blob/main/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-plugin-import/compare/v2.31.0...v2.32.0)

Updates `eslint-plugin-prettier` from 5.4.1 to 5.5.5
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.4.1...v5.5.5)

Updates `prettier` from 3.5.3 to 3.8.1
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.5.3...3.8.1)

Updates `typescript` from 5.8.3 to 5.9.3
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.8.3...v5.9.3)

---
updated-dependencies:
- dependency-name: "@rollup/plugin-node-resolve"
  dependency-version: 16.0.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: "@rollup/plugin-typescript"
  dependency-version: 12.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: "@types/node"
  dependency-version: 24.12.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.57.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.57.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: eslint-config-prettier
  dependency-version: 10.1.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: eslint-import-resolver-typescript
  dependency-version: 4.4.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-development
- dependency-name: eslint-plugin-import
  dependency-version: 2.32.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: eslint-plugin-prettier
  dependency-version: 5.5.5
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: prettier
  dependency-version: 3.8.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
- dependency-name: typescript
  dependency-version: 5.9.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-13 21:30:41 +00:00
Johan Jansson
1f6750a867 Merge pull request #169 from actions/dependabot/npm_and_yarn/modelcontextprotocol/sdk-1.26.0
chore(deps): bump @modelcontextprotocol/sdk from 1.25.2 to 1.26.0
2026-03-13 11:28:46 -10:00
dependabot[bot]
3a4bd7a335 chore(deps): bump @modelcontextprotocol/sdk from 1.25.2 to 1.26.0
Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) from 1.25.2 to 1.26.0.
- [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases)
- [Commits](https://github.com/modelcontextprotocol/typescript-sdk/compare/v1.25.2...v1.26.0)

---
updated-dependencies:
- dependency-name: "@modelcontextprotocol/sdk"
  dependency-version: 1.26.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-13 21:22:13 +00:00
Johan Jansson
09488142e3 Merge pull request #174 from actions/dependabot/npm_and_yarn/qs-6.14.2
chore(deps): bump qs from 6.14.1 to 6.14.2
2026-03-13 11:20:50 -10:00
dependabot[bot]
c729573012 chore(deps): bump qs from 6.14.1 to 6.14.2
Bumps [qs](https://github.com/ljharb/qs) from 6.14.1 to 6.14.2.
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.14.1...v6.14.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.14.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-13 21:15:02 +00:00
Johan Jansson
fa073b82c5 Merge pull request #179 from actions/dependabot/npm_and_yarn/rollup-4.59.0
chore(deps-dev): bump rollup from 4.43.0 to 4.59.0
2026-03-13 11:13:49 -10:00
dependabot[bot]
1157ae8180 chore(deps-dev): bump rollup from 4.43.0 to 4.59.0
Bumps [rollup](https://github.com/rollup/rollup) from 4.43.0 to 4.59.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.43.0...v4.59.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 4.59.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-13 21:11:33 +00:00
Johan Jansson
39e1ff891d Merge pull request #181 from actions/dependabot/npm_and_yarn/ajv-6.14.0
chore(deps-dev): bump ajv from 6.12.6 to 6.14.0
2026-03-13 11:10:15 -10:00
dependabot[bot]
2da133cc84 chore(deps-dev): bump ajv from 6.12.6 to 6.14.0
Bumps [ajv](https://github.com/ajv-validator/ajv) from 6.12.6 to 6.14.0.
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.6...v6.14.0)

---
updated-dependencies:
- dependency-name: ajv
  dependency-version: 6.14.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-13 21:08:59 +00:00
Johan Jansson
121a7cf487 Merge pull request #161 from actions/dependabot/npm_and_yarn/actions/core-2.0.2
chore(deps): bump @actions/core from 1.11.1 to 2.0.2
2026-03-13 11:07:38 -10:00
dependabot[bot]
e06ed630a2 chore(deps): bump @actions/core from 1.11.1 to 2.0.2
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.11.1 to 2.0.2.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-version: 2.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-13 21:05:29 +00:00
Johan Jansson
230b1cd3d0 Merge pull request #140 from actions/dependabot/npm_and_yarn/openai-6.7.0
chore(deps): bump openai from 5.11.0 to 6.7.0
2026-03-13 11:03:23 -10:00
dependabot[bot]
3d8acac3cb chore(deps): bump openai from 5.11.0 to 6.7.0
Bumps [openai](https://github.com/openai/openai-node) from 5.11.0 to 6.7.0.
- [Release notes](https://github.com/openai/openai-node/releases)
- [Changelog](https://github.com/openai/openai-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/openai/openai-node/compare/v5.11.0...v6.7.0)

---
updated-dependencies:
- dependency-name: openai
  dependency-version: 6.7.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-13 21:02:13 +00:00
Johan Jansson
d46015cb8d Merge pull request #189 from actions/dependabot/npm_and_yarn/hono-4.12.7
chore(deps): bump hono from 4.11.3 to 4.12.7
2026-03-13 10:11:39 -10:00
dependabot[bot]
b44f5a29f4 chore(deps): bump hono from 4.11.3 to 4.12.7
Bumps [hono](https://github.com/honojs/hono) from 4.11.3 to 4.12.7.
- [Release notes](https://github.com/honojs/hono/releases)
- [Commits](https://github.com/honojs/hono/compare/v4.11.3...v4.12.7)

---
updated-dependencies:
- dependency-name: hono
  dependency-version: 4.12.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-13 20:10:04 +00:00
Johan Jansson
a6d96d58d5 Merge pull request #186 from Pet3cy/security-fix-mcp-token-exposure-9299248942858101367
Security fix mcp token exposure 9299248942858101367
2026-03-13 10:03:38 -10:00
Johan Jansson
4eebe5ea25 Merge branch 'main' into security-fix-mcp-token-exposure-9299248942858101367 2026-03-13 10:00:12 -10:00
Johan Jansson
cf1eafb00d Merge pull request #190 from actions/try-to-fix-ci-error
Fix CI error: Check Transpiled JavaScript / Check dist
2026-03-13 09:59:59 -10:00
Johan Jansson
debf34cf91 Fix CI error: Check Transpiled JavaScript / Check dist 2026-03-13 09:49:01 -10:00
Johan Jansson
541dd69625 Merge branch 'main' into security-fix-mcp-token-exposure-9299248942858101367 2026-03-13 09:33:41 -10:00
Johan Jansson
f65d1a34dc Merge pull request #182 from actions/dependabot/npm_and_yarn/fast-xml-parser-5.4.2
chore(deps-dev): bump fast-xml-parser from 5.2.3 to 5.4.2
2026-03-13 09:32:38 -10:00
google-labs-jules[bot]
9d962e5274 🔒 [security fix] Mask sensitive tokens in GitHub Actions logs
- Added `core.setSecret(token)` to mask the primary GitHub token.
- Added `core.setSecret(githubMcpToken)` to mask the GitHub MCP token.
- Updated `__fixtures__/core.ts` to include the `setSecret` mock.
- Updated `__tests__/main.test.ts` to verify `setSecret` is called for the tokens.
2026-03-10 22:44:58 +00:00
dependabot[bot]
8b38b47848 chore(deps-dev): bump fast-xml-parser from 5.2.3 to 5.4.2
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.2.3 to 5.4.2.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.2.3...v5.4.2)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-version: 5.4.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-03 13:20:56 +00:00
Pet3cy
b7792492cd Merge pull request #12 from Pet3cy/fix-testing-improvement-parse-file-template-variables-6142620025282989819
🧪 [testing improvement] validate non-string file paths in parseFileTemplateVariables
2026-02-25 05:12:54 +01:00
google-labs-jules[bot]
a2600c61b7 test: validate non-string file paths in parseFileTemplateVariables
Add test cases to verify that `parseFileTemplateVariables` correctly
throws an error when a non-string value (e.g. number, boolean, object)
is provided as a file path in the input YAML. This ensures the existing
validation is properly tested.

Co-authored-by: Pet3cy <169947521+Pet3cy@users.noreply.github.com>
2026-02-25 04:12:17 +00:00
Pet3cy
306ffe21b9 Merge pull request #11 from Pet3cy/relax-header-validation-16962389466518057682
🧹 Relax overly restrictive HTTP header name validation
2026-02-24 18:45:30 +01:00
google-labs-jules[bot]
326b9a12f4 chore: relax HTTP header name validation to match RFC 7230
Updated the regex in `src/helpers.ts` to allow all valid characters in an HTTP token (RFC 7230, section 3.2.6), including symbols like `_`, `.`, `!`, and `*`. Previously, the validation was overly restrictive, only allowing alphanumeric characters and hyphens.

Also updated the corresponding unit test in `__tests__/helpers.test.ts` to reflect the change.
2026-02-24 17:44:57 +00:00
Pet3cy
8207a8ca01 Merge pull request #10 from Pet3cy/security-fix-sensitive-data-exposure-logs-8322086360319645856
🔒 [security fix] Fix sensitive data exposure in MCP Inference logs
2026-02-24 18:42:50 +01:00
google-labs-jules[bot]
c6c19e0fb7 🔒 [security fix] Fix sensitive data exposure in logs
- Change core.info to core.debug for model responses in src/inference.ts
- Change core.info to core.debug for tool execution details in src/mcp.ts
- Change core.info to core.debug for custom header logging in src/helpers.ts
- Remove sensitive response previews from error messages in src/inference.ts
- Update tests to reflect changes from core.info to core.debug
2026-02-24 17:42:20 +00:00
Stephanie Giang
e09e659817 Merge pull request #173 from GitPaulo/main
Support passing max_tokens and max_completion_tokens
2026-02-24 10:40:15 -05:00
Paulo Santos
e608d2ba8a update dist 2026-02-15 00:26:15 +00:00
Paulo Santos
27965bc3a4 updated docs for missing prompt.yml model parameters 2026-02-15 00:23:47 +00:00
Paulo Santos
a8bddad5e5 update dist 2026-02-13 12:41:36 +00:00
Paulo Santos
672ba8a3ac missed comment 2026-02-13 12:38:48 +00:00
Paulo Santos
3a80d137e1 update comments 2026-02-13 12:36:47 +00:00
Paulo Santos
074e8b294d copilot review: add test for coverage of no params passed 2026-02-13 12:31:45 +00:00
Paulo Santos
f1ca66fc66 build dist 2026-02-13 12:16:03 +00:00
Paulo Santos
6360e0db9b implement passing two action input properties to cover all model scenarios 2026-02-13 12:15:12 +00:00
23 changed files with 857 additions and 460 deletions

View File

@@ -43,7 +43,7 @@ jobs:
- name: Build dist/ Directory
id: build
run: npm run bundle
run: npm run package
# This will fail the workflow if the `dist/` directory is different than
# expected.

View File

@@ -42,7 +42,7 @@ jobs:
- name: Setup Ruby
id: setup-ruby
uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71
uses: ruby/setup-ruby@4eb9f110bac952a8b68ecf92e3b5c7a987594ba6
with:
ruby-version: ruby

View File

@@ -38,7 +38,7 @@ jobs:
- name: Lint Codebase
id: super-linter
uses: super-linter/super-linter/slim@5119dcd8011e92182ce8219d9e9efc82f16fddb6
uses: super-linter/super-linter/slim@61abc07d755095a68f4987d1c2c3d1d64408f1f9
env:
DEFAULT_BRANCH: main
FILTER_REGEX_EXCLUDE: dist/**/*

View File

@@ -16,6 +16,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Update the ${{ env.TAG_NAME }} tag
uses: actions/publish-action@v0.3.0
uses: actions/publish-action@v0.4.0
with:
source-tag: ${{ env.TAG_NAME }}

View File

@@ -123,6 +123,33 @@ supplied via the `input` parameter in YAML format. Additionally, you can
provide file-based variables via `file_input`, where each key maps to a file
path.
### Prompt.yml with model parameters
You can specify model parameters directly in your `.prompt.yml` files using the
`modelParameters` key:
```yaml
messages:
- role: system
content: Be as concise as possible
- role: user
content: 'Compare {{a}} and {{b}}, please'
model: openai/gpt-4o
modelParameters:
maxCompletionTokens: 500
temperature: 0.7
```
| Key | Type | Description |
| --------------------- | ------ | ----------------------------------------------------- |
| `maxCompletionTokens` | number | The maximum number of tokens to generate |
| `maxTokens` | number | The maximum number of tokens to generate (deprecated) |
| `temperature` | number | The sampling temperature to use (0-1) |
| `topP` | number | The nucleus sampling parameter to use (0-1) |
> ![Note]
> Parameters set in `modelParameters` take precedence over the corresponding action inputs.
### Using a system prompt file
In addition to the regular prompt, you can provide a system prompt file instead
@@ -276,23 +303,24 @@ perform actions like searching issues and PRs.
Various inputs are defined in [`action.yml`](action.yml) to let you configure
the action:
| Name | Description | Default |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------ |
| `token` | Token to use for inference. Typically the GITHUB_TOKEN secret | `github.token` |
| `prompt` | The prompt to send to the model | N/A |
| `prompt-file` | Path to a file containing the prompt (supports .txt and .prompt.yml formats). If both `prompt` and `prompt-file` are provided, `prompt-file` takes precedence | `""` |
| `input` | Template variables in YAML format for .prompt.yml files (e.g., `var1: value1` on separate lines) | `""` |
| `file_input` | Template variables in YAML where values are file paths. The file contents are read and used for templating | `""` |
| `system-prompt` | The system prompt to send to the model | `"You are a helpful assistant"` |
| `system-prompt-file` | Path to a file containing the system prompt. If both `system-prompt` and `system-prompt-file` are provided, `system-prompt-file` takes precedence | `""` |
| `model` | The model to use for inference. Must be available in the [GitHub Models](https://github.com/marketplace?type=models) catalog | `openai/gpt-4o` |
| `endpoint` | The endpoint to use for inference. If you're running this as part of an org, you should probably use the org-specific Models endpoint | `https://models.github.ai/inference` |
| `max-tokens` | The max number of tokens to generate | 200 |
| `temperature` | The sampling temperature to use (0-1) | `""` |
| `top-p` | The nucleus sampling parameter to use (0-1) | `""` |
| `enable-github-mcp` | Enable Model Context Protocol integration with GitHub tools | `false` |
| `github-mcp-token` | Token to use for GitHub MCP server (defaults to the main token if not specified). | `""` |
| `custom-headers` | Custom HTTP headers to include in API requests. Supports both YAML format (`header1: value1`) and JSON format (`{"header1": "value1"}`). Useful for API Management platforms, rate limiting, and request tracking. | `""` |
| Name | Description | Default |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------ |
| `token` | Token to use for inference. Typically the GITHUB_TOKEN secret | `github.token` |
| `prompt` | The prompt to send to the model | N/A |
| `prompt-file` | Path to a file containing the prompt (supports .txt and .prompt.yml formats). If both `prompt` and `prompt-file` are provided, `prompt-file` takes precedence | `""` |
| `input` | Template variables in YAML format for .prompt.yml files (e.g., `var1: value1` on separate lines) | `""` |
| `file_input` | Template variables in YAML where values are file paths. The file contents are read and used for templating | `""` |
| `system-prompt` | The system prompt to send to the model | `"You are a helpful assistant"` |
| `system-prompt-file` | Path to a file containing the system prompt. If both `system-prompt` and `system-prompt-file` are provided, `system-prompt-file` takes precedence | `""` |
| `model` | The model to use for inference. Must be available in the [GitHub Models](https://github.com/marketplace?type=models) catalog | `openai/gpt-4o` |
| `endpoint` | The endpoint to use for inference. If you're running this as part of an org, you should probably use the org-specific Models endpoint | `https://models.github.ai/inference` |
| `max-tokens` | The maximum number of tokens to generate (deprecated, use `max-completion-tokens` instead) | 200 |
| `max-completion-tokens` | The maximum number of tokens to generate | `""` |
| `temperature` | The sampling temperature to use (0-1) | `""` |
| `top-p` | The nucleus sampling parameter to use (0-1) | `""` |
| `enable-github-mcp` | Enable Model Context Protocol integration with GitHub tools | `false` |
| `github-mcp-token` | Token to use for GitHub MCP server (defaults to the main token if not specified). | `""` |
| `custom-headers` | Custom HTTP headers to include in API requests. Supports both YAML format (`header1: value1`) and JSON format (`{"header1": "value1"}`). Useful for API Management platforms, rate limiting, and request tracking. | `""` |
## Outputs

View File

@@ -9,3 +9,4 @@ export const getBooleanInput = vi.fn<typeof core.getBooleanInput>()
export const setOutput = vi.fn<typeof core.setOutput>()
export const setFailed = vi.fn<typeof core.setFailed>()
export const warning = vi.fn<typeof core.warning>()
export const setSecret = vi.fn<typeof core.setSecret>()

View File

@@ -109,6 +109,7 @@ describe('helpers.ts - inference request building', () => {
undefined,
undefined,
100,
undefined,
'https://api.test.com',
'test-token',
)
@@ -122,6 +123,7 @@ describe('helpers.ts - inference request building', () => {
temperature: undefined,
topP: undefined,
maxTokens: 100,
maxCompletionTokens: undefined,
endpoint: 'https://api.test.com',
token: 'test-token',
responseFormat: {
@@ -143,6 +145,7 @@ describe('helpers.ts - inference request building', () => {
undefined,
undefined,
100,
undefined,
'https://api.test.com',
'test-token',
)
@@ -156,6 +159,7 @@ describe('helpers.ts - inference request building', () => {
temperature: undefined,
topP: undefined,
maxTokens: 100,
maxCompletionTokens: undefined,
endpoint: 'https://api.test.com',
token: 'test-token',
responseFormat: undefined,

View File

@@ -150,9 +150,9 @@ X-Custom-Header: custom-value`
header2: 'value2',
'X-Custom-Header': 'custom-value',
})
expect(core.info).toHaveBeenCalledWith('Custom header added: header1: value1')
expect(core.info).toHaveBeenCalledWith('Custom header added: header2: value2')
expect(core.info).toHaveBeenCalledWith('Custom header added: X-Custom-Header: custom-value')
expect(core.debug).toHaveBeenCalledWith('Custom header added: header1: value1')
expect(core.debug).toHaveBeenCalledWith('Custom header added: header2: value2')
expect(core.debug).toHaveBeenCalledWith('Custom header added: X-Custom-Header: custom-value')
})
it('parses JSON format headers correctly', () => {
@@ -165,9 +165,9 @@ X-Custom-Header: custom-value`
header2: 'value2',
'X-Team': 'engineering',
})
expect(core.info).toHaveBeenCalledWith('Custom header added: header1: value1')
expect(core.info).toHaveBeenCalledWith('Custom header added: header2: value2')
expect(core.info).toHaveBeenCalledWith('Custom header added: X-Team: engineering')
expect(core.debug).toHaveBeenCalledWith('Custom header added: header1: value1')
expect(core.debug).toHaveBeenCalledWith('Custom header added: header2: value2')
expect(core.debug).toHaveBeenCalledWith('Custom header added: X-Team: engineering')
})
it('returns empty object for empty input', () => {
@@ -194,13 +194,13 @@ password: pass123`
})
// Sensitive headers should be masked
expect(core.info).toHaveBeenCalledWith('Custom header added: Ocp-Apim-Subscription-Key: ***MASKED***')
expect(core.info).toHaveBeenCalledWith('Custom header added: X-Api-Token: ***MASKED***')
expect(core.info).toHaveBeenCalledWith('Custom header added: Authorization: ***MASKED***')
expect(core.info).toHaveBeenCalledWith('Custom header added: password: ***MASKED***')
expect(core.debug).toHaveBeenCalledWith('Custom header added: Ocp-Apim-Subscription-Key: ***MASKED***')
expect(core.debug).toHaveBeenCalledWith('Custom header added: X-Api-Token: ***MASKED***')
expect(core.debug).toHaveBeenCalledWith('Custom header added: Authorization: ***MASKED***')
expect(core.debug).toHaveBeenCalledWith('Custom header added: password: ***MASKED***')
// Non-sensitive headers should not be masked
expect(core.info).toHaveBeenCalledWith('Custom header added: serviceName: my-service')
expect(core.debug).toHaveBeenCalledWith('Custom header added: serviceName: my-service')
})
it('validates header names and skips invalid ones', () => {
@@ -214,13 +214,11 @@ valid123: value5`
expect(result).toEqual({
'valid-header': 'value1',
invalid_underscore: 'value3',
valid123: 'value5',
})
expect(core.warning).toHaveBeenCalledWith(expect.stringContaining('Skipping invalid header name: invalid header'))
expect(core.warning).toHaveBeenCalledWith(
expect.stringContaining('Skipping invalid header name: invalid_underscore'),
)
expect(core.warning).toHaveBeenCalledWith(expect.stringContaining('Skipping invalid header name: invalid@header'))
})
@@ -367,8 +365,8 @@ systemID: terraform-ci`
})
// Only the subscription key should be masked
expect(core.info).toHaveBeenCalledWith('Custom header added: Ocp-Apim-Subscription-Key: ***MASKED***')
expect(core.info).toHaveBeenCalledWith('Custom header added: serviceName: terraform-plan-workflow')
expect(core.debug).toHaveBeenCalledWith('Custom header added: Ocp-Apim-Subscription-Key: ***MASKED***')
expect(core.debug).toHaveBeenCalledWith('Custom header added: serviceName: terraform-plan-workflow')
})
})
})

View File

@@ -31,7 +31,7 @@ describe('inference.ts', () => {
{role: 'user' as const, content: 'Hello, AI!'},
],
modelName: 'gpt-4',
maxTokens: 100,
maxCompletionTokens: 100,
endpoint: 'https://api.test.com',
token: 'test-token',
}
@@ -58,7 +58,7 @@ describe('inference.ts', () => {
expect(result).toBe('Hello, user!')
expect(core.info).toHaveBeenCalledWith('Running simple inference without tools')
expect(core.info).toHaveBeenCalledWith('Model response: Hello, user!')
expect(core.debug).toHaveBeenCalledWith('Model response: Hello, user!')
// Verify the request structure
expect(mockCreate).toHaveBeenCalledWith({
@@ -136,7 +136,7 @@ describe('inference.ts', () => {
const result = await simpleInference(mockRequest)
expect(result).toBeNull()
expect(core.info).toHaveBeenCalledWith('Model response: No response content')
expect(core.debug).toHaveBeenCalledWith('Model response: No response content')
})
it('includes response format when specified', async () => {
@@ -633,4 +633,64 @@ describe('inference.ts', () => {
expect(result).toBe('{"immediate": "result"}')
})
})
describe('token param routing', () => {
it('sends max_tokens when only maxTokens is set', async () => {
const requestWithMaxTokens = {
...mockRequest,
maxCompletionTokens: undefined,
maxTokens: 100,
}
const mockResponse = {
choices: [
{
message: {
content: 'Direct max_tokens response',
},
},
],
}
mockCreate.mockResolvedValueOnce(mockResponse)
const result = await simpleInference(requestWithMaxTokens)
expect(result).toBe('Direct max_tokens response')
expect(mockCreate).toHaveBeenCalledTimes(1)
// Should have sent max_tokens directly
expect(mockCreate.mock.calls[0][0]).toHaveProperty('max_tokens', 100)
expect(mockCreate.mock.calls[0][0]).not.toHaveProperty('max_completion_tokens')
})
it('sends neither token param when both are undefined', async () => {
const requestWithNoTokens = {
...mockRequest,
maxCompletionTokens: undefined,
maxTokens: undefined,
}
const mockResponse = {
choices: [
{
message: {
content: 'No token limit response',
},
},
],
}
mockCreate.mockResolvedValueOnce(mockResponse)
const result = await simpleInference(requestWithNoTokens)
expect(result).toBe('No token limit response')
expect(mockCreate).toHaveBeenCalledTimes(1)
const params = mockCreate.mock.calls[0][0]
expect(params).not.toHaveProperty('max_tokens')
expect(params).not.toHaveProperty('max_completion_tokens')
})
})
})

View File

@@ -136,6 +136,7 @@ describe('main.ts', () => {
await run()
expect(core.setOutput).toHaveBeenCalled()
expect(core.setSecret).toHaveBeenCalledWith('fake-token')
verifyStandardResponse()
expect(mockProcessExit).toHaveBeenCalledWith(0)
})
@@ -168,6 +169,7 @@ describe('main.ts', () => {
],
modelName: 'gpt-4',
maxTokens: 100,
maxCompletionTokens: undefined,
endpoint: 'https://api.test.com',
token: 'fake-token',
responseFormat: undefined,
@@ -198,6 +200,7 @@ describe('main.ts', () => {
await run()
expect(core.setSecret).toHaveBeenCalledWith('fake-token')
expect(mockConnectToGitHubMCP).toHaveBeenCalledWith('fake-token', '')
expect(mockMcpInference).toHaveBeenCalledWith(
expect.objectContaining({
@@ -259,6 +262,7 @@ describe('main.ts', () => {
],
modelName: 'gpt-4',
maxTokens: 100,
maxCompletionTokens: undefined,
endpoint: 'https://api.test.com',
token: 'fake-token',
responseFormat: undefined,

View File

@@ -177,8 +177,8 @@ describe('mcp.ts', () => {
name: 'test-tool',
content: JSON.stringify(toolResult.content),
})
expect(core.info).toHaveBeenCalledWith('Executing GitHub MCP tool: test-tool with args: {"param": "value"}')
expect(core.info).toHaveBeenCalledWith('GitHub MCP tool test-tool executed successfully')
expect(core.debug).toHaveBeenCalledWith('Executing GitHub MCP tool: test-tool with args: {"param": "value"}')
expect(core.debug).toHaveBeenCalledWith('GitHub MCP tool test-tool executed successfully')
})
it('handles tool execution errors gracefully', async () => {

View File

@@ -135,5 +135,17 @@ describe('prompt.ts', () => {
it('errors on missing files', () => {
expect(() => parseFileTemplateVariables('x: ./does-not-exist.txt')).toThrow('was not found')
})
it('errors on non-string file paths', () => {
expect(() => parseFileTemplateVariables('x: 123')).toThrow(
"File template variable 'x' must be a string file path",
)
expect(() => parseFileTemplateVariables('x: true')).toThrow(
"File template variable 'x' must be a string file path",
)
expect(() => parseFileTemplateVariables('x: { nested: "object" }')).toThrow(
"File template variable 'x' must be a string file path",
)
})
})
})

View File

@@ -43,9 +43,13 @@ inputs:
required: false
default: ''
max-tokens:
description: The maximum number of tokens to generate
description: The maximum number of tokens to generate (deprecated)
required: false
default: '200'
max-completion-tokens:
description: The maximum number of tokens to generate
required: false
default: ''
temperature:
description: The sampling temperature to use (0-1)
required: false

34
dist/index.js generated vendored
View File

@@ -58300,6 +58300,19 @@ OpenAI.Responses = Responses;
OpenAI.Evals = Evals;
OpenAI.Containers = Containers;
/**
* Build according to what input was passed, default to max_tokens.
* Only one of max_tokens or max_completion_tokens will be set.
*/
function buildMaxTokensParam(request) {
if (request.maxCompletionTokens != null) {
return { max_completion_tokens: request.maxCompletionTokens };
}
if (request.maxTokens != null) {
return { max_tokens: request.maxTokens };
}
return {};
}
/**
* Simple one-shot inference without tools
*/
@@ -58312,10 +58325,10 @@ async function simpleInference(request) {
});
const chatCompletionRequest = {
messages: request.messages,
max_completion_tokens: request.maxTokens,
model: request.modelName,
temperature: request.temperature,
top_p: request.topP,
...buildMaxTokensParam(request), // Note: solution around models using different underlying max tokens properties
};
// Add response format if specified
if (request.responseFormat) {
@@ -58349,10 +58362,10 @@ async function mcpInference(request, githubMcpClient) {
coreExports.info(`MCP inference iteration ${iterationCount}`);
const chatCompletionRequest = {
messages: messages,
max_completion_tokens: request.maxTokens,
model: request.modelName,
temperature: request.temperature,
top_p: request.topP,
...buildMaxTokensParam(request), // Note: solution around models using different underlying max tokens properties
};
// Add response format if specified (only on final iteration to avoid conflicts with tool calls)
if (finalMessage && request.responseFormat) {
@@ -61382,7 +61395,8 @@ function validateAndMaskHeaders(headers) {
/**
* Build complete InferenceRequest from prompt config and inputs
*/
function buildInferenceRequest(promptConfig, systemPrompt, prompt, modelName, temperature, topP, maxTokens, endpoint, token, customHeaders) {
function buildInferenceRequest(promptConfig, systemPrompt, prompt, modelName, temperature, topP, maxTokens, // Deprecated
maxCompletionTokens, endpoint, token, customHeaders) {
const messages = buildMessages(promptConfig, systemPrompt, prompt);
const responseFormat = buildResponseFormat(promptConfig);
return {
@@ -61390,7 +61404,8 @@ function buildInferenceRequest(promptConfig, systemPrompt, prompt, modelName, te
modelName,
temperature,
topP,
maxTokens,
maxTokens, // Deprecated
maxCompletionTokens,
endpoint,
token,
responseFormat,
@@ -61536,10 +61551,11 @@ async function run() {
}
// Get common parameters
const modelName = promptConfig?.model || coreExports.getInput('model');
let maxTokens = promptConfig?.modelParameters?.maxTokens ?? coreExports.getInput('max-tokens');
if (typeof maxTokens === 'string') {
maxTokens = parseInt(maxTokens, 10);
}
// Parse token limit inputs
const maxCompletionTokensInput = promptConfig?.modelParameters?.maxCompletionTokens ?? coreExports.getInput('max-completion-tokens');
const maxCompletionTokens = maxCompletionTokensInput ? Number(maxCompletionTokensInput) : undefined;
const maxTokensInput = promptConfig?.modelParameters?.maxTokens ?? coreExports.getInput('max-tokens');
const maxTokens = maxCompletionTokens != null ? undefined : maxTokensInput ? Number(maxTokensInput) : undefined;
const token = process.env['GITHUB_TOKEN'] || coreExports.getInput('token');
if (token === undefined) {
throw new Error('GITHUB_TOKEN is not set');
@@ -61557,7 +61573,7 @@ async function run() {
const customHeadersInput = coreExports.getInput('custom-headers');
const customHeaders = parseCustomHeaders(customHeadersInput);
// Build the inference request with pre-processed messages and response format
const inferenceRequest = buildInferenceRequest(promptConfig, systemPrompt, prompt, modelName, temperature, topP, maxTokens, endpoint, token, customHeaders);
const inferenceRequest = buildInferenceRequest(promptConfig, systemPrompt, prompt, modelName, temperature, topP, maxTokens, maxCompletionTokens, endpoint, token, customHeaders);
const enableMcp = coreExports.getBooleanInput('enable-github-mcp') || false;
let modelResponse = null;
if (enableMcp) {

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@@ -46,7 +46,7 @@ export default [
parserOptions: {
project: ['tsconfig.eslint.json'],
tsconfigRootDir: '.',
tsconfigRootDir: __dirname,
},
},

984
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -23,11 +23,11 @@
"license": "MIT",
"prettier": "@github/prettier-config",
"dependencies": {
"@actions/core": "^1.11.1",
"@modelcontextprotocol/sdk": "^1.25.2",
"@actions/core": "^3.0.0",
"@modelcontextprotocol/sdk": "^1.26.0",
"@types/tmp": "^0.2.6",
"js-yaml": "^4.1.1",
"openai": "^5.11.0",
"openai": "^6.28.0",
"pkce-challenge": "^5.0.0",
"tmp": "^0.2.4"
},
@@ -37,21 +37,21 @@
"@github/prettier-config": "^0.0.6",
"@rollup/plugin-commonjs": "^28.0.5",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-typescript": "^12.1.2",
"@rollup/plugin-node-resolve": "^16.0.3",
"@rollup/plugin-typescript": "^12.3.0",
"@types/js-yaml": "^4.0.9",
"@types/node": "^24.1.0",
"@typescript-eslint/eslint-plugin": "^8.34.0",
"@types/node": "^24.12.0",
"@typescript-eslint/eslint-plugin": "^8.57.0",
"@typescript-eslint/parser": "^8.32.1",
"eslint": "^9.29.0",
"eslint-config-prettier": "^10.1.5",
"eslint-import-resolver-typescript": "^4.4.3",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-prettier": "^5.4.1",
"prettier": "^3.5.3",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-prettier": "^5.5.5",
"prettier": "^3.8.1",
"prettier-eslint": "^16.4.2",
"rollup": "^4.43.0",
"typescript": "^5.8.3",
"rollup": "^4.59.0",
"typescript": "^5.9.3",
"vitest": "^3"
},
"optionalDependencies": {

View File

@@ -121,9 +121,10 @@ function validateAndMaskHeaders(headers: Record<string, unknown>): Record<string
const sensitivePatterns = ['key', 'token', 'secret', 'password', 'authorization']
for (const [name, value] of Object.entries(headers)) {
// Validate header name (basic HTTP header name validation, RFC 7230: letters, digits, and hyphens)
if (!/^[A-Za-z0-9-]+$/.test(name)) {
core.warning(`Skipping invalid header name: ${name} (only alphanumeric characters and hyphens allowed)`)
// Validate header name (RFC 7230: token = 1*tchar)
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
if (!/^[A-Za-z0-9!#$%&'*+\-.^_`|~]+$/.test(name)) {
core.warning(`Skipping invalid header name: ${name} (contains invalid characters)`)
continue
}
@@ -143,9 +144,9 @@ function validateAndMaskHeaders(headers: Record<string, unknown>): Record<string
const lowerName = name.toLowerCase()
const isSensitive = sensitivePatterns.some(pattern => lowerName.includes(pattern))
if (isSensitive) {
core.info(`Custom header added: ${name}: ***MASKED***`)
core.debug(`Custom header added: ${name}: ***MASKED***`)
} else {
core.info(`Custom header added: ${name}: ${stringValue}`)
core.debug(`Custom header added: ${name}: ${stringValue}`)
}
}
@@ -162,7 +163,8 @@ export function buildInferenceRequest(
modelName: string,
temperature: number | undefined,
topP: number | undefined,
maxTokens: number,
maxTokens: number | undefined, // Deprecated
maxCompletionTokens: number | undefined,
endpoint: string,
token: string,
customHeaders?: Record<string, string>,
@@ -175,7 +177,8 @@ export function buildInferenceRequest(
modelName,
temperature,
topP,
maxTokens,
maxTokens, // Deprecated
maxCompletionTokens,
endpoint,
token,
responseFormat,

View File

@@ -12,7 +12,8 @@ interface ChatMessage {
export interface InferenceRequest {
messages: Array<{role: 'system' | 'user' | 'assistant' | 'tool'; content: string}>
modelName: string
maxTokens: number
maxTokens?: number // Deprecated
maxCompletionTokens?: number
endpoint: string
token: string
temperature?: number
@@ -33,6 +34,20 @@ export interface InferenceResponse {
}>
}
/**
* Build according to what input was passed, default to max_tokens.
* Only one of max_tokens or max_completion_tokens will be set.
*/
function buildMaxTokensParam(request: InferenceRequest): {max_tokens?: number; max_completion_tokens?: number} {
if (request.maxCompletionTokens != null) {
return {max_completion_tokens: request.maxCompletionTokens}
}
if (request.maxTokens != null) {
return {max_tokens: request.maxTokens}
}
return {}
}
/**
* Simple one-shot inference without tools
*/
@@ -47,10 +62,10 @@ export async function simpleInference(request: InferenceRequest): Promise<string
const chatCompletionRequest: OpenAI.Chat.Completions.ChatCompletionCreateParams = {
messages: request.messages as OpenAI.Chat.Completions.ChatCompletionMessageParam[],
max_completion_tokens: request.maxTokens,
model: request.modelName,
temperature: request.temperature,
top_p: request.topP,
...buildMaxTokensParam(request), // Note: solution around models using different underlying max tokens properties
}
// Add response format if specified
@@ -61,7 +76,7 @@ export async function simpleInference(request: InferenceRequest): Promise<string
const response = await chatCompletion(client, chatCompletionRequest, 'simpleInference')
const modelResponse = response.choices[0]?.message?.content
core.info(`Model response: ${modelResponse || 'No response content'}`)
core.debug(`Model response: ${modelResponse || 'No response content'}`)
return modelResponse || null
}
@@ -95,10 +110,10 @@ export async function mcpInference(
const chatCompletionRequest: OpenAI.Chat.Completions.ChatCompletionCreateParams = {
messages: messages as OpenAI.Chat.Completions.ChatCompletionMessageParam[],
max_completion_tokens: request.maxTokens,
model: request.modelName,
temperature: request.temperature,
top_p: request.topP,
...buildMaxTokensParam(request), // Note: solution around models using different underlying max tokens properties
}
// Add response format if specified (only on final iteration to avoid conflicts with tool calls)
@@ -116,7 +131,7 @@ export async function mcpInference(
const modelResponse = assistantMessage?.content
const toolCalls = assistantMessage?.tool_calls
core.info(`Model response: ${modelResponse || 'No response content'}`)
core.debug(`Model response: ${modelResponse || 'No response content'}`)
messages.push({
role: 'assistant',
@@ -181,16 +196,14 @@ async function chatCompletion(
try {
response = JSON.parse(response)
} catch (e) {
const preview = response.slice(0, 400)
throw new Error(
`${context}: Chat completion response was a string and not valid JSON (${(e as Error).message}). Preview: ${preview}`,
`${context}: Chat completion response was a string and not valid JSON (${(e as Error).message})`,
)
}
}
if (!response || typeof response !== 'object' || !('choices' in response)) {
const preview = JSON.stringify(response)?.slice(0, 800)
throw new Error(`${context}: Unexpected response shape (no choices). Preview: ${preview}`)
throw new Error(`${context}: Unexpected response shape (no choices)`)
}
return response as OpenAI.Chat.Completions.ChatCompletion

View File

@@ -48,19 +48,25 @@ export async function run(): Promise<void> {
// Get common parameters
const modelName = promptConfig?.model || core.getInput('model')
let maxTokens = promptConfig?.modelParameters?.maxTokens ?? core.getInput('max-tokens')
if (typeof maxTokens === 'string') {
maxTokens = parseInt(maxTokens, 10)
}
// Parse token limit inputs
const maxCompletionTokensInput =
promptConfig?.modelParameters?.maxCompletionTokens ?? core.getInput('max-completion-tokens')
const maxCompletionTokens = maxCompletionTokensInput ? Number(maxCompletionTokensInput) : undefined
const maxTokensInput = promptConfig?.modelParameters?.maxTokens ?? core.getInput('max-tokens')
const maxTokens = maxCompletionTokens != null ? undefined : maxTokensInput ? Number(maxTokensInput) : undefined
const token = process.env['GITHUB_TOKEN'] || core.getInput('token')
if (token === undefined) {
throw new Error('GITHUB_TOKEN is not set')
}
core.setSecret(token)
// Get GitHub MCP token (use dedicated token if provided, otherwise fall back to main token)
const githubMcpToken = core.getInput('github-mcp-token') || token
core.setSecret(githubMcpToken)
const githubMcpToolsets = core.getInput('github-mcp-toolsets')
const endpoint = core.getInput('endpoint')
@@ -85,6 +91,7 @@ export async function run(): Promise<void> {
temperature,
topP,
maxTokens,
maxCompletionTokens,
endpoint,
token,
customHeaders,

View File

@@ -96,7 +96,7 @@ export async function connectToGitHubMCP(token: string, toolsets?: string): Prom
* Execute a single tool call via GitHub MCP
*/
export async function executeToolCall(githubMcpClient: Client, toolCall: ToolCall): Promise<ToolResult> {
core.info(`Executing GitHub MCP tool: ${toolCall.function.name} with args: ${toolCall.function.arguments}`)
core.debug(`Executing GitHub MCP tool: ${toolCall.function.name} with args: ${toolCall.function.arguments}`)
try {
const args = JSON.parse(toolCall.function.arguments)
@@ -106,7 +106,7 @@ export async function executeToolCall(githubMcpClient: Client, toolCall: ToolCal
arguments: args,
})
core.info(`GitHub MCP tool ${toolCall.function.name} executed successfully`)
core.debug(`GitHub MCP tool ${toolCall.function.name} executed successfully`)
return {
tool_call_id: toolCall.id,

View File

@@ -8,7 +8,8 @@ export interface PromptMessage {
}
export interface ModelParameters {
maxTokens?: number
maxTokens?: number // Deprecated
maxCompletionTokens?: number
temperature?: number
topP?: number
}