Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5b826567d | ||
|
|
4738a2d212 | ||
|
|
afaedf6677 | ||
|
|
78d6b91d0b | ||
|
|
1a66a5968c | ||
|
|
efbbaa2667 | ||
|
|
a57b52eccd | ||
|
|
32ebbe708a | ||
|
|
fbd6a39716 |
@@ -14,16 +14,24 @@ your actions.
|
|||||||
Create a workflow to use the AI inference action:
|
Create a workflow to use the AI inference action:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
name: 'AI inference'
|
||||||
- name: Test Local Action
|
on: workflow_dispatch
|
||||||
id: inference
|
|
||||||
uses: actions/ai-inference@v1
|
|
||||||
with:
|
|
||||||
prompt: 'Hello!'
|
|
||||||
|
|
||||||
- name: Print Output
|
jobs:
|
||||||
id: output
|
inference:
|
||||||
run: echo "${{ steps.test-action.outputs.response }}"
|
permissions:
|
||||||
|
models: read
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Test Local Action
|
||||||
|
id: inference
|
||||||
|
uses: actions/ai-inference@v1
|
||||||
|
with:
|
||||||
|
prompt: 'Hello!'
|
||||||
|
|
||||||
|
- name: Print Output
|
||||||
|
id: output
|
||||||
|
run: echo "${{ steps.inference.outputs.response }}"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Inputs
|
## Inputs
|
||||||
@@ -31,13 +39,14 @@ steps:
|
|||||||
Various inputs are defined in [`action.yml`](action.yml) to let you configure
|
Various inputs are defined in [`action.yml`](action.yml) to let you configure
|
||||||
the action:
|
the action:
|
||||||
|
|
||||||
| Name | Description | Default |
|
| Name | Description | Default |
|
||||||
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
|
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
|
||||||
| `token` | Token to use for inference. Typically the GITHUB_TOKEN secret | `github.token` |
|
| `token` | Token to use for inference. Typically the GITHUB_TOKEN secret | `github.token` |
|
||||||
| `prompt` | The prompt to send to the model | N/A |
|
| `prompt` | The prompt to send to the model | N/A |
|
||||||
| `model` | The model to use for inference. Must be available in the [GitHub Models](https://github.com/marketplace?type=models) catalog | `gpt-4o` |
|
| `system-prompt` | The system prompt to send to the model | `""` |
|
||||||
| `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` |
|
| `model` | The model to use for inference. Must be available in the [GitHub Models](https://github.com/marketplace?type=models) catalog | `gpt-4o` |
|
||||||
| `max_tokens` | The max number of tokens to generate | 200 |
|
| `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 |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
|
|||||||
+12
-4
@@ -4,27 +4,35 @@ author: 'GitHub'
|
|||||||
|
|
||||||
# Add your action's branding here. This will appear on the GitHub Marketplace.
|
# Add your action's branding here. This will appear on the GitHub Marketplace.
|
||||||
branding:
|
branding:
|
||||||
icon: 'play-circle'
|
icon: 'message-square'
|
||||||
color: red
|
color: red
|
||||||
|
|
||||||
# Define your inputs here.
|
# Define your inputs here.
|
||||||
inputs:
|
inputs:
|
||||||
prompt:
|
prompt:
|
||||||
description: Your input description here
|
description: The prompt for the model
|
||||||
required: true
|
required: true
|
||||||
default: ''
|
default: ''
|
||||||
model:
|
model:
|
||||||
description: The model to use
|
description: The model to use
|
||||||
required: false
|
required: false
|
||||||
default: 'gpt-4o'
|
default: 'openai/gpt-4o'
|
||||||
endpoint:
|
endpoint:
|
||||||
description: The endpoint to use
|
description: The endpoint to use
|
||||||
required: false
|
required: false
|
||||||
default: 'https://models.github.ai/inference'
|
default: 'https://models.github.ai/inference'
|
||||||
max_tokens:
|
system-prompt:
|
||||||
|
description: The system prompt for the model
|
||||||
|
required: false
|
||||||
|
default: 'You are a helpful assistant'
|
||||||
|
max-tokens:
|
||||||
description: The maximum number of tokens to generate
|
description: The maximum number of tokens to generate
|
||||||
required: false
|
required: false
|
||||||
default: '200'
|
default: '200'
|
||||||
|
token:
|
||||||
|
description: The token to use
|
||||||
|
required: false
|
||||||
|
default: ${{ github.token }}
|
||||||
|
|
||||||
# Define your outputs here.
|
# Define your outputs here.
|
||||||
outputs:
|
outputs:
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="116" height="20" role="img" aria-label="Coverage: 89.47%"><title>Coverage: 89.47%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="116" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="63" height="20" fill="#555"/><rect x="63" width="53" height="20" fill="#dfb317"/><rect width="116" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">Coverage</text><text x="325" y="140" transform="scale(.1)" fill="#fff" textLength="530">Coverage</text><text aria-hidden="true" x="885" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">89.47%</text><text x="885" y="140" transform="scale(.1)" fill="#fff" textLength="430">89.47%</text></g></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="116" height="20" role="img" aria-label="Coverage: 76.92%"><title>Coverage: 76.92%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="116" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="63" height="20" fill="#555"/><rect x="63" width="53" height="20" fill="#e05d44"/><rect width="116" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">Coverage</text><text x="325" y="140" transform="scale(.1)" fill="#fff" textLength="530">Coverage</text><text aria-hidden="true" x="885" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">76.92%</text><text x="885" y="140" transform="scale(.1)" fill="#fff" textLength="430">76.92%</text></g></svg>
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
+24
-7
@@ -33559,21 +33559,28 @@ async function run() {
|
|||||||
if (prompt === undefined || prompt === '') {
|
if (prompt === undefined || prompt === '') {
|
||||||
throw new Error('prompt is not set');
|
throw new Error('prompt is not set');
|
||||||
}
|
}
|
||||||
const systemPrompt = coreExports.getInput('system_prompt');
|
const systemPrompt = coreExports.getInput('system-prompt');
|
||||||
const modelName = coreExports.getInput('model');
|
const modelName = coreExports.getInput('model');
|
||||||
const maxTokens = parseInt(coreExports.getInput('max_tokens'), 10);
|
const maxTokens = parseInt(coreExports.getInput('max-tokens'), 10);
|
||||||
const token = process.env['GITHUB_TOKEN'];
|
const token = coreExports.getInput('token') || process.env['GITHUB_TOKEN'];
|
||||||
if (token === undefined) {
|
if (token === undefined) {
|
||||||
throw new Error('GITHUB_TOKEN is not set');
|
throw new Error('GITHUB_TOKEN is not set');
|
||||||
}
|
}
|
||||||
const endpoint = coreExports.getInput('endpoint');
|
let endpoint = coreExports.getInput('endpoint');
|
||||||
|
// If we're in an org-owned repository, we should use the org-owned endpoint
|
||||||
|
const repoOwner = process.env.GITHUB_REPOSITORY_OWNER;
|
||||||
|
const ownerType = process.env.GITHUB_REPOSITORY_OWNER_TYPE;
|
||||||
|
if (endpoint == 'https://models.github.ai/inference' &&
|
||||||
|
ownerType == 'Organization') {
|
||||||
|
endpoint = `https://models.github.ai/${repoOwner}/inference`;
|
||||||
|
}
|
||||||
const client = createClient(endpoint, new AzureKeyCredential(token));
|
const client = createClient(endpoint, new AzureKeyCredential(token));
|
||||||
const response = await client.path('/chat/completions').post({
|
const response = await client.path('/chat/completions').post({
|
||||||
body: {
|
body: {
|
||||||
messages: [
|
messages: [
|
||||||
{
|
{
|
||||||
role: 'system',
|
role: 'system',
|
||||||
content: systemPrompt || 'You are a helpful assistant.'
|
content: systemPrompt
|
||||||
},
|
},
|
||||||
{ role: 'user', content: prompt }
|
{ role: 'user', content: prompt }
|
||||||
],
|
],
|
||||||
@@ -33584,7 +33591,13 @@ async function run() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (isUnexpected(response)) {
|
if (isUnexpected(response)) {
|
||||||
throw response.body.error;
|
if (response.body.error) {
|
||||||
|
throw response.body.error;
|
||||||
|
}
|
||||||
|
throw new Error('An error occurred while fetching the response (' +
|
||||||
|
response.status +
|
||||||
|
'): ' +
|
||||||
|
response.body);
|
||||||
}
|
}
|
||||||
const modelResponse = response.body.choices[0].message.content;
|
const modelResponse = response.body.choices[0].message.content;
|
||||||
// Set outputs for other workflow steps to use
|
// Set outputs for other workflow steps to use
|
||||||
@@ -33592,8 +33605,12 @@ async function run() {
|
|||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
// Fail the workflow run if an error occurs
|
// Fail the workflow run if an error occurs
|
||||||
if (error instanceof Error)
|
if (error instanceof Error) {
|
||||||
coreExports.setFailed(error.message);
|
coreExports.setFailed(error.message);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
coreExports.setFailed('An unexpected error occurred');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+30
-7
@@ -14,15 +14,26 @@ export async function run(): Promise<void> {
|
|||||||
throw new Error('prompt is not set')
|
throw new Error('prompt is not set')
|
||||||
}
|
}
|
||||||
|
|
||||||
const systemPrompt: string = core.getInput('system_prompt')
|
const systemPrompt: string = core.getInput('system-prompt')
|
||||||
const modelName: string = core.getInput('model')
|
const modelName: string = core.getInput('model')
|
||||||
const maxTokens: number = parseInt(core.getInput('max_tokens'), 10)
|
const maxTokens: number = parseInt(core.getInput('max-tokens'), 10)
|
||||||
|
|
||||||
const token = process.env['GITHUB_TOKEN']
|
const token = core.getInput('token') || process.env['GITHUB_TOKEN']
|
||||||
if (token === undefined) {
|
if (token === undefined) {
|
||||||
throw new Error('GITHUB_TOKEN is not set')
|
throw new Error('GITHUB_TOKEN is not set')
|
||||||
}
|
}
|
||||||
const endpoint = core.getInput('endpoint')
|
|
||||||
|
let endpoint = core.getInput('endpoint')
|
||||||
|
|
||||||
|
// If we're in an org-owned repository, we should use the org-owned endpoint
|
||||||
|
const repoOwner = process.env.GITHUB_REPOSITORY_OWNER
|
||||||
|
const ownerType = process.env.GITHUB_REPOSITORY_OWNER_TYPE
|
||||||
|
if (
|
||||||
|
endpoint == 'https://models.github.ai/inference' &&
|
||||||
|
ownerType == 'Organization'
|
||||||
|
) {
|
||||||
|
endpoint = `https://models.github.ai/${repoOwner}/inference`
|
||||||
|
}
|
||||||
|
|
||||||
const client = ModelClient(endpoint, new AzureKeyCredential(token))
|
const client = ModelClient(endpoint, new AzureKeyCredential(token))
|
||||||
|
|
||||||
@@ -31,7 +42,7 @@ export async function run(): Promise<void> {
|
|||||||
messages: [
|
messages: [
|
||||||
{
|
{
|
||||||
role: 'system',
|
role: 'system',
|
||||||
content: systemPrompt || 'You are a helpful assistant.'
|
content: systemPrompt
|
||||||
},
|
},
|
||||||
{ role: 'user', content: prompt }
|
{ role: 'user', content: prompt }
|
||||||
],
|
],
|
||||||
@@ -43,7 +54,15 @@ export async function run(): Promise<void> {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (isUnexpected(response)) {
|
if (isUnexpected(response)) {
|
||||||
throw response.body.error
|
if (response.body.error) {
|
||||||
|
throw response.body.error
|
||||||
|
}
|
||||||
|
throw new Error(
|
||||||
|
'An error occurred while fetching the response (' +
|
||||||
|
response.status +
|
||||||
|
'): ' +
|
||||||
|
response.body
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const modelResponse: string | null =
|
const modelResponse: string | null =
|
||||||
@@ -53,6 +72,10 @@ export async function run(): Promise<void> {
|
|||||||
core.setOutput('response', modelResponse || '')
|
core.setOutput('response', modelResponse || '')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Fail the workflow run if an error occurs
|
// Fail the workflow run if an error occurs
|
||||||
if (error instanceof Error) core.setFailed(error.message)
|
if (error instanceof Error) {
|
||||||
|
core.setFailed(error.message)
|
||||||
|
} else {
|
||||||
|
core.setFailed('An unexpected error occurred')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user