UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio

188 lines 7.06 kB
// src/lib/action/githubIntegration.ts /** * GitHub API integration for comments, outputs, and job summary * @module action/githubIntegration */ import * as core from "@actions/core"; import * as github from "@actions/github"; /** * Build comment body for PR/issue */ function buildCommentBody(inputs, result) { const commentTag = `<!-- ${inputs.commentTag} -->`; const parts = [commentTag]; parts.push("## 🤖 NeuroLink AI Response\n"); parts.push(result.response); parts.push("\n---"); // Build metadata line const metaParts = []; if (result.model) { metaParts.push(`\`${result.model}\``); } if (result.provider) { metaParts.push(`via ${result.provider}`); } if (result.cost) { metaParts.push(`$${result.cost.toFixed(6)}`); } if (result.usage?.totalTokens) { metaParts.push(`${result.usage.totalTokens} tokens`); } parts.push(`<sub>Generated by [NeuroLink](https://github.com/juspay/neurolink)${metaParts.length ? ` using ${metaParts.join(" | ")}` : ""}</sub>`); return parts.join("\n"); } /** * Find existing comment by tag */ async function findExistingComment(octokit, owner, repo, issueNumber, commentTag) { const { data: comments } = await octokit.rest.issues.listComments({ owner, repo, issue_number: issueNumber, }); const existing = comments.find((c) => c.body?.includes(`<!-- ${commentTag} -->`)); return existing?.id; } /** * Post result as comment on PR or issue */ export async function postResultComment(inputs, result) { if (!inputs.postComment) { return { success: true }; } const token = inputs.githubToken; if (!token) { core.warning("post_comment enabled but no github_token provided"); return { success: false, error: "No GitHub token" }; } const context = github.context; const issueNumber = context.payload.pull_request?.number || context.payload.issue?.number; if (!issueNumber) { core.warning("post_comment enabled but not in PR or issue context"); return { success: false, error: "Not in PR or issue context" }; } const octokit = github.getOctokit(token); const body = buildCommentBody(inputs, result); try { // Check for existing comment if update mode is enabled if (inputs.updateExistingComment) { const existingId = await findExistingComment(octokit, context.repo.owner, context.repo.repo, issueNumber, inputs.commentTag); if (existingId) { const { data } = await octokit.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existingId, body, }); core.info(`Updated existing comment #${existingId}`); return { success: true, commentId: data.id, commentUrl: data.html_url }; } } // Create new comment const { data } = await octokit.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issueNumber, body, }); core.info(`Created comment #${data.id}`); return { success: true, commentId: data.id, commentUrl: data.html_url }; } catch (error) { const message = error instanceof Error ? error.message : String(error); core.warning(`Failed to post comment: ${message}`); return { success: false, error: message }; } } /** * Write job summary */ export async function writeJobSummary(inputs, result) { const summary = core.summary .addHeading("NeuroLink Execution Summary", 2) .addTable([ [ { data: "Metric", header: true }, { data: "Value", header: true }, ], ["Provider", result.provider || "auto"], ["Model", result.model || "auto"], ["Input Tokens", String(result.usage?.promptTokens || "N/A")], ["Output Tokens", String(result.usage?.completionTokens || "N/A")], ["Total Tokens", String(result.usage?.totalTokens || "N/A")], ["Cost", result.cost ? `$${result.cost.toFixed(6)}` : "N/A"], [ "Execution Time", result.executionTime ? `${result.executionTime}ms` : "N/A", ], ]); if (result.evaluation) { summary.addHeading("Quality Evaluation", 3); summary.addRaw(`Score: ${result.evaluation.overallScore}/100`); } summary.addHeading("Response", 3); const truncatedResponse = result.response.length > 5000 ? result.response.substring(0, 5000) + "..." : result.response; summary.addRaw(truncatedResponse); try { await summary.write(); } catch (error) { // Job summary may not be available in all environments (e.g., local testing) core.warning(`Unable to write job summary: ${error instanceof Error ? error.message : String(error)}`); } } /** * Set all action outputs */ export function setActionOutputs(result, commentResult) { core.setOutput("response", result.response); core.setOutput("response_json", JSON.stringify(result.responseJson || {})); if (result.provider) { core.setOutput("provider", result.provider); } if (result.model) { core.setOutput("model", result.model); } if (result.usage?.totalTokens) { core.setOutput("tokens_used", result.usage.totalTokens.toString()); } if (result.usage?.promptTokens) { core.setOutput("prompt_tokens", result.usage.promptTokens.toString()); } if (result.usage?.completionTokens) { core.setOutput("completion_tokens", result.usage.completionTokens.toString()); } if (result.cost) { core.setOutput("cost", result.cost.toString()); } if (result.executionTime) { core.setOutput("execution_time", result.executionTime.toString()); } if (result.evaluation?.overallScore) { core.setOutput("evaluation_score", result.evaluation.overallScore.toString()); } if (commentResult?.commentId) { core.setOutput("comment_id", commentResult.commentId.toString()); } } /** * Get all outputs as typed object (snake_case to match action.yml outputs) */ export function getActionOutputs(result, commentResult) { return { response: result.response, response_json: JSON.stringify(result.responseJson || {}), provider: result.provider, model: result.model, tokens_used: result.usage?.totalTokens?.toString(), prompt_tokens: result.usage?.promptTokens?.toString(), completion_tokens: result.usage?.completionTokens?.toString(), cost: result.cost?.toString(), execution_time: result.executionTime?.toString(), evaluation_score: result.evaluation?.overallScore?.toString(), comment_id: commentResult?.commentId?.toString(), }; } //# sourceMappingURL=githubIntegration.js.map