Formatting
This commit is contained in:
+41
-27
@@ -30,10 +30,14 @@ jest.unstable_mockModule('@azure-rest/ai-inference', () => ({
|
|||||||
|
|
||||||
// Default to throwing errors to catch unexpected calls
|
// Default to throwing errors to catch unexpected calls
|
||||||
const mockExistsSync = jest.fn().mockImplementation(() => {
|
const mockExistsSync = jest.fn().mockImplementation(() => {
|
||||||
throw new Error('Unexpected call to existsSync - test should override this implementation')
|
throw new Error(
|
||||||
|
'Unexpected call to existsSync - test should override this implementation'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
const mockReadFileSync = jest.fn().mockImplementation(() => {
|
const mockReadFileSync = jest.fn().mockImplementation(() => {
|
||||||
throw new Error('Unexpected call to readFileSync - test should override this implementation')
|
throw new Error(
|
||||||
|
'Unexpected call to readFileSync - test should override this implementation'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,9 +45,12 @@ const mockReadFileSync = jest.fn().mockImplementation(() => {
|
|||||||
* @param fileContents - Object mapping file paths to their contents
|
* @param fileContents - Object mapping file paths to their contents
|
||||||
* @param nonExistentFiles - Array of file paths that should be treated as non-existent
|
* @param nonExistentFiles - Array of file paths that should be treated as non-existent
|
||||||
*/
|
*/
|
||||||
function mockFileContent(fileContents: Record<string, string> = {}, nonExistentFiles: string[] = []): void {
|
function mockFileContent(
|
||||||
|
fileContents: Record<string, string> = {},
|
||||||
|
nonExistentFiles: string[] = []
|
||||||
|
): void {
|
||||||
// Mock existsSync to return true for files that exist, false for those that don't
|
// Mock existsSync to return true for files that exist, false for those that don't
|
||||||
mockExistsSync.mockImplementation(function(this: any, path: any): boolean {
|
mockExistsSync.mockImplementation(function (this: any, path: any): boolean {
|
||||||
if (nonExistentFiles.includes(path)) {
|
if (nonExistentFiles.includes(path)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -51,7 +58,11 @@ function mockFileContent(fileContents: Record<string, string> = {}, nonExistentF
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Mock readFileSync to return the content for known files
|
// Mock readFileSync to return the content for known files
|
||||||
mockReadFileSync.mockImplementation(function(this: any, path: any, encoding: any): string {
|
mockReadFileSync.mockImplementation(function (
|
||||||
|
this: any,
|
||||||
|
path: any,
|
||||||
|
encoding: any
|
||||||
|
): string {
|
||||||
if (encoding === 'utf-8' && path in fileContents) {
|
if (encoding === 'utf-8' && path in fileContents) {
|
||||||
return fileContents[path]
|
return fileContents[path]
|
||||||
}
|
}
|
||||||
@@ -66,11 +77,11 @@ function mockFileContent(fileContents: Record<string, string> = {}, nonExistentF
|
|||||||
function mockInputs(inputs: Record<string, string> = {}): void {
|
function mockInputs(inputs: Record<string, string> = {}): void {
|
||||||
// Default values that are applied unless overridden
|
// Default values that are applied unless overridden
|
||||||
const defaultInputs: Record<string, string> = {
|
const defaultInputs: Record<string, string> = {
|
||||||
'token': 'fake-token'
|
token: 'fake-token'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine defaults with user-provided inputs
|
// Combine defaults with user-provided inputs
|
||||||
const allInputs: Record<string, string> = {...defaultInputs, ...inputs}
|
const allInputs: Record<string, string> = { ...defaultInputs, ...inputs }
|
||||||
|
|
||||||
core.getInput.mockImplementation((name: string) => {
|
core.getInput.mockImplementation((name: string) => {
|
||||||
return allInputs[name] || ''
|
return allInputs[name] || ''
|
||||||
@@ -81,11 +92,7 @@ function mockInputs(inputs: Record<string, string> = {}): void {
|
|||||||
* Helper function to verify common response assertions
|
* Helper function to verify common response assertions
|
||||||
*/
|
*/
|
||||||
function verifyStandardResponse(): void {
|
function verifyStandardResponse(): void {
|
||||||
expect(core.setOutput).toHaveBeenNthCalledWith(
|
expect(core.setOutput).toHaveBeenNthCalledWith(1, 'response', 'Hello, user!')
|
||||||
1,
|
|
||||||
'response',
|
|
||||||
'Hello, user!'
|
|
||||||
)
|
|
||||||
expect(core.setOutput).toHaveBeenNthCalledWith(
|
expect(core.setOutput).toHaveBeenNthCalledWith(
|
||||||
2,
|
2,
|
||||||
'response-file',
|
'response-file',
|
||||||
@@ -107,13 +114,13 @@ const { run } = await import('../src/main.js')
|
|||||||
describe('main.ts', () => {
|
describe('main.ts', () => {
|
||||||
// Reset all mocks before each test
|
// Reset all mocks before each test
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks()
|
||||||
});
|
})
|
||||||
|
|
||||||
it('Sets the response output', async () => {
|
it('Sets the response output', async () => {
|
||||||
// Set the action's inputs as return values from core.getInput().
|
// Set the action's inputs as return values from core.getInput().
|
||||||
mockInputs({
|
mockInputs({
|
||||||
'prompt': 'Hello, AI!',
|
prompt: 'Hello, AI!',
|
||||||
'system-prompt': 'You are a test assistant.'
|
'system-prompt': 'You are a test assistant.'
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -125,14 +132,17 @@ describe('main.ts', () => {
|
|||||||
it('Sets a failed status when no prompt is set', async () => {
|
it('Sets a failed status when no prompt is set', async () => {
|
||||||
// Clear the getInput mock and simulate no prompt or prompt-file input
|
// Clear the getInput mock and simulate no prompt or prompt-file input
|
||||||
mockInputs({
|
mockInputs({
|
||||||
'prompt': '',
|
prompt: '',
|
||||||
'prompt-file': ''
|
'prompt-file': ''
|
||||||
})
|
})
|
||||||
|
|
||||||
await run()
|
await run()
|
||||||
|
|
||||||
// Verify that the action was marked as failed.
|
// Verify that the action was marked as failed.
|
||||||
expect(core.setFailed).toHaveBeenNthCalledWith(1, 'Neither prompt-file nor prompt was set')
|
expect(core.setFailed).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
'Neither prompt-file nor prompt was set'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('uses prompt-file', async () => {
|
it('uses prompt-file', async () => {
|
||||||
@@ -188,7 +198,7 @@ describe('main.ts', () => {
|
|||||||
|
|
||||||
// Set up input mocks
|
// Set up input mocks
|
||||||
mockInputs({
|
mockInputs({
|
||||||
'prompt': promptString,
|
prompt: promptString,
|
||||||
'prompt-file': promptFile,
|
'prompt-file': promptFile,
|
||||||
'system-prompt': 'You are a test assistant.'
|
'system-prompt': 'You are a test assistant.'
|
||||||
})
|
})
|
||||||
@@ -206,7 +216,7 @@ describe('main.ts', () => {
|
|||||||
role: 'system',
|
role: 'system',
|
||||||
content: expect.any(String)
|
content: expect.any(String)
|
||||||
},
|
},
|
||||||
{ role: 'user', content: promptFileContent } // Should use the file content, not the string input
|
{ role: 'user', content: promptFileContent } // Should use the file content, not the string input
|
||||||
],
|
],
|
||||||
max_tokens: expect.any(Number),
|
max_tokens: expect.any(Number),
|
||||||
model: expect.any(String)
|
model: expect.any(String)
|
||||||
@@ -218,7 +228,8 @@ describe('main.ts', () => {
|
|||||||
|
|
||||||
it('uses system-prompt-file', async () => {
|
it('uses system-prompt-file', async () => {
|
||||||
const systemPromptFile = 'system-prompt.txt'
|
const systemPromptFile = 'system-prompt.txt'
|
||||||
const systemPromptContent = 'You are a specialized system assistant for testing'
|
const systemPromptContent =
|
||||||
|
'You are a specialized system assistant for testing'
|
||||||
|
|
||||||
// Set up mock to return specific content for the system prompt file
|
// Set up mock to return specific content for the system prompt file
|
||||||
mockFileContent({
|
mockFileContent({
|
||||||
@@ -227,7 +238,7 @@ describe('main.ts', () => {
|
|||||||
|
|
||||||
// Set up input mocks
|
// Set up input mocks
|
||||||
mockInputs({
|
mockInputs({
|
||||||
'prompt': 'Hello, AI!',
|
prompt: 'Hello, AI!',
|
||||||
'system-prompt-file': systemPromptFile
|
'system-prompt-file': systemPromptFile
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -246,7 +257,7 @@ describe('main.ts', () => {
|
|||||||
|
|
||||||
// Set up input mocks
|
// Set up input mocks
|
||||||
mockInputs({
|
mockInputs({
|
||||||
'prompt': 'Hello, AI!',
|
prompt: 'Hello, AI!',
|
||||||
'system-prompt-file': systemPromptFile
|
'system-prompt-file': systemPromptFile
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -260,8 +271,10 @@ describe('main.ts', () => {
|
|||||||
|
|
||||||
it('prefers system-prompt-file over system-prompt when both are provided', async () => {
|
it('prefers system-prompt-file over system-prompt when both are provided', async () => {
|
||||||
const systemPromptFile = 'system-prompt.txt'
|
const systemPromptFile = 'system-prompt.txt'
|
||||||
const systemPromptFileContent = 'You are a specialized system assistant from file'
|
const systemPromptFileContent =
|
||||||
const systemPromptString = 'You are a basic system assistant from input parameter'
|
'You are a specialized system assistant from file'
|
||||||
|
const systemPromptString =
|
||||||
|
'You are a basic system assistant from input parameter'
|
||||||
|
|
||||||
// Set up mock to return specific content for the system prompt file
|
// Set up mock to return specific content for the system prompt file
|
||||||
mockFileContent({
|
mockFileContent({
|
||||||
@@ -270,7 +283,7 @@ describe('main.ts', () => {
|
|||||||
|
|
||||||
// Set up input mocks
|
// Set up input mocks
|
||||||
mockInputs({
|
mockInputs({
|
||||||
'prompt': 'Hello, AI!',
|
prompt: 'Hello, AI!',
|
||||||
'system-prompt-file': systemPromptFile,
|
'system-prompt-file': systemPromptFile,
|
||||||
'system-prompt': systemPromptString
|
'system-prompt': systemPromptString
|
||||||
})
|
})
|
||||||
@@ -302,7 +315,8 @@ describe('main.ts', () => {
|
|||||||
const promptFile = 'prompt.txt'
|
const promptFile = 'prompt.txt'
|
||||||
const promptContent = 'This is a prompt from a file'
|
const promptContent = 'This is a prompt from a file'
|
||||||
const systemPromptFile = 'system-prompt.txt'
|
const systemPromptFile = 'system-prompt.txt'
|
||||||
const systemPromptContent = 'You are a specialized system assistant from file'
|
const systemPromptContent =
|
||||||
|
'You are a specialized system assistant from file'
|
||||||
|
|
||||||
// Set up mock to return specific content for both files
|
// Set up mock to return specific content for both files
|
||||||
mockFileContent({
|
mockFileContent({
|
||||||
@@ -345,7 +359,7 @@ describe('main.ts', () => {
|
|||||||
const customMaxTokens = 500
|
const customMaxTokens = 500
|
||||||
|
|
||||||
mockInputs({
|
mockInputs({
|
||||||
'prompt': 'Hello, AI!',
|
prompt: 'Hello, AI!',
|
||||||
'system-prompt': 'You are a test assistant.',
|
'system-prompt': 'You are a test assistant.',
|
||||||
'max-tokens': customMaxTokens.toString()
|
'max-tokens': customMaxTokens.toString()
|
||||||
})
|
})
|
||||||
|
|||||||
+30
-31
@@ -33552,6 +33552,32 @@ function getPathFromMapKey(mapKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RESPONSE_FILE = 'modelResponse.txt';
|
const RESPONSE_FILE = 'modelResponse.txt';
|
||||||
|
/**
|
||||||
|
* Helper function to load content from a file or use fallback input
|
||||||
|
* @param filePathInput - Input name for the file path
|
||||||
|
* @param contentInput - Input name for the direct content
|
||||||
|
* @param defaultValue - Default value to use if neither file nor content is provided
|
||||||
|
* @returns The loaded content
|
||||||
|
*/
|
||||||
|
function loadContentFromFileOrInput(filePathInput, contentInput, defaultValue) {
|
||||||
|
const filePath = coreExports.getInput(filePathInput);
|
||||||
|
const contentString = coreExports.getInput(contentInput);
|
||||||
|
if (filePath !== undefined && filePath !== '') {
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
throw new Error(`File for ${filePathInput} was not found: ${filePath}`);
|
||||||
|
}
|
||||||
|
return fs.readFileSync(filePath, 'utf-8');
|
||||||
|
}
|
||||||
|
else if (contentString !== undefined && contentString !== '') {
|
||||||
|
return contentString;
|
||||||
|
}
|
||||||
|
else if (defaultValue !== undefined) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error(`Neither ${filePathInput} nor ${contentInput} was set`);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* The main function for the action.
|
* The main function for the action.
|
||||||
*
|
*
|
||||||
@@ -33559,37 +33585,10 @@ const RESPONSE_FILE = 'modelResponse.txt';
|
|||||||
*/
|
*/
|
||||||
async function run() {
|
async function run() {
|
||||||
try {
|
try {
|
||||||
const promptFile = coreExports.getInput('prompt-file');
|
// Load prompt content - required
|
||||||
const promptString = coreExports.getInput('prompt');
|
const prompt = loadContentFromFileOrInput('prompt-file', 'prompt');
|
||||||
let prompt;
|
// Load system prompt with default value
|
||||||
if (promptFile !== undefined && promptFile !== '') {
|
const systemPrompt = loadContentFromFileOrInput('system-prompt-file', 'system-prompt', 'You are a helpful assistant');
|
||||||
if (!fs.existsSync(promptFile)) {
|
|
||||||
throw new Error(`Prompt file not found: ${promptFile}`);
|
|
||||||
}
|
|
||||||
prompt = fs.readFileSync(promptFile, 'utf-8');
|
|
||||||
}
|
|
||||||
else if (promptString !== undefined && promptString !== '') {
|
|
||||||
prompt = promptString;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error('prompt is not set');
|
|
||||||
}
|
|
||||||
const systemPromptFile = coreExports.getInput('system-prompt-file');
|
|
||||||
const systemPromptString = coreExports.getInput('system-prompt');
|
|
||||||
let systemPrompt;
|
|
||||||
if (systemPromptFile !== undefined && systemPromptFile !== '') {
|
|
||||||
if (!fs.existsSync(systemPromptFile)) {
|
|
||||||
throw new Error(`System prompt file not found: ${systemPromptFile}`);
|
|
||||||
}
|
|
||||||
systemPrompt = fs.readFileSync(systemPromptFile, 'utf-8');
|
|
||||||
}
|
|
||||||
else if (systemPromptString !== undefined && systemPromptString !== '') {
|
|
||||||
systemPrompt = systemPromptString;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Use default system prompt
|
|
||||||
systemPrompt = 'You are a helpful assistant';
|
|
||||||
}
|
|
||||||
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 = coreExports.getInput('token') || process.env['GITHUB_TOKEN'];
|
const token = coreExports.getInput('token') || process.env['GITHUB_TOKEN'];
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -32,7 +32,7 @@
|
|||||||
"local-action": "npx @github/local-action . src/main.ts .env",
|
"local-action": "npx @github/local-action . src/main.ts .env",
|
||||||
"package": "npx rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
|
"package": "npx rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
|
||||||
"package:watch": "npm run package -- --watch",
|
"package:watch": "npm run package -- --watch",
|
||||||
"test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest",
|
"test": "npx cross-env NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest",
|
||||||
"all": "npm run format:write && npm run lint && npm run test && npm run coverage && npm run package"
|
"all": "npm run format:write && npm run lint && npm run test && npm run coverage && npm run package"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
+1
-4
@@ -44,10 +44,7 @@ function loadContentFromFileOrInput(
|
|||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
// Load prompt content - required
|
// Load prompt content - required
|
||||||
const prompt = loadContentFromFileOrInput(
|
const prompt = loadContentFromFileOrInput('prompt-file', 'prompt')
|
||||||
'prompt-file',
|
|
||||||
'prompt'
|
|
||||||
)
|
|
||||||
|
|
||||||
// Load system prompt with default value
|
// Load system prompt with default value
|
||||||
const systemPrompt = loadContentFromFileOrInput(
|
const systemPrompt = loadContentFromFileOrInput(
|
||||||
|
|||||||
Reference in New Issue
Block a user