Skip to content

Commit

Permalink
Merge branch 'feat/contributor-incentives-total-scoring' of https://g…
Browse files Browse the repository at this point in the history
…ithub.com/pavlovcik/ubiquibot into feat/contributor-incentives-total-scoring
  • Loading branch information
0x4007 committed Nov 17, 2023
2 parents 82450db + d00946c commit 1d6da4b
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 61 deletions.
14 changes: 9 additions & 5 deletions src/handlers/comment/handlers/issue/allCommentScoring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ export async function allCommentScoring({
const usersByClass = await sortUsersByClass(context, issue, comments);
const commentsByClass = sortCommentsByClass(usersByClass, comments, view);
const contributionClasses = Object.keys(usersByClass).map((key) => key as ContributorClassesKeys);

return contributionClasses
.filter((className: string) => className.endsWith("Comment"))
.flatMap((contributionStyle) => {
const scoring = commentScoringByContributionClass[contributionStyle];
const commentsOfRole = commentsByClass[contributionStyle as keyof typeof commentsByClass];
const scoring = commentScoringByContributionClass[contributionStyle]();

const selection = usersByClass[contributionStyle as keyof typeof usersByClass];

Expand All @@ -33,12 +33,16 @@ export async function allCommentScoring({
// Ensure selection is always an array
const users = Array.isArray(selection) ? selection : [selection];

return users.flatMap((user) => {
const commentsOfRole = commentsByClass[contributionStyle as keyof typeof commentsByClass];
users.forEach((user) => {
if (!commentsOfRole) {
return [];
}
return perUserCommentScoring(user, commentsOfRole, scoring);
perUserCommentScoring(
user,
commentsOfRole.filter((comment) => comment.user.id === user.id),
scoring
);
});
return scoring;
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,62 @@ import { ContributorClasses } from "./contribution-style-types";
export const commentScoringByContributionClass = {
// TODO: make this configurable

"Issue Assignee Task": new CommentScoring({
contributionClass: "Issue Assignee Task",
formattingMultiplier: 0,
wordValue: 0,
}),
"Issue Assignee Task": () =>
new CommentScoring({
contributionClass: "Issue Assignee Task",
formattingMultiplier: 0,
wordValue: 0,
}),

"Issue Issuer Comment": new CommentScoring({
contributionClass: "Issue Issuer Comment",
formattingMultiplier: 1,
wordValue: 0.2,
}),
"Issue Assignee Comment": new CommentScoring({
contributionClass: "Issue Assignee Comment",
formattingMultiplier: 0,
wordValue: 0,
}),
"Issue Issuer Comment": () =>
new CommentScoring({
contributionClass: "Issue Issuer Comment",
formattingMultiplier: 1,
wordValue: 0.2,
}),
"Issue Assignee Comment": () =>
new CommentScoring({
contributionClass: "Issue Assignee Comment",
formattingMultiplier: 0,
wordValue: 0,
}),

"Issue Collaborator Comment": new CommentScoring({
contributionClass: "Issue Collaborator Comment",
formattingMultiplier: 1,
wordValue: 0.1,
}),
"Issue Contributor Comment": new CommentScoring({
contributionClass: "Issue Contributor Comment",
formattingMultiplier: 0.25,
wordValue: 0.1,
}),
"Review Issuer Comment": new CommentScoring({
contributionClass: "Review Issuer Comment",
formattingMultiplier: 2,
wordValue: 0.2,
}),
"Review Assignee Comment": new CommentScoring({
contributionClass: "Review Assignee Comment",
formattingMultiplier: 1,
wordValue: 0.1,
}),
"Review Collaborator Comment": new CommentScoring({
contributionClass: "Review Collaborator Comment",
formattingMultiplier: 1,
wordValue: 0.1,
}),
"Review Contributor Comment": new CommentScoring({
contributionClass: "Review Contributor Comment",
formattingMultiplier: 0.25,
wordValue: 0.1,
}),
"Issue Collaborator Comment": () =>
new CommentScoring({
contributionClass: "Issue Collaborator Comment",
formattingMultiplier: 1,
wordValue: 0.1,
}),
"Issue Contributor Comment": () =>
new CommentScoring({
contributionClass: "Issue Contributor Comment",
formattingMultiplier: 0.25,
wordValue: 0.1,
}),
"Review Issuer Comment": () =>
new CommentScoring({
contributionClass: "Review Issuer Comment",
formattingMultiplier: 2,
wordValue: 0.2,
}),
"Review Assignee Comment": () =>
new CommentScoring({
contributionClass: "Review Assignee Comment",
formattingMultiplier: 1,
wordValue: 0.1,
}),
"Review Collaborator Comment": () =>
new CommentScoring({
contributionClass: "Review Collaborator Comment",
formattingMultiplier: 1,
wordValue: 0.1,
}),
"Review Contributor Comment": () =>
new CommentScoring({
contributionClass: "Review Contributor Comment",
formattingMultiplier: 0.25,
wordValue: 0.1,
}),
// end comments
// "Issue Issuer Specification": new CommentScoring({
// contributionClass: "Issue Issuer Specification",
Expand Down Expand Up @@ -97,5 +106,5 @@ export const commentScoringByContributionClass = {
// wordValue: 1,
// }),
} as {
[key in keyof ContributorClasses]: CommentScoring;
[key in keyof ContributorClasses]: () => CommentScoring;
};
3 changes: 1 addition & 2 deletions src/handlers/comment/handlers/issue/evaluate-comments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export async function commentsScoring({
const userScoreDetails = formattingWithRelevance.reduce((acc, commentScoring) => {
for (const userId in commentScoring.commentScores) {
const userScore = commentScoring.commentScores[userId];
if (!userScore.details[userId]) continue;

const userScoreDetail: UserScoreDetails = {
score: userScore.totalScoreTotal,
Expand All @@ -44,7 +43,7 @@ export async function commentsScoring({
},
source: {
issue,
user: userScore.details[userId].comment.user,
user: Object.values(userScore.details)[0].comment.user,
},
};

Expand Down
21 changes: 15 additions & 6 deletions src/handlers/comment/handlers/issue/generate-permits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { stringify } from "yaml";
import Runtime from "../../../../bindings/bot-runtime";
import { getPayoutConfigByNetworkId } from "../../../../helpers";
import { getTokenSymbol } from "../../../../helpers/contracts";
import { Context } from "../../../../types";
import { Context, Issue, Payload } from "../../../../types";
import structuredMetadata from "../../../shared/structured-metadata";
import { generatePermit2Signature } from "./generate-permit-2-signature";
import { UserScoreTotals } from "./issue-shared-types";
Expand All @@ -22,18 +22,19 @@ async function generateComment(context: Context, totals: TotalsById) {
const {
keys: { evmPrivateEncrypted },
} = context.config;
const payload = context.event.payload as Payload;
const issue = payload.issue as Issue;
const { rpc, paymentToken } = getPayoutConfigByNetworkId(context.config.payments.evmNetworkId);

const contributionsOverviewTable = generateContributionsOverview(totals);
const conversationIncentivesTable = generateDetailsTable(totals);

const tokenSymbol = await getTokenSymbol(paymentToken, rpc);
const HTMLs = [] as string[];

const permits = [];

for (const userId in totals) {
const userTotals = totals[userId];
const contributionsOverviewTable = generateContributionsOverview({ [userId]: userTotals }, issue);
const conversationIncentivesTable = generateDetailsTable({ [userId]: userTotals });

const tokenAmount = userTotals.total;

Expand Down Expand Up @@ -92,7 +93,7 @@ function generateHtml({
`;
}

function generateContributionsOverview(userScoreDetails: TotalsById) {
function generateContributionsOverview(userScoreDetails: TotalsById, issue: Issue) {
const buffer = [
"<h6>Contributions Overview</h6>",
"<table><thead>",
Expand Down Expand Up @@ -140,7 +141,14 @@ function generateContributionsOverview(userScoreDetails: TotalsById) {
);
}
if (task) {
buffer.push(newRow("Issue", "Task", task?.toString() || "-", task?.toString() || "-"));
buffer.push(
newRow(
"Issue",
"Task",
issue.assignees.length === 0 ? "-" : `${(1 / issue.assignees.length).toFixed(2)}`,
task?.toString() || "-"
)
);
}
}
}
Expand Down Expand Up @@ -216,6 +224,7 @@ function generateDetailsTable(totals: TotalsById) {
}
}
}
if (tableRows === "") return "";
return `<table><tbody><tr><td>Comment</td><td>Formatting</td><td>Relevance</td><td>Reward</td></tr>${tableRows}</tbody></table>`;
}

Expand Down
3 changes: 2 additions & 1 deletion src/handlers/comment/handlers/issue/identify-user-ids.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ async function filterUsers(context: Context, issue: Issue, contributorComments:
const contributors = humanUsersWhoCommented.filter(
(user: User) => !allRoleUsers.some((_user) => _user?.id === user.id)
);
return { issuer, assignees, collaborators, contributors };
const uniqueContributors = Array.from(new Map(contributors.map((user) => [user.id, user])).values());
return { issuer, assignees, collaborators, contributors: uniqueContributors };
}

function returnValues(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export async function specificationScoring({
const scoreDetails = addRelevanceAndFormatScoring(RELEVANT, formatting);
for (const user in scoreDetails) {
const userScore = scoreDetails[user];
if (userScore.contributionClass !== "Issue Issuer Comment") continue;

if (!userScore.commentScores[issue.user.id]) continue;
const userScoreDetail: UserScoreDetails = {
score: userScore.commentScores[issue.user.id].totalScoreTotal,
view: view,
Expand Down

0 comments on commit 1d6da4b

Please sign in to comment.