17 Commits

Author SHA1 Message Date
Sean Goedecke
5022b33bc1 Merge pull request #148 from dsanders11/feat/prompt-yaml-model-parameters
feat: support modelParameters in prompt.yaml files
2025-11-24 11:27:47 +11:00
David Sanders
c9e14713bc chore: update dist 2025-11-23 16:19:48 -08:00
David Sanders
39308142df chore: apply code review comment
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-23 16:19:12 -08:00
David Sanders
48f0edec4d feat: support modelParameters in prompt.yaml files 2025-11-23 16:07:11 -08:00
Sean Goedecke
36ea1371dc Merge pull request #136 from dsanders11/fix/template-substition
fix: do template substition after parsing prompt YAML
2025-11-24 10:22:42 +11:00
Sean Goedecke
de16a30c20 Merge branch 'main' into fix/template-substition 2025-11-24 10:21:49 +11:00
Sean Goedecke
dd3dff10ba Merge pull request #147 from srt32/patch-1
Clarify PAT requirement for github-mcp-token
2025-11-24 10:18:50 +11:00
Simon Taranto
4bb01ee5ee Clarify PAT requirement for github-mcp-token
I mistakenly read the description of the mcp-token field to mean I needed a "PAT for MCP" as if there were a PAT permission for MCP. This change clarifies the language.
2025-11-21 13:36:45 -05:00
David Sanders
af1c1c29a3 fix: do template substition after parsing prompt YAML 2025-10-20 21:32:06 -07:00
Sean Goedecke
83bb5ca3e8 Merge pull request #93 from FidelusAleksander/main
docs: update documentation on mcp usage
2025-08-26 18:13:39 +10:00
Aleksander Fidelus
4d2337d006 Merge branch 'actions:main' into main 2025-08-25 11:08:41 +02:00
Yuzuki
7ba7530ad4 Merge pull request #94 from actions/dependabot/github_actions/actions/checkout-5
chore(deps): bump actions/checkout from 4 to 5
2025-08-25 14:00:39 +10:00
Yuzuki
4d7d83c494 Merge branch 'main' into dependabot/github_actions/actions/checkout-5 2025-08-25 13:55:57 +10:00
FidelusAleksander
7fa0024f13 docs: run prettier 2025-08-18 14:42:29 +02:00
dependabot[bot]
fc6f9a0800 chore(deps): bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-18 03:58:02 +00:00
FidelusAleksander
a1d07305b7 docs: update github-mcp-token description 2025-08-15 08:22:55 +02:00
FidelusAleksander
6e0d8949d8 docs: update documentation on mcp usage 2025-08-15 07:52:22 +02:00
14 changed files with 74 additions and 21 deletions

View File

@@ -28,7 +28,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup Node.js
id: setup-node

View File

@@ -20,7 +20,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup Node.js
id: setup-node
@@ -54,7 +54,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Test Local Action
id: test-action
@@ -77,7 +77,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Create Prompt File
run: echo "hello" > prompt.txt

View File

@@ -30,7 +30,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Initialize CodeQL
id: initialize

View File

@@ -27,7 +27,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup Node.js
id: setup-node

View File

@@ -21,7 +21,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0

View File

@@ -162,6 +162,9 @@ This action now supports **read-only** integration with the GitHub-hosted Model
Context Protocol (MCP) server, which provides access to GitHub tools like
repository management, issue tracking, and pull request operations.
> [!NOTE]
> The GitHub MCP integration requires a Personal Access Token (PAT) and cannot use the built-in `GITHUB_TOKEN`.
```yaml
steps:
- name: AI Inference with GitHub Tools
@@ -209,7 +212,7 @@ the action:
| `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 |
| `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). Use a separate PAT for tighter security | `""` |
| `github-mcp-token` | Token to use for GitHub MCP server (defaults to the main token if not specified). This must be a PAT in order for MCP to work | `""` |
## Outputs

View File

@@ -106,6 +106,8 @@ describe('helpers.ts - inference request building', () => {
undefined,
undefined,
'gpt-4',
undefined,
undefined,
100,
'https://api.test.com',
'test-token',
@@ -117,6 +119,8 @@ describe('helpers.ts - inference request building', () => {
{role: 'user', content: 'User message'},
],
modelName: 'gpt-4',
temperature: undefined,
topP: undefined,
maxTokens: 100,
endpoint: 'https://api.test.com',
token: 'test-token',
@@ -136,6 +140,8 @@ describe('helpers.ts - inference request building', () => {
'System prompt',
'User prompt',
'gpt-4',
undefined,
undefined,
100,
'https://api.test.com',
'test-token',
@@ -147,6 +153,8 @@ describe('helpers.ts - inference request building', () => {
{role: 'user', content: 'User prompt'},
],
modelName: 'gpt-4',
temperature: undefined,
topP: undefined,
maxTokens: 100,
endpoint: 'https://api.test.com',
token: 'test-token',

View File

@@ -55,7 +55,7 @@ inputs:
required: false
default: 'false'
github-mcp-token:
description: The token to use for GitHub MCP server (defaults to GITHUB_TOKEN if not specified)
description: The token to use for GitHub MCP server (defaults to the main token if not specified). This must be a PAT for MCP to work.
required: false
default: ''

26
dist/index.js generated vendored
View File

@@ -49496,6 +49496,8 @@ async function simpleInference(request) {
messages: request.messages,
max_tokens: request.maxTokens,
model: request.modelName,
temperature: request.temperature,
top_p: request.topP,
};
// Add response format if specified
if (request.responseFormat) {
@@ -49530,6 +49532,8 @@ async function mcpInference(request, githubMcpClient) {
messages: messages,
max_tokens: request.maxTokens,
model: request.modelName,
temperature: request.temperature,
top_p: request.topP,
};
// Add response format if specified (only on final iteration to avoid conflicts with tool calls)
if (finalMessage && request.responseFormat) {
@@ -49685,12 +49689,14 @@ function buildResponseFormat(promptConfig) {
/**
* Build complete InferenceRequest from prompt config and inputs
*/
function buildInferenceRequest(promptConfig, systemPrompt, prompt, modelName, maxTokens, endpoint, token) {
function buildInferenceRequest(promptConfig, systemPrompt, prompt, modelName, temperature, topP, maxTokens, endpoint, token) {
const messages = buildMessages(promptConfig, systemPrompt, prompt);
const responseFormat = buildResponseFormat(promptConfig);
return {
messages,
modelName,
temperature,
topP,
maxTokens,
endpoint,
token,
@@ -52572,10 +52578,8 @@ function loadPromptFile(filePath, templateVariables = {}) {
throw new Error(`Prompt file not found: ${filePath}`);
}
const fileContent = fs.readFileSync(filePath, 'utf-8');
// Apply template variable substitution
const processedContent = replaceTemplateVariables(fileContent, templateVariables);
try {
const config = load(processedContent);
const config = load(fileContent);
if (!config.messages || !Array.isArray(config.messages)) {
throw new Error('Prompt file must contain a "messages" array');
}
@@ -52588,6 +52592,13 @@ function loadPromptFile(filePath, templateVariables = {}) {
throw new Error(`Invalid message role: ${message.role}`);
}
}
// Prepare messages by replacing template variables with actual content
config.messages = config.messages.map(msg => {
return {
...msg,
content: replaceTemplateVariables(msg.content, templateVariables),
};
});
return config;
}
catch (error) {
@@ -52635,7 +52646,10 @@ async function run() {
}
// Get common parameters
const modelName = promptConfig?.model || coreExports.getInput('model');
const maxTokens = parseInt(coreExports.getInput('max-tokens'), 10);
let maxTokens = promptConfig?.modelParameters?.maxTokens ?? coreExports.getInput('max-tokens');
if (typeof maxTokens === 'string') {
maxTokens = parseInt(maxTokens, 10);
}
const token = process.env['GITHUB_TOKEN'] || coreExports.getInput('token');
if (token === undefined) {
throw new Error('GITHUB_TOKEN is not set');
@@ -52644,7 +52658,7 @@ async function run() {
const githubMcpToken = coreExports.getInput('github-mcp-token') || token;
const endpoint = coreExports.getInput('endpoint');
// Build the inference request with pre-processed messages and response format
const inferenceRequest = buildInferenceRequest(promptConfig, systemPrompt, prompt, modelName, maxTokens, endpoint, token);
const inferenceRequest = buildInferenceRequest(promptConfig, systemPrompt, prompt, modelName, promptConfig?.modelParameters?.temperature, promptConfig?.modelParameters?.topP, maxTokens, endpoint, token);
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

@@ -82,6 +82,8 @@ export function buildInferenceRequest(
systemPrompt: string | undefined,
prompt: string | undefined,
modelName: string,
temperature: number | undefined,
topP: number | undefined,
maxTokens: number,
endpoint: string,
token: string,
@@ -92,6 +94,8 @@ export function buildInferenceRequest(
return {
messages,
modelName,
temperature,
topP,
maxTokens,
endpoint,
token,

View File

@@ -15,6 +15,8 @@ export interface InferenceRequest {
maxTokens: number
endpoint: string
token: string
temperature?: number
topP?: number
responseFormat?: {type: 'json_schema'; json_schema: unknown} // Processed response format for the API
}
@@ -45,6 +47,8 @@ export async function simpleInference(request: InferenceRequest): Promise<string
messages: request.messages as OpenAI.Chat.Completions.ChatCompletionMessageParam[],
max_tokens: request.maxTokens,
model: request.modelName,
temperature: request.temperature,
top_p: request.topP,
}
// Add response format if specified
@@ -90,6 +94,8 @@ export async function mcpInference(
messages: messages as OpenAI.Chat.Completions.ChatCompletionMessageParam[],
max_tokens: request.maxTokens,
model: request.modelName,
temperature: request.temperature,
top_p: request.topP,
}
// Add response format if specified (only on final iteration to avoid conflicts with tool calls)

View File

@@ -53,7 +53,11 @@ export async function run(): Promise<void> {
// Get common parameters
const modelName = promptConfig?.model || core.getInput('model')
const maxTokens = parseInt(core.getInput('max-tokens'), 10)
let maxTokens = promptConfig?.modelParameters?.maxTokens ?? core.getInput('max-tokens')
if (typeof maxTokens === 'string') {
maxTokens = parseInt(maxTokens, 10)
}
const token = process.env['GITHUB_TOKEN'] || core.getInput('token')
if (token === undefined) {
@@ -71,6 +75,8 @@ export async function run(): Promise<void> {
systemPrompt,
prompt,
modelName,
promptConfig?.modelParameters?.temperature,
promptConfig?.modelParameters?.topP,
maxTokens,
endpoint,
token,

View File

@@ -7,9 +7,16 @@ export interface PromptMessage {
content: string
}
export interface ModelParameters {
maxTokens?: number
temperature?: number
topP?: number
}
export interface PromptConfig {
messages: PromptMessage[]
model?: string
modelParameters?: ModelParameters
responseFormat?: 'text' | 'json_schema'
jsonSchema?: string
}
@@ -101,11 +108,8 @@ export function loadPromptFile(filePath: string, templateVariables: TemplateVari
const fileContent = fs.readFileSync(filePath, 'utf-8')
// Apply template variable substitution
const processedContent = replaceTemplateVariables(fileContent, templateVariables)
try {
const config = yaml.load(processedContent) as PromptConfig
const config = yaml.load(fileContent) as PromptConfig
if (!config.messages || !Array.isArray(config.messages)) {
throw new Error('Prompt file must contain a "messages" array')
@@ -121,6 +125,14 @@ export function loadPromptFile(filePath: string, templateVariables: TemplateVari
}
}
// Prepare messages by replacing template variables with actual content
config.messages = config.messages.map(msg => {
return {
...msg,
content: replaceTemplateVariables(msg.content, templateVariables),
}
})
return config
} catch (error) {
throw new Error(`Failed to parse prompt file: ${error instanceof Error ? error.message : 'Unknown error'}`)