@ubiquity-os/plugin-sdk 3.6.3 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/configuration.d.mts +16 -11
- package/dist/configuration.d.ts +16 -11
- package/dist/configuration.js +219 -36
- package/dist/configuration.mjs +219 -36
- package/dist/{context-BbEmsEct.d.ts → context-BE4WjJZf.d.ts} +1 -0
- package/dist/{context-sqbr2o6i.d.mts → context-Ckj1HMjz.d.mts} +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +209 -124
- package/dist/index.mjs +209 -124
- package/dist/llm.d.mts +1 -1
- package/dist/llm.d.ts +1 -1
- package/dist/llm.js +46 -11
- package/dist/llm.mjs +46 -11
- package/dist/signature.js +2 -2
- package/dist/signature.mjs +2 -2
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// src/actions.ts
|
|
2
2
|
import * as core from "@actions/core";
|
|
3
|
-
import * as github2 from "@actions/github";
|
|
4
3
|
import { Value as Value3 } from "@sinclair/typebox/value";
|
|
5
4
|
|
|
6
5
|
// ../../node_modules/@ubiquity-os/ubiquity-os-logger/dist/index.js
|
|
@@ -338,8 +337,56 @@ var Logs = class _Logs {
|
|
|
338
337
|
// src/actions.ts
|
|
339
338
|
import { config } from "dotenv";
|
|
340
339
|
|
|
341
|
-
// src/
|
|
342
|
-
|
|
340
|
+
// src/error.ts
|
|
341
|
+
function getErrorStatus(err) {
|
|
342
|
+
if (!err || typeof err !== "object") return null;
|
|
343
|
+
const candidate = err;
|
|
344
|
+
const directStatus = candidate.status ?? candidate.response?.status;
|
|
345
|
+
if (typeof directStatus === "number" && Number.isFinite(directStatus)) return directStatus;
|
|
346
|
+
if (typeof directStatus === "string" && directStatus.trim()) {
|
|
347
|
+
const parsed = Number.parseInt(directStatus, 10);
|
|
348
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
349
|
+
}
|
|
350
|
+
if (err instanceof Error) {
|
|
351
|
+
const match = /LLM API error:\s*(\d{3})/i.exec(err.message);
|
|
352
|
+
if (match) {
|
|
353
|
+
const parsed = Number.parseInt(match[1], 10);
|
|
354
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
function logByStatus(context, message, metadata) {
|
|
360
|
+
const status = getErrorStatus(metadata.err);
|
|
361
|
+
const payload = { ...metadata, ...status ? { status } : {} };
|
|
362
|
+
if (status && status >= 500) return context.logger.error(message, payload);
|
|
363
|
+
if (status && status >= 400) return context.logger.warn(message, payload);
|
|
364
|
+
if (status && status >= 300) return context.logger.debug(message, payload);
|
|
365
|
+
if (status && status >= 200) return context.logger.ok(message, payload);
|
|
366
|
+
if (status && status >= 100) return context.logger.info(message, payload);
|
|
367
|
+
return context.logger.error(message, payload);
|
|
368
|
+
}
|
|
369
|
+
function transformError(context, error) {
|
|
370
|
+
if (error instanceof LogReturn) {
|
|
371
|
+
return error;
|
|
372
|
+
}
|
|
373
|
+
if (error instanceof AggregateError) {
|
|
374
|
+
const message = error.errors.map((err) => {
|
|
375
|
+
if (err instanceof LogReturn) {
|
|
376
|
+
return err.logMessage.raw;
|
|
377
|
+
}
|
|
378
|
+
if (err instanceof Error) {
|
|
379
|
+
return err.message;
|
|
380
|
+
}
|
|
381
|
+
return String(err);
|
|
382
|
+
}).join("\n\n");
|
|
383
|
+
return logByStatus(context, message, { err: error });
|
|
384
|
+
}
|
|
385
|
+
if (error instanceof Error) {
|
|
386
|
+
return logByStatus(context, error.message, { err: error });
|
|
387
|
+
}
|
|
388
|
+
return logByStatus(context, String(error), { err: error });
|
|
389
|
+
}
|
|
343
390
|
|
|
344
391
|
// ../../node_modules/hono/dist/helper/adapter/index.js
|
|
345
392
|
var env = (c, runtime) => {
|
|
@@ -391,6 +438,21 @@ var checkUserAgentEquals = (platform) => {
|
|
|
391
438
|
return userAgent.startsWith(platform);
|
|
392
439
|
};
|
|
393
440
|
|
|
441
|
+
// src/helpers/github-context.ts
|
|
442
|
+
import * as github from "@actions/github";
|
|
443
|
+
function getGithubContext() {
|
|
444
|
+
const override = globalThis.__UOS_GITHUB_CONTEXT__;
|
|
445
|
+
if (override) {
|
|
446
|
+
return override;
|
|
447
|
+
}
|
|
448
|
+
const module = github;
|
|
449
|
+
const context = module.context ?? module.default?.context;
|
|
450
|
+
if (!context) {
|
|
451
|
+
throw new Error("GitHub context is unavailable.");
|
|
452
|
+
}
|
|
453
|
+
return context;
|
|
454
|
+
}
|
|
455
|
+
|
|
394
456
|
// src/helpers/runtime-info.ts
|
|
395
457
|
var PluginRuntimeInfo = class _PluginRuntimeInfo {
|
|
396
458
|
static _instance = null;
|
|
@@ -439,10 +501,11 @@ var CfRuntimeInfo = class extends PluginRuntimeInfo {
|
|
|
439
501
|
};
|
|
440
502
|
var NodeRuntimeInfo = class extends PluginRuntimeInfo {
|
|
441
503
|
get version() {
|
|
442
|
-
return
|
|
504
|
+
return getGithubContext().sha;
|
|
443
505
|
}
|
|
444
506
|
get runUrl() {
|
|
445
|
-
|
|
507
|
+
const context = getGithubContext();
|
|
508
|
+
return context.payload.repository ? `${context.payload.repository?.html_url}/actions/runs/${context.runId}` : "http://localhost";
|
|
446
509
|
}
|
|
447
510
|
};
|
|
448
511
|
var DenoRuntimeInfo = class extends PluginRuntimeInfo {
|
|
@@ -532,14 +595,23 @@ function getPluginOptions(options) {
|
|
|
532
595
|
}
|
|
533
596
|
|
|
534
597
|
// src/comment.ts
|
|
598
|
+
function logByStatus2(logger, message, status, metadata) {
|
|
599
|
+
const payload = { ...metadata, ...status ? { status } : {} };
|
|
600
|
+
if (status && status >= 500) return logger.error(message, payload);
|
|
601
|
+
if (status && status >= 400) return logger.warn(message, payload);
|
|
602
|
+
if (status && status >= 300) return logger.debug(message, payload);
|
|
603
|
+
if (status && status >= 200) return logger.ok(message, payload);
|
|
604
|
+
if (status && status >= 100) return logger.info(message, payload);
|
|
605
|
+
return logger.error(message, payload);
|
|
606
|
+
}
|
|
535
607
|
var CommentHandler = class _CommentHandler {
|
|
536
608
|
static HEADER_NAME = "UbiquityOS";
|
|
537
609
|
_lastCommentId = { reviewCommentId: null, issueCommentId: null };
|
|
538
|
-
async _updateIssueComment(
|
|
610
|
+
async _updateIssueComment(context, params) {
|
|
539
611
|
if (!this._lastCommentId.issueCommentId) {
|
|
540
|
-
throw
|
|
612
|
+
throw context.logger.error("issueCommentId is missing");
|
|
541
613
|
}
|
|
542
|
-
const commentData = await
|
|
614
|
+
const commentData = await context.octokit.rest.issues.updateComment({
|
|
543
615
|
owner: params.owner,
|
|
544
616
|
repo: params.repo,
|
|
545
617
|
comment_id: this._lastCommentId.issueCommentId,
|
|
@@ -547,11 +619,11 @@ var CommentHandler = class _CommentHandler {
|
|
|
547
619
|
});
|
|
548
620
|
return { ...commentData.data, issueNumber: params.issueNumber };
|
|
549
621
|
}
|
|
550
|
-
async _updateReviewComment(
|
|
622
|
+
async _updateReviewComment(context, params) {
|
|
551
623
|
if (!this._lastCommentId.reviewCommentId) {
|
|
552
|
-
throw
|
|
624
|
+
throw context.logger.error("reviewCommentId is missing");
|
|
553
625
|
}
|
|
554
|
-
const commentData = await
|
|
626
|
+
const commentData = await context.octokit.rest.pulls.updateReviewComment({
|
|
555
627
|
owner: params.owner,
|
|
556
628
|
repo: params.repo,
|
|
557
629
|
comment_id: this._lastCommentId.reviewCommentId,
|
|
@@ -559,9 +631,9 @@ var CommentHandler = class _CommentHandler {
|
|
|
559
631
|
});
|
|
560
632
|
return { ...commentData.data, issueNumber: params.issueNumber };
|
|
561
633
|
}
|
|
562
|
-
async _createNewComment(
|
|
634
|
+
async _createNewComment(context, params) {
|
|
563
635
|
if (params.commentId) {
|
|
564
|
-
const commentData2 = await
|
|
636
|
+
const commentData2 = await context.octokit.rest.pulls.createReplyForReviewComment({
|
|
565
637
|
owner: params.owner,
|
|
566
638
|
repo: params.repo,
|
|
567
639
|
pull_number: params.issueNumber,
|
|
@@ -571,7 +643,7 @@ var CommentHandler = class _CommentHandler {
|
|
|
571
643
|
this._lastCommentId.reviewCommentId = commentData2.data.id;
|
|
572
644
|
return { ...commentData2.data, issueNumber: params.issueNumber };
|
|
573
645
|
}
|
|
574
|
-
const commentData = await
|
|
646
|
+
const commentData = await context.octokit.rest.issues.createComment({
|
|
575
647
|
owner: params.owner,
|
|
576
648
|
repo: params.repo,
|
|
577
649
|
issue_number: params.issueNumber,
|
|
@@ -580,54 +652,58 @@ var CommentHandler = class _CommentHandler {
|
|
|
580
652
|
this._lastCommentId.issueCommentId = commentData.data.id;
|
|
581
653
|
return { ...commentData.data, issueNumber: params.issueNumber };
|
|
582
654
|
}
|
|
583
|
-
_getIssueNumber(
|
|
584
|
-
if ("issue" in
|
|
585
|
-
if ("pull_request" in
|
|
586
|
-
if ("discussion" in
|
|
655
|
+
_getIssueNumber(context) {
|
|
656
|
+
if ("issue" in context.payload) return context.payload.issue.number;
|
|
657
|
+
if ("pull_request" in context.payload) return context.payload.pull_request.number;
|
|
658
|
+
if ("discussion" in context.payload) return context.payload.discussion.number;
|
|
587
659
|
return void 0;
|
|
588
660
|
}
|
|
589
|
-
_getCommentId(
|
|
590
|
-
return "pull_request" in
|
|
661
|
+
_getCommentId(context) {
|
|
662
|
+
return "pull_request" in context.payload && "comment" in context.payload ? context.payload.comment.id : void 0;
|
|
591
663
|
}
|
|
592
|
-
_extractIssueContext(
|
|
593
|
-
if (!("repository" in
|
|
664
|
+
_extractIssueContext(context) {
|
|
665
|
+
if (!("repository" in context.payload) || !context.payload.repository?.owner?.login) {
|
|
594
666
|
return null;
|
|
595
667
|
}
|
|
596
|
-
const issueNumber = this._getIssueNumber(
|
|
668
|
+
const issueNumber = this._getIssueNumber(context);
|
|
597
669
|
if (!issueNumber) return null;
|
|
598
670
|
return {
|
|
599
671
|
issueNumber,
|
|
600
|
-
commentId: this._getCommentId(
|
|
601
|
-
owner:
|
|
602
|
-
repo:
|
|
672
|
+
commentId: this._getCommentId(context),
|
|
673
|
+
owner: context.payload.repository.owner.login,
|
|
674
|
+
repo: context.payload.repository.name
|
|
603
675
|
};
|
|
604
676
|
}
|
|
605
|
-
_processMessage(
|
|
677
|
+
_processMessage(context, message) {
|
|
606
678
|
if (message instanceof Error) {
|
|
607
679
|
const metadata2 = {
|
|
608
680
|
message: message.message,
|
|
609
681
|
name: message.name,
|
|
610
682
|
stack: message.stack
|
|
611
683
|
};
|
|
612
|
-
|
|
684
|
+
const status = getErrorStatus(message);
|
|
685
|
+
const logReturn = logByStatus2(context.logger, message.message, status, metadata2);
|
|
686
|
+
return { metadata: { ...metadata2, ...status ? { status } : {} }, logMessage: logReturn.logMessage };
|
|
613
687
|
}
|
|
688
|
+
const stackLine = message.metadata?.error?.stack?.split("\n")[2];
|
|
689
|
+
const callerMatch = stackLine ? /at (\S+)/.exec(stackLine) : null;
|
|
614
690
|
const metadata = message.metadata ? {
|
|
615
691
|
...message.metadata,
|
|
616
692
|
message: message.metadata.message,
|
|
617
693
|
stack: message.metadata.stack || message.metadata.error?.stack,
|
|
618
|
-
caller: message.metadata.caller ||
|
|
694
|
+
caller: message.metadata.caller || callerMatch?.[1]
|
|
619
695
|
} : { ...message };
|
|
620
696
|
return { metadata, logMessage: message.logMessage };
|
|
621
697
|
}
|
|
622
|
-
_getInstigatorName(
|
|
623
|
-
if ("installation" in
|
|
624
|
-
return
|
|
698
|
+
_getInstigatorName(context) {
|
|
699
|
+
if ("installation" in context.payload && context.payload.installation && "account" in context.payload.installation && context.payload.installation?.account?.name) {
|
|
700
|
+
return context.payload.installation?.account?.name;
|
|
625
701
|
}
|
|
626
|
-
return
|
|
702
|
+
return context.payload.sender?.login || _CommentHandler.HEADER_NAME;
|
|
627
703
|
}
|
|
628
|
-
_createMetadataContent(
|
|
704
|
+
_createMetadataContent(context, metadata) {
|
|
629
705
|
const jsonPretty = sanitizeMetadata(metadata);
|
|
630
|
-
const instigatorName = this._getInstigatorName(
|
|
706
|
+
const instigatorName = this._getInstigatorName(context);
|
|
631
707
|
const runUrl = PluginRuntimeInfo.getInstance().runUrl;
|
|
632
708
|
const version = PluginRuntimeInfo.getInstance().version;
|
|
633
709
|
const callingFnName = metadata.caller || "anonymous";
|
|
@@ -644,63 +720,39 @@ var CommentHandler = class _CommentHandler {
|
|
|
644
720
|
/*
|
|
645
721
|
* Creates the body for the comment, embeds the metadata and the header hidden in the body as well.
|
|
646
722
|
*/
|
|
647
|
-
createCommentBody(
|
|
648
|
-
return this._createCommentBody(
|
|
723
|
+
createCommentBody(context, message, options) {
|
|
724
|
+
return this._createCommentBody(context, message, options);
|
|
649
725
|
}
|
|
650
|
-
_createCommentBody(
|
|
651
|
-
const { metadata, logMessage } = this._processMessage(
|
|
652
|
-
const { header, jsonPretty } = this._createMetadataContent(
|
|
726
|
+
_createCommentBody(context, message, options) {
|
|
727
|
+
const { metadata, logMessage } = this._processMessage(context, message);
|
|
728
|
+
const { header, jsonPretty } = this._createMetadataContent(context, metadata);
|
|
653
729
|
const metadataContent = this._formatMetadataContent(logMessage, header, jsonPretty);
|
|
654
730
|
return `${options?.raw ? logMessage?.raw : logMessage?.diff}
|
|
655
731
|
|
|
656
732
|
${metadataContent}
|
|
657
733
|
`;
|
|
658
734
|
}
|
|
659
|
-
async postComment(
|
|
660
|
-
const issueContext = this._extractIssueContext(
|
|
735
|
+
async postComment(context, message, options = { updateComment: true, raw: false }) {
|
|
736
|
+
const issueContext = this._extractIssueContext(context);
|
|
661
737
|
if (!issueContext) {
|
|
662
|
-
|
|
738
|
+
context.logger.warn("Cannot post comment: missing issue context in payload");
|
|
663
739
|
return null;
|
|
664
740
|
}
|
|
665
|
-
const body = this._createCommentBody(
|
|
741
|
+
const body = this._createCommentBody(context, message, options);
|
|
666
742
|
const { issueNumber, commentId, owner, repo } = issueContext;
|
|
667
743
|
const params = { owner, repo, body, issueNumber };
|
|
668
744
|
if (options.updateComment) {
|
|
669
|
-
if (this._lastCommentId.issueCommentId && !("pull_request" in
|
|
670
|
-
return this._updateIssueComment(
|
|
745
|
+
if (this._lastCommentId.issueCommentId && !("pull_request" in context.payload && "comment" in context.payload)) {
|
|
746
|
+
return this._updateIssueComment(context, params);
|
|
671
747
|
}
|
|
672
|
-
if (this._lastCommentId.reviewCommentId && "pull_request" in
|
|
673
|
-
return this._updateReviewComment(
|
|
748
|
+
if (this._lastCommentId.reviewCommentId && "pull_request" in context.payload && "comment" in context.payload) {
|
|
749
|
+
return this._updateReviewComment(context, params);
|
|
674
750
|
}
|
|
675
751
|
}
|
|
676
|
-
return this._createNewComment(
|
|
752
|
+
return this._createNewComment(context, { ...params, commentId });
|
|
677
753
|
}
|
|
678
754
|
};
|
|
679
755
|
|
|
680
|
-
// src/error.ts
|
|
681
|
-
function transformError(context2, error) {
|
|
682
|
-
let loggerError;
|
|
683
|
-
if (error instanceof AggregateError) {
|
|
684
|
-
loggerError = context2.logger.error(
|
|
685
|
-
error.errors.map((err) => {
|
|
686
|
-
if (err instanceof LogReturn) {
|
|
687
|
-
return err.logMessage.raw;
|
|
688
|
-
} else if (err instanceof Error) {
|
|
689
|
-
return err.message;
|
|
690
|
-
} else {
|
|
691
|
-
return err;
|
|
692
|
-
}
|
|
693
|
-
}).join("\n\n"),
|
|
694
|
-
{ error }
|
|
695
|
-
);
|
|
696
|
-
} else if (error instanceof Error || error instanceof LogReturn) {
|
|
697
|
-
loggerError = error;
|
|
698
|
-
} else {
|
|
699
|
-
loggerError = context2.logger.error(String(error));
|
|
700
|
-
}
|
|
701
|
-
return loggerError;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
756
|
// src/helpers/command.ts
|
|
705
757
|
import { Value } from "@sinclair/typebox/value";
|
|
706
758
|
function getCommand(inputs, pluginOptions) {
|
|
@@ -933,7 +985,7 @@ async function verifySignature(publicKeyPem, inputs, signature) {
|
|
|
933
985
|
ref: inputs.ref,
|
|
934
986
|
command: inputs.command
|
|
935
987
|
};
|
|
936
|
-
const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").
|
|
988
|
+
const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").replace(/\s+/g, "");
|
|
937
989
|
const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
|
|
938
990
|
const publicKey = await crypto.subtle.importKey(
|
|
939
991
|
"spki",
|
|
@@ -986,16 +1038,12 @@ var inputSchema = T2.Object({
|
|
|
986
1038
|
|
|
987
1039
|
// src/actions.ts
|
|
988
1040
|
config();
|
|
989
|
-
async function handleError(
|
|
1041
|
+
async function handleError(context, pluginOptions, error) {
|
|
990
1042
|
console.error(error);
|
|
991
|
-
const loggerError = transformError(
|
|
992
|
-
|
|
993
|
-
core.setFailed(loggerError.logMessage.diff);
|
|
994
|
-
} else if (loggerError instanceof Error) {
|
|
995
|
-
core.setFailed(loggerError);
|
|
996
|
-
}
|
|
1043
|
+
const loggerError = transformError(context, error);
|
|
1044
|
+
core.setFailed(loggerError.logMessage.diff);
|
|
997
1045
|
if (pluginOptions.postCommentOnError && loggerError) {
|
|
998
|
-
await
|
|
1046
|
+
await context.commentHandler.postComment(context, loggerError);
|
|
999
1047
|
}
|
|
1000
1048
|
}
|
|
1001
1049
|
async function createActionsPlugin(handler, options) {
|
|
@@ -1005,7 +1053,8 @@ async function createActionsPlugin(handler, options) {
|
|
|
1005
1053
|
core.setFailed("Error: PLUGIN_GITHUB_TOKEN env is not set");
|
|
1006
1054
|
return;
|
|
1007
1055
|
}
|
|
1008
|
-
const
|
|
1056
|
+
const githubContext = getGithubContext();
|
|
1057
|
+
const body = githubContext.payload.inputs;
|
|
1009
1058
|
const inputSchemaErrors = [...Value3.Errors(inputSchema, body)];
|
|
1010
1059
|
if (inputSchemaErrors.length) {
|
|
1011
1060
|
console.dir(inputSchemaErrors, { depth: null });
|
|
@@ -1043,7 +1092,7 @@ async function createActionsPlugin(handler, options) {
|
|
|
1043
1092
|
env2 = process.env;
|
|
1044
1093
|
}
|
|
1045
1094
|
const command = getCommand(inputs, pluginOptions);
|
|
1046
|
-
const
|
|
1095
|
+
const context = {
|
|
1047
1096
|
eventName: inputs.eventName,
|
|
1048
1097
|
payload: inputs.eventPayload,
|
|
1049
1098
|
command,
|
|
@@ -1056,20 +1105,21 @@ async function createActionsPlugin(handler, options) {
|
|
|
1056
1105
|
commentHandler: new CommentHandler()
|
|
1057
1106
|
};
|
|
1058
1107
|
try {
|
|
1059
|
-
const result = await handler(
|
|
1108
|
+
const result = await handler(context);
|
|
1060
1109
|
core.setOutput("result", result);
|
|
1061
1110
|
if (pluginOptions?.returnDataToKernel) {
|
|
1062
1111
|
await returnDataToKernel(pluginGithubToken, inputs.stateId, result);
|
|
1063
1112
|
}
|
|
1064
1113
|
} catch (error) {
|
|
1065
|
-
await handleError(
|
|
1114
|
+
await handleError(context, pluginOptions, error);
|
|
1066
1115
|
}
|
|
1067
1116
|
}
|
|
1068
1117
|
async function returnDataToKernel(repoToken, stateId, output) {
|
|
1118
|
+
const githubContext = getGithubContext();
|
|
1069
1119
|
const octokit = new customOctokit({ auth: repoToken });
|
|
1070
1120
|
await octokit.rest.repos.createDispatchEvent({
|
|
1071
|
-
owner:
|
|
1072
|
-
repo:
|
|
1121
|
+
owner: githubContext.repo.owner,
|
|
1122
|
+
repo: githubContext.repo.repo,
|
|
1073
1123
|
event_type: "return-data-to-ubiquity-os-kernel",
|
|
1074
1124
|
client_payload: {
|
|
1075
1125
|
state_id: stateId,
|
|
@@ -1136,7 +1186,7 @@ import { Value as Value4 } from "@sinclair/typebox/value";
|
|
|
1136
1186
|
|
|
1137
1187
|
// ../../node_modules/hono/dist/compose.js
|
|
1138
1188
|
var compose = (middleware, onError, onNotFound) => {
|
|
1139
|
-
return (
|
|
1189
|
+
return (context, next) => {
|
|
1140
1190
|
let index = -1;
|
|
1141
1191
|
return dispatch(0);
|
|
1142
1192
|
async function dispatch(i) {
|
|
@@ -1149,31 +1199,31 @@ var compose = (middleware, onError, onNotFound) => {
|
|
|
1149
1199
|
let handler;
|
|
1150
1200
|
if (middleware[i]) {
|
|
1151
1201
|
handler = middleware[i][0][0];
|
|
1152
|
-
|
|
1202
|
+
context.req.routeIndex = i;
|
|
1153
1203
|
} else {
|
|
1154
1204
|
handler = i === middleware.length && next || void 0;
|
|
1155
1205
|
}
|
|
1156
1206
|
if (handler) {
|
|
1157
1207
|
try {
|
|
1158
|
-
res = await handler(
|
|
1208
|
+
res = await handler(context, () => dispatch(i + 1));
|
|
1159
1209
|
} catch (err) {
|
|
1160
1210
|
if (err instanceof Error && onError) {
|
|
1161
|
-
|
|
1162
|
-
res = await onError(err,
|
|
1211
|
+
context.error = err;
|
|
1212
|
+
res = await onError(err, context);
|
|
1163
1213
|
isError = true;
|
|
1164
1214
|
} else {
|
|
1165
1215
|
throw err;
|
|
1166
1216
|
}
|
|
1167
1217
|
}
|
|
1168
1218
|
} else {
|
|
1169
|
-
if (
|
|
1170
|
-
res = await onNotFound(
|
|
1219
|
+
if (context.finalized === false && onNotFound) {
|
|
1220
|
+
res = await onNotFound(context);
|
|
1171
1221
|
}
|
|
1172
1222
|
}
|
|
1173
|
-
if (res && (
|
|
1174
|
-
|
|
1223
|
+
if (res && (context.finalized === false || isError)) {
|
|
1224
|
+
context.res = res;
|
|
1175
1225
|
}
|
|
1176
|
-
return
|
|
1226
|
+
return context;
|
|
1177
1227
|
}
|
|
1178
1228
|
};
|
|
1179
1229
|
};
|
|
@@ -1575,7 +1625,7 @@ var raw = (value, callbacks) => {
|
|
|
1575
1625
|
escapedString.callbacks = callbacks;
|
|
1576
1626
|
return escapedString;
|
|
1577
1627
|
};
|
|
1578
|
-
var resolveCallback = async (str, phase, preserveCallbacks,
|
|
1628
|
+
var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
|
|
1579
1629
|
if (typeof str === "object" && !(str instanceof String)) {
|
|
1580
1630
|
if (!(str instanceof Promise)) {
|
|
1581
1631
|
str = str.toString();
|
|
@@ -1593,9 +1643,9 @@ var resolveCallback = async (str, phase, preserveCallbacks, context2, buffer) =>
|
|
|
1593
1643
|
} else {
|
|
1594
1644
|
buffer = [str];
|
|
1595
1645
|
}
|
|
1596
|
-
const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context
|
|
1646
|
+
const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then(
|
|
1597
1647
|
(res) => Promise.all(
|
|
1598
|
-
res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false,
|
|
1648
|
+
res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer))
|
|
1599
1649
|
).then(() => buffer[0])
|
|
1600
1650
|
);
|
|
1601
1651
|
if (preserveCallbacks) {
|
|
@@ -1988,13 +2038,13 @@ var Hono = class {
|
|
|
1988
2038
|
const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
|
|
1989
2039
|
return (async () => {
|
|
1990
2040
|
try {
|
|
1991
|
-
const
|
|
1992
|
-
if (!
|
|
2041
|
+
const context = await composed(c);
|
|
2042
|
+
if (!context.finalized) {
|
|
1993
2043
|
throw new Error(
|
|
1994
2044
|
"Context is not finalized. Did you forget to return a Response object or `await next()`?"
|
|
1995
2045
|
);
|
|
1996
2046
|
}
|
|
1997
|
-
return
|
|
2047
|
+
return context.res;
|
|
1998
2048
|
} catch (err) {
|
|
1999
2049
|
return this.#handleError(err, c);
|
|
2000
2050
|
}
|
|
@@ -2053,7 +2103,7 @@ var Node = class {
|
|
|
2053
2103
|
#index;
|
|
2054
2104
|
#varIndex;
|
|
2055
2105
|
#children = /* @__PURE__ */ Object.create(null);
|
|
2056
|
-
insert(tokens, index, paramMap,
|
|
2106
|
+
insert(tokens, index, paramMap, context, pathErrorCheckOnly) {
|
|
2057
2107
|
if (tokens.length === 0) {
|
|
2058
2108
|
if (this.#index !== void 0) {
|
|
2059
2109
|
throw PATH_ERROR;
|
|
@@ -2091,7 +2141,7 @@ var Node = class {
|
|
|
2091
2141
|
}
|
|
2092
2142
|
node = this.#children[regexpStr] = new Node();
|
|
2093
2143
|
if (name !== "") {
|
|
2094
|
-
node.#varIndex =
|
|
2144
|
+
node.#varIndex = context.varIndex++;
|
|
2095
2145
|
}
|
|
2096
2146
|
}
|
|
2097
2147
|
if (!pathErrorCheckOnly && name !== "") {
|
|
@@ -2111,7 +2161,7 @@ var Node = class {
|
|
|
2111
2161
|
node = this.#children[token] = new Node();
|
|
2112
2162
|
}
|
|
2113
2163
|
}
|
|
2114
|
-
node.insert(restTokens, index, paramMap,
|
|
2164
|
+
node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);
|
|
2115
2165
|
}
|
|
2116
2166
|
buildRegExpStr() {
|
|
2117
2167
|
const childKeys = Object.keys(this.#children).sort(compareKey);
|
|
@@ -2653,11 +2703,11 @@ var HTTPException = class extends Error {
|
|
|
2653
2703
|
};
|
|
2654
2704
|
|
|
2655
2705
|
// src/server.ts
|
|
2656
|
-
async function handleError2(
|
|
2706
|
+
async function handleError2(context, pluginOptions, error) {
|
|
2657
2707
|
console.error(error);
|
|
2658
|
-
const loggerError = transformError(
|
|
2708
|
+
const loggerError = transformError(context, error);
|
|
2659
2709
|
if (pluginOptions.postCommentOnError && loggerError) {
|
|
2660
|
-
await
|
|
2710
|
+
await context.commentHandler.postComment(context, loggerError);
|
|
2661
2711
|
}
|
|
2662
2712
|
throw new HTTPException(500, { message: "Unexpected error" });
|
|
2663
2713
|
}
|
|
@@ -2708,7 +2758,7 @@ function createPlugin(handler, manifest, options) {
|
|
|
2708
2758
|
const workerName = new URL(inputs.ref).hostname.split(".")[0];
|
|
2709
2759
|
PluginRuntimeInfo.getInstance({ ...env2, CLOUDFLARE_WORKER_NAME: workerName });
|
|
2710
2760
|
const command = getCommand(inputs, pluginOptions);
|
|
2711
|
-
const
|
|
2761
|
+
const context = {
|
|
2712
2762
|
eventName: inputs.eventName,
|
|
2713
2763
|
payload: inputs.eventPayload,
|
|
2714
2764
|
command,
|
|
@@ -2721,10 +2771,10 @@ function createPlugin(handler, manifest, options) {
|
|
|
2721
2771
|
commentHandler: new CommentHandler()
|
|
2722
2772
|
};
|
|
2723
2773
|
try {
|
|
2724
|
-
const result = await handler(
|
|
2774
|
+
const result = await handler(context);
|
|
2725
2775
|
return ctx.json({ stateId: inputs.stateId, output: result ?? {} });
|
|
2726
2776
|
} catch (error) {
|
|
2727
|
-
await handleError2(
|
|
2777
|
+
await handleError2(context, pluginOptions, error);
|
|
2728
2778
|
}
|
|
2729
2779
|
});
|
|
2730
2780
|
return app;
|
|
@@ -2739,6 +2789,14 @@ function normalizeBaseUrl(baseUrl) {
|
|
|
2739
2789
|
}
|
|
2740
2790
|
return normalized;
|
|
2741
2791
|
}
|
|
2792
|
+
var MAX_LLM_RETRIES = 2;
|
|
2793
|
+
var RETRY_BACKOFF_MS = [250, 750];
|
|
2794
|
+
function getRetryDelayMs(attempt) {
|
|
2795
|
+
return RETRY_BACKOFF_MS[Math.min(attempt, RETRY_BACKOFF_MS.length - 1)] ?? 750;
|
|
2796
|
+
}
|
|
2797
|
+
function sleep(ms) {
|
|
2798
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2799
|
+
}
|
|
2742
2800
|
function getEnvString(name) {
|
|
2743
2801
|
if (typeof process === "undefined" || !process?.env) return EMPTY_STRING;
|
|
2744
2802
|
return String(process.env[name] ?? EMPTY_STRING).trim();
|
|
@@ -2753,7 +2811,11 @@ function getAiBaseUrl(options) {
|
|
|
2753
2811
|
}
|
|
2754
2812
|
async function callLlm(options, input) {
|
|
2755
2813
|
const authToken = String(input.authToken ?? EMPTY_STRING).trim();
|
|
2756
|
-
if (!authToken)
|
|
2814
|
+
if (!authToken) {
|
|
2815
|
+
const err = new Error("Missing authToken in input");
|
|
2816
|
+
err.status = 401;
|
|
2817
|
+
throw err;
|
|
2818
|
+
}
|
|
2757
2819
|
const kernelToken = "ubiquityKernelToken" in input ? input.ubiquityKernelToken : void 0;
|
|
2758
2820
|
const payload = getPayload(input);
|
|
2759
2821
|
const { owner, repo, installationId } = getRepoMetadata(payload);
|
|
@@ -2773,13 +2835,7 @@ async function callLlm(options, input) {
|
|
|
2773
2835
|
installationId,
|
|
2774
2836
|
ubiquityKernelToken: kernelToken
|
|
2775
2837
|
});
|
|
2776
|
-
const response = await
|
|
2777
|
-
if (!response.ok) {
|
|
2778
|
-
const err = await response.text();
|
|
2779
|
-
const error = new Error(`LLM API error: ${response.status} - ${err}`);
|
|
2780
|
-
error.status = response.status;
|
|
2781
|
-
throw error;
|
|
2782
|
-
}
|
|
2838
|
+
const response = await fetchWithRetry(url, { method: "POST", headers, body }, MAX_LLM_RETRIES);
|
|
2783
2839
|
if (isStream) {
|
|
2784
2840
|
if (!response.body) {
|
|
2785
2841
|
throw new Error("LLM API error: missing response body for streaming request");
|
|
@@ -2791,17 +2847,46 @@ async function callLlm(options, input) {
|
|
|
2791
2847
|
function ensureKernelToken(authToken, kernelToken) {
|
|
2792
2848
|
const isKernelTokenRequired = authToken.startsWith("gh");
|
|
2793
2849
|
if (isKernelTokenRequired && !kernelToken) {
|
|
2794
|
-
|
|
2850
|
+
const err = new Error("Missing ubiquityKernelToken in input (kernel attestation is required for GitHub auth)");
|
|
2851
|
+
err.status = 401;
|
|
2852
|
+
throw err;
|
|
2795
2853
|
}
|
|
2796
2854
|
}
|
|
2797
2855
|
function ensureMessages(messages) {
|
|
2798
2856
|
if (!Array.isArray(messages) || messages.length === 0) {
|
|
2799
|
-
|
|
2857
|
+
const err = new Error("messages must be a non-empty array");
|
|
2858
|
+
err.status = 400;
|
|
2859
|
+
throw err;
|
|
2800
2860
|
}
|
|
2801
2861
|
}
|
|
2802
2862
|
function buildAiUrl(options, baseUrl) {
|
|
2803
2863
|
return `${getAiBaseUrl({ ...options, baseUrl })}/v1/chat/completions`;
|
|
2804
2864
|
}
|
|
2865
|
+
async function fetchWithRetry(url, options, maxRetries) {
|
|
2866
|
+
let attempt = 0;
|
|
2867
|
+
let lastError;
|
|
2868
|
+
while (attempt <= maxRetries) {
|
|
2869
|
+
try {
|
|
2870
|
+
const response = await fetch(url, options);
|
|
2871
|
+
if (response.ok) return response;
|
|
2872
|
+
const errText = await response.text();
|
|
2873
|
+
if (response.status >= 500 && attempt < maxRetries) {
|
|
2874
|
+
await sleep(getRetryDelayMs(attempt));
|
|
2875
|
+
attempt += 1;
|
|
2876
|
+
continue;
|
|
2877
|
+
}
|
|
2878
|
+
const error = new Error(`LLM API error: ${response.status} - ${errText}`);
|
|
2879
|
+
error.status = response.status;
|
|
2880
|
+
throw error;
|
|
2881
|
+
} catch (error) {
|
|
2882
|
+
lastError = error;
|
|
2883
|
+
if (attempt >= maxRetries) throw error;
|
|
2884
|
+
await sleep(getRetryDelayMs(attempt));
|
|
2885
|
+
attempt += 1;
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
throw lastError ?? new Error("LLM API error: request failed after retries");
|
|
2889
|
+
}
|
|
2805
2890
|
function getPayload(input) {
|
|
2806
2891
|
if ("payload" in input) {
|
|
2807
2892
|
return input.payload;
|
|
@@ -2863,7 +2948,7 @@ function getEventData(event) {
|
|
|
2863
2948
|
if (!event.trim()) return null;
|
|
2864
2949
|
const dataLines = event.split("\n").filter((line) => line.startsWith("data:"));
|
|
2865
2950
|
if (!dataLines.length) return null;
|
|
2866
|
-
const data = dataLines.map((line) => line.startsWith("data: ") ? line.slice(6) : line.slice(5).replace(/^ /,
|
|
2951
|
+
const data = dataLines.map((line) => line.startsWith("data: ") ? line.slice(6) : line.slice(5).replace(/^ /, EMPTY_STRING)).join("\n");
|
|
2867
2952
|
return data || null;
|
|
2868
2953
|
}
|
|
2869
2954
|
function parseEventData(data) {
|
package/dist/llm.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChatCompletionMessageParam, ChatCompletionCreateParamsNonStreaming, ChatCompletion, ChatCompletionChunk } from 'openai/resources/chat/completions';
|
|
2
|
-
import { C as Context } from './context-
|
|
2
|
+
import { C as Context } from './context-Ckj1HMjz.mjs';
|
|
3
3
|
import { PluginInput } from './signature.mjs';
|
|
4
4
|
import '@octokit/webhooks';
|
|
5
5
|
import '@ubiquity-os/ubiquity-os-logger';
|
package/dist/llm.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChatCompletionMessageParam, ChatCompletionCreateParamsNonStreaming, ChatCompletion, ChatCompletionChunk } from 'openai/resources/chat/completions';
|
|
2
|
-
import { C as Context } from './context-
|
|
2
|
+
import { C as Context } from './context-BE4WjJZf.js';
|
|
3
3
|
import { PluginInput } from './signature.js';
|
|
4
4
|
import '@octokit/webhooks';
|
|
5
5
|
import '@ubiquity-os/ubiquity-os-logger';
|