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

SDK and command interface #46

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
2 changes: 1 addition & 1 deletion .github/knip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const config: KnipConfig = {
ignore: ["src/types/config.ts", "**/__mocks__/**", "**/__fixtures__/**", "src/types/database.ts"],
ignoreExportsUsedInFile: true,
// eslint can also be safely ignored as per the docs: https://knip.dev/guides/handling-issues#eslint--jest
ignoreDependencies: ["eslint-config-prettier", "eslint-plugin-prettier"],
ignoreDependencies: ["eslint-config-prettier", "eslint-plugin-prettier", "ts-node", "hono"],
eslint: true,
};

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/compute.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ on:
description: "Ref"
signature:
description: "Signature tp identify the Kernel"
command:
description: "Command"

jobs:
compute:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,4 @@ jobs:
echo "No changes to commit"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
10 changes: 0 additions & 10 deletions jest.config.json

This file was deleted.

24 changes: 24 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { JestConfigWithTsJest } from "ts-jest";

module.exports = {
preset: "ts-jest",
testEnvironment: "node",
roots: ["./tests"],
coveragePathIgnorePatterns: ["node_modules", "mocks"],
collectCoverage: true,
coverageReporters: ["json", "lcov", "text", "clover", "json-summary"],
reporters: ["default", "jest-junit", "jest-md-dashboard"],
coverageDirectory: "coverage",
extensionsToTreatAsEsm: [".ts"],
moduleNameMapper: {
"^(\\.{1,2}/.*)\\.js$": "$1",
},
transform: {
"^.+\\.tsx?$": [
"ts-jest",
{
useESM: true,
},
],
},
} as JestConfigWithTsJest;
8 changes: 2 additions & 6 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@
"type": "number"
}
},
"required": [
"matchThreshold",
"warningThreshold",
"jobMatchingThreshold"
]
"required": ["matchThreshold", "warningThreshold", "jobMatchingThreshold"]
}
}
}
19 changes: 8 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
"knip": "knip --config .github/knip.ts",
"knip-ci": "knip --no-exit-code --reporter json --config .github/knip.ts",
"prepare": "husky install",
"test": "jest --setupFiles dotenv/config --coverage",
"worker": "wrangler dev --env dev --port 5000",
"test": "cross-env NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --setupFiles dotenv/config --coverage",
"worker": "wrangler dev --env dev --port 4004",
"supabase:generate:local": "supabase gen types typescript --local > src/types/database.ts",
"supabase:generate:remote": "cross-env-shell \"supabase gen types typescript --project-id $SUPABASE_PROJECT_ID --schema public > src/types/database.ts\""
},
Expand All @@ -29,18 +29,14 @@
"open-source"
],
"dependencies": {
"@actions/core": "1.10.1",
"@actions/github": "6.0.0",
"@octokit/rest": "20.1.1",
"@octokit/webhooks": "13.2.7",
"@sinclair/typebox": "0.32.33",
"@sinclair/typebox": "0.34.3",
"@supabase/supabase-js": "^2.45.2",
"@types/markdown-it": "^14.1.2",
"@ubiquity-os/plugin-sdk": "^1.1.0",
"@ubiquity-os/ubiquity-os-logger": "^1.3.2",
"dotenv": "16.4.5",
"markdown-it": "^14.1.0",
"markdown-it-plain-text": "^0.3.0",
"typebox-validators": "0.3.5",
"voyageai": "^0.0.1-5"
},
"devDependencies": {
Expand Down Expand Up @@ -69,12 +65,13 @@
"lint-staged": "15.2.7",
"npm-run-all": "4.1.5",
"prettier": "3.3.2",
"supabase": "1.200.3",
"supabase": "1.219.2",
"ts-jest": "29.1.5",
"ts-node": "^10.9.2",
"tsx": "4.15.6",
"typescript": "5.6.2",
"typescript-eslint": "7.13.1",
"wrangler": "3.78.12"
"typescript-eslint": "8.15.0",
"wrangler": "3.89.0"
},
"lint-staged": {
"*.ts": [
Expand Down
10 changes: 5 additions & 5 deletions src/adapters/supabase/helpers/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class Comment extends SuperSupabase {
//First Check if the comment already exists
const { data, error } = await this.supabase.from("issue_comments").select("*").eq("id", commentNodeId);
if (error) {
this.context.logger.error("Error creating comment", error);
this.context.logger.error("Error creating comment", { err: error });
return;
}
if (data && data.length > 0) {
Expand All @@ -47,7 +47,7 @@ export class Comment extends SuperSupabase {
.from("issue_comments")
.insert([{ id: commentNodeId, markdown, plaintext, author_id: authorId, payload, embedding: embedding, issue_id: issueId }]);
if (error) {
this.context.logger.error("Error creating comment", error);
this.context.logger.error("Error creating comment", { err: error });
return;
}
}
Expand Down Expand Up @@ -80,23 +80,23 @@ export class Comment extends SuperSupabase {
.update({ markdown, plaintext, embedding: embedding, payload, modified_at: new Date() })
.eq("id", commentNodeId);
if (error) {
this.context.logger.error("Error updating comment", error);
this.context.logger.error("Error updating comment", { err: error });
}
}
}

async getComment(commentNodeId: string): Promise<CommentType[] | null> {
const { data, error } = await this.supabase.from("issue_comments").select("*").eq("id", commentNodeId);
if (error) {
this.context.logger.error("Error getting comment", error);
this.context.logger.error("Error getting comment", { err: error });
}
return data;
}

async deleteComment(commentNodeId: string) {
const { error } = await this.supabase.from("issue_comments").delete().eq("id", commentNodeId);
if (error) {
this.context.logger.error("Error deleting comment", error);
this.context.logger.error("Error deleting comment", { err: error });
}
}
}
14 changes: 7 additions & 7 deletions src/adapters/supabase/helpers/issues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class Issues extends SuperSupabase {
//First Check if the issue already exists
const { data, error } = await this.supabase.from("issues").select("*").eq("id", issueNodeId);
if (error) {
this.context.logger.error("Error creating issue", error);
this.context.logger.error("Error creating issue", { err: error });
return;
}
if (data && data.length > 0) {
Expand All @@ -45,7 +45,7 @@ export class Issues extends SuperSupabase {
}
const { error } = await this.supabase.from("issues").insert([{ id: issueNodeId, payload, markdown, plaintext, author_id: authorId, embedding }]);
if (error) {
this.context.logger.error("Error creating issue", error);
this.context.logger.error("Error creating issue", { err: error });
return;
}
}
Expand All @@ -68,15 +68,15 @@ export class Issues extends SuperSupabase {
const { error } = await this.supabase.from("issues").update({ markdown, plaintext, embedding, payload, modified_at: new Date() }).eq("id", issueNodeId);

if (error) {
this.context.logger.error("Error updating comment", error);
this.context.logger.error("Error updating comment", { err: error });
}
}
}

async deleteIssue(issueNodeId: string) {
const { error } = await this.supabase.from("issues").delete().eq("id", issueNodeId);
if (error) {
this.context.logger.error("Error deleting comment", error);
this.context.logger.error("Error deleting comment", { err: error });
}
}

Expand All @@ -87,7 +87,7 @@ export class Issues extends SuperSupabase {
.eq("id", issueNodeId)
.returns<IssueType[]>();
if (error) {
this.context.logger.error("Error getting issue", error);
this.context.logger.error("Error getting issue", { err: error });
return null;
}
return data;
Expand All @@ -102,7 +102,7 @@ export class Issues extends SuperSupabase {
top_k: 5,
});
if (error) {
this.context.logger.error("Error finding similar issues", error);
this.context.logger.error("Error finding similar issues", { err: error });
return [];
}
return data;
Expand All @@ -111,7 +111,7 @@ export class Issues extends SuperSupabase {
async updatePayload(issueNodeId: string, payload: Record<string, unknown>) {
const { error } = await this.supabase.from("issues").update({ payload }).eq("id", issueNodeId);
if (error) {
this.context.logger.error("Error updating issue payload", error);
this.context.logger.error("Error updating issue payload", { err: error });
}
}
}
5 changes: 2 additions & 3 deletions src/handlers/add-comments.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Context } from "../types";
import { CommentPayload } from "../types/payload";

export async function addComments(context: Context) {
export async function addComments(context: Context<"issue_comment.created">) {
const {
logger,
adapters: { supabase },
payload,
} = context;
const { payload } = context as { payload: CommentPayload };
const markdown = payload.comment.body;
const authorId = payload.comment.user?.id || -1;
const nodeId = payload.comment.node_id;
Expand Down
5 changes: 2 additions & 3 deletions src/handlers/add-issue.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Context } from "../types";
import { IssuePayload } from "../types/payload";
import { removeFootnotes } from "./issue-deduplication";

export async function addIssue(context: Context) {
export async function addIssue(context: Context<"issues.opened">) {
const {
logger,
adapters: { supabase },
payload,
} = context;
const { payload } = context as { payload: IssuePayload };
const markdown = payload.issue.body + " " + payload.issue.title || null;
const authorId = payload.issue.user?.id || -1;
const nodeId = payload.issue.node_id;
Expand Down
5 changes: 2 additions & 3 deletions src/handlers/delete-comments.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Context } from "../types";
import { CommentPayload } from "../types/payload";

export async function deleteComment(context: Context) {
export async function deleteComment(context: Context<"issue_comment.deleted">) {
const {
logger,
adapters: { supabase },
payload,
} = context;
const { payload } = context as { payload: CommentPayload };
const nodeId = payload.comment.node_id;

try {
Expand Down
5 changes: 2 additions & 3 deletions src/handlers/delete-issue.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Context } from "../types";
import { IssuePayload } from "../types/payload";

export async function deleteIssues(context: Context) {
export async function deleteIssues(context: Context<"issues.deleted">) {
const {
logger,
adapters: { supabase },
payload,
} = context;
const { payload } = context as { payload: IssuePayload };
const nodeId = payload.issue.node_id;

try {
Expand Down
21 changes: 13 additions & 8 deletions src/handlers/issue-deduplication.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { IssueSimilaritySearchResult } from "../adapters/supabase/helpers/issues";
import { Context } from "../types";
import { IssuePayload } from "../types/payload";

export interface IssueGraphqlResponse {
node: {
Expand All @@ -25,13 +24,13 @@ export interface IssueGraphqlResponse {
* @param context The context object
* @returns True if a similar issue is found, false otherwise
**/
export async function issueChecker(context: Context): Promise<boolean> {
export async function issueChecker(context: Context<"issues.opened" | "issues.edited">): Promise<boolean> {
const {
logger,
adapters: { supabase },
octokit,
payload,
} = context;
const { payload } = context as { payload: IssuePayload };
const issue = payload.issue;
let issueBody = issue.body;
if (!issueBody) {
Expand All @@ -48,7 +47,7 @@ export async function issueChecker(context: Context): Promise<boolean> {
//To the issue body, add a footnote with the link to the similar issue
const updatedBody = await handleMatchIssuesComment(context, payload, issueBody, processedIssues);
issueBody = updatedBody || issueBody;
await octokit.issues.update({
await octokit.rest.issues.update({
owner: payload.repository.owner.login,
repo: payload.repository.name,
issue_number: issue.number,
Expand All @@ -67,7 +66,7 @@ export async function issueChecker(context: Context): Promise<boolean> {
//Use the IssueBody (Without footnotes) to update the issue when no similar issues are found
//Only if the issue has "possible duplicate" footnotes, update the issue
if (checkIfDuplicateFootNoteExists(issue.body || "")) {
await octokit.issues.update({
await octokit.rest.issues.update({
owner: payload.repository.owner.login,
repo: payload.repository.name,
issue_number: issue.number,
Expand Down Expand Up @@ -130,7 +129,13 @@ function findMostSimilarSentence(issueContent: string, similarIssueContent: stri
return { sentence: mostSimilarSentence, similarity: maxSimilarity, index: mostSimilarIndex };
}

async function handleSimilarIssuesComment(context: Context, payload: IssuePayload, issueBody: string, issueNumber: number, issueList: IssueGraphqlResponse[]) {
async function handleSimilarIssuesComment(
context: Context,
payload: Context<"issues.opened" | "issues.edited">["payload"],
issueBody: string,
issueNumber: number,
issueList: IssueGraphqlResponse[]
) {
const relevantIssues = issueList.filter((issue) =>
matchRepoOrgToSimilarIssueRepoOrg(payload.repository.owner.login, issue.node.repository.owner.login, payload.repository.name, issue.node.repository.name)
);
Expand Down Expand Up @@ -170,7 +175,7 @@ async function handleSimilarIssuesComment(context: Context, payload: IssuePayloa
updatedBody += "\n\n" + footnotes.join("");
}
// Update the issue with the modified body
await context.octokit.issues.update({
await context.octokit.rest.issues.update({
owner: payload.repository.owner.login,
repo: payload.repository.name,
issue_number: issueNumber,
Expand All @@ -181,7 +186,7 @@ async function handleSimilarIssuesComment(context: Context, payload: IssuePayloa
//When similarity is greater than match threshold, Add Caution mentioning the issues to which its is very much similar
async function handleMatchIssuesComment(
context: Context,
payload: IssuePayload,
payload: Context<"issues.opened" | "issues.edited">["payload"],
issueBody: string,
issueList: IssueGraphqlResponse[]
): Promise<string | undefined> {
Expand Down
Loading