Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update route and prompt #33

Merged
merged 4 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 83 additions & 71 deletions src/controllers/evaluationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,9 @@ const batchPromises = <T>(array: T[], batchSize: number): T[][] => {

export const createLLMEvaluations = async (
paramsArray: CreateLLMEvaluationParams[]
): Promise<void> => {
): Promise<string[]> => {
const roundCache: Record<string, RoundWithApplications> = {};
const failedProjects: string[] = [];

// Split the paramsArray into batches of 10
const batchedParams = batchPromises(paramsArray, 10);
Expand All @@ -310,86 +311,95 @@ export const createLLMEvaluations = async (
try {
// Process each batch of promises concurrently
const evaluationPromises = batch.map(async params => {
const evaluationQuestions =
params.questions === undefined || params.questions.length === 0
? await evaluationService.getQuestionsByChainAndAlloPoolId(
params.chainId,
params.alloPoolId
)
: params.questions;

if (evaluationQuestions === null || evaluationQuestions.length === 0) {
logger.error(
'createLLMEvaluations:Failed to get evaluation questions'
);
throw new Error('Failed to get evaluation questions');
}

let roundMetadata = params.roundMetadata;
let applicationMetadata = params.applicationMetadata;

// Check if the round is already in cache
if (roundMetadata == null || applicationMetadata == null) {
let round: RoundWithApplications | null;

// If the round is cached, use it
if (roundCache[params.alloPoolId] != null) {
round = roundCache[params.alloPoolId];
logger.debug(
`Using cached round data for roundId: ${params.alloPoolId}`
);
} else {
// Fetch the round and store it in the cache
const [error, fetchedRound] = await catchError(
indexerClient.getRoundWithApplications({
chainId: params.chainId,
roundId: params.alloPoolId,
})
try {
const evaluationQuestions =
params.questions === undefined || params.questions.length === 0
? await evaluationService.getQuestionsByChainAndAlloPoolId(
params.chainId,
params.alloPoolId
)
: params.questions;

if (
evaluationQuestions === null ||
evaluationQuestions.length === 0
) {
logger.error(
'createLLMEvaluations:Failed to get evaluation questions'
);
throw new Error('Failed to get evaluation questions');
}

if (error !== undefined || fetchedRound == null) {
logger.error('Failed to fetch round with applications');
throw new Error('Failed to fetch round with applications');
let roundMetadata = params.roundMetadata;
let applicationMetadata = params.applicationMetadata;

// Check if the round is already in cache
if (roundMetadata == null || applicationMetadata == null) {
let round: RoundWithApplications | null;

// If the round is cached, use it
if (roundCache[params.alloPoolId] != null) {
round = roundCache[params.alloPoolId];
logger.debug(
`Using cached round data for roundId: ${params.alloPoolId}`
);
} else {
// Fetch the round and store it in the cache
const [error, fetchedRound] = await catchError(
indexerClient.getRoundWithApplications({
chainId: params.chainId,
roundId: params.alloPoolId,
})
);

if (error !== undefined || fetchedRound == null) {
logger.error('Failed to fetch round with applications');
throw new Error('Failed to fetch round with applications');
}

round = fetchedRound;
roundCache[params.alloPoolId] = round;
logger.info(
`Fetched and cached round with ID: ${round.id}, which includes ${round.applications.length} applications`
);
}

round = fetchedRound;
roundCache[params.alloPoolId] = round;
logger.info(
`Fetched and cached round with ID: ${round.id}, which includes ${round.applications.length} applications`
const application = round.applications.find(
app => app.id === params.alloApplicationId
);
if (application == null) {
logger.error(
`Application with ID: ${params.alloApplicationId} not found in round`
);
throw new NotFoundError(
`Application with ID: ${params.alloApplicationId} not found in round`
);
}

roundMetadata = round.roundMetadata;
applicationMetadata = application.metadata;
}

const application = round.applications.find(
app => app.id === params.alloApplicationId
const evaluation = await requestEvaluation(
roundMetadata,
applicationMetadata,
evaluationQuestions
);
if (application == null) {
logger.error(
`Application with ID: ${params.alloApplicationId} not found in round`
);
throw new NotFoundError(
`Application with ID: ${params.alloApplicationId} not found in round`
);
}

roundMetadata = round.roundMetadata;
applicationMetadata = application.metadata;
await createEvaluation({
chainId: params.chainId,
alloPoolId: params.alloPoolId,
alloApplicationId: params.alloApplicationId,
cid: params.cid,
evaluator: params.evaluator,
summaryInput: evaluation,
evaluatorType: EVALUATOR_TYPE.LLM_GPT3,
});
} catch (error) {
// If an error occurs, add the project ID to the failedProjects array
failedProjects.push(params.alloApplicationId);
throw error;
}

const evaluation = await requestEvaluation(
roundMetadata,
applicationMetadata,
evaluationQuestions
);

await createEvaluation({
chainId: params.chainId,
alloPoolId: params.alloPoolId,
alloApplicationId: params.alloApplicationId,
cid: params.cid,
evaluator: params.evaluator,
summaryInput: evaluation,
evaluatorType: EVALUATOR_TYPE.LLM_GPT3,
});
});

await Promise.all(evaluationPromises);
Expand All @@ -405,4 +415,6 @@ export const createLLMEvaluations = async (
continue;
}
}

return failedProjects;
};
32 changes: 25 additions & 7 deletions src/controllers/poolController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,34 @@ export const syncPool = async (req: Request, res: Response): Promise<void> => {

// ---- LLM evaluation ----
// Trigger LLM evaluation for the pool if there are applications without evaluations
if (skipEvaluation !== true)
await triggerLLMEvaluationByPool(
let failedProjects: string[] = [];
if (skipEvaluation !== true) {
failedProjects = await triggerLLMEvaluationByPool(
alloPoolId,
chainId,
indexerPoolData,
evaluationQuestions
);
// Log success and respond to the request
logger.info('successfully synced pool', pool);
res.status(200).json({ message: 'pool synced successfully' });
}

// Check if there are any failed projects and respond accordingly
if (failedProjects.length > 0) {
logger.info('Pool synced successfully with some projects failing', {
pool,
failedProjects,
});
res.status(207).json({
success: true,
message: 'Pool synced successfully, with some projects failing.',
failedProjects,
});
} else {
logger.info('Successfully synced pool', pool);
res.status(200).json({
success: true,
message: 'Pool synced successfully.',
});
}
};

const handlePoolEvaluationQuestions = async (
Expand Down Expand Up @@ -171,7 +189,7 @@ const triggerLLMEvaluationByPool = async (
chainId: number,
indexerPoolData: IndexerRoundWithApplications,
evaluationQuestions: PromptEvaluationQuestions
): Promise<void> => {
): Promise<string[]> => {
const applicationsWithoutLLM =
await applicationService.getApplicationsWithoutLLMEvalutionsByAlloPoolId(
alloPoolId,
Expand Down Expand Up @@ -212,5 +230,5 @@ const triggerLLMEvaluationByPool = async (
logger.warn('Some applications were not found in indexerPoolData');
}

await createLLMEvaluations(evaluationParamsArray);
return await createLLMEvaluations(evaluationParamsArray);
};
6 changes: 3 additions & 3 deletions src/ext/openai/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ const sanitizeAndReduceMetadata = (
};

const sanitizeRoundMetadata = (metadata: RoundMetadata): string => {
return sanitizeAndReduceMetadata(metadata, essentialRoundFields, 1000);
return sanitizeAndReduceMetadata(metadata, essentialRoundFields, 50000);
};

const sanitizeApplicationMetadata = (metadata: object): string => {
return sanitizeAndReduceMetadata(metadata, essentialApplicationFields, 3000);
return sanitizeAndReduceMetadata(metadata, essentialApplicationFields, 50000);
};
export const createAiEvaluationPrompt = (
roundMetadata: RoundMetadata,
Expand All @@ -52,7 +52,7 @@ export const createAiEvaluationPrompt = (
): string => {
const sanitizedRoundMetadata = sanitizeRoundMetadata(roundMetadata);
const sanitizedApplicationMetadata = sanitizeApplicationMetadata(
applicationMetadata.application.project
applicationMetadata.application
);

const questionsString = applicationQuestions
Expand Down
36 changes: 24 additions & 12 deletions src/routes/poolRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,43 @@ const router = Router();
* alloPoolId:
* type: string
* description: The ID of the pool to create
* example: "609" # Example of poolId
* example: "609"
* chainId:
* type: number
* description: The chain ID associated with the pool
* example: 42161 # Example of chainId (Arbitrum)
* example: 42161
* skipEvaluation:
* type: boolean
* description: Skip evaluation of the pool
* example: true
* type: boolean
* description: Skip evaluation of the pool
* example: true
* required:
* - alloPoolId
* - chainId
* responses:
* 201:
* description: Pool created successfully
* description: Pool synced successfully
* 207:
* description: Pool synced successfully, with some projects failing
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* example: true
* message:
* type: string
* example: Pool synced successfully, with some projects failing.
* failedProjects:
* type: array
* items:
* type: string
* example: "0xprojectId1"
* 400:
* description: Invalid poolId or chainId format
* 500:
* description: Internal server error
* examples:
* application/json:
* - value:
* alloPoolId: "609"
* chainId: "42161"
* skipEvaluation: true
*/
router.post('/', syncPool);

Expand Down
Loading