@ubiquity-os/plugin-sdk 3.3.0 → 3.4.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/index.d.mts CHANGED
@@ -129,11 +129,13 @@ interface Options$1 {
129
129
  bypassSignatureVerification?: boolean;
130
130
  returnDataToKernel?: boolean;
131
131
  }
132
+ /**
133
+ * Removes wrapper backticks or fenced blocks that LLMs often return around payloads.
134
+ */
135
+ declare function sanitizeLlmResponse(input: string): string;
132
136
 
133
137
  declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, options?: Options$1): Promise<void>;
134
138
 
135
- declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
136
-
137
139
  /**
138
140
  * Options for cleanMarkdown.
139
141
  *
@@ -164,4 +166,6 @@ type Options = {
164
166
  */
165
167
  declare function cleanMarkdown(md: string, options?: Options): string;
166
168
 
167
- export { CommentHandler, type Context, type Options$1 as Options, cleanMarkdown, createActionsPlugin, createPlugin };
169
+ declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
170
+
171
+ export { CommentHandler, type Context, type Options$1 as Options, cleanMarkdown, createActionsPlugin, createPlugin, sanitizeLlmResponse };
package/dist/index.d.ts CHANGED
@@ -129,11 +129,13 @@ interface Options$1 {
129
129
  bypassSignatureVerification?: boolean;
130
130
  returnDataToKernel?: boolean;
131
131
  }
132
+ /**
133
+ * Removes wrapper backticks or fenced blocks that LLMs often return around payloads.
134
+ */
135
+ declare function sanitizeLlmResponse(input: string): string;
132
136
 
133
137
  declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, options?: Options$1): Promise<void>;
134
138
 
135
- declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
136
-
137
139
  /**
138
140
  * Options for cleanMarkdown.
139
141
  *
@@ -164,4 +166,6 @@ type Options = {
164
166
  */
165
167
  declare function cleanMarkdown(md: string, options?: Options): string;
166
168
 
167
- export { CommentHandler, type Context, type Options$1 as Options, cleanMarkdown, createActionsPlugin, createPlugin };
169
+ declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
170
+
171
+ export { CommentHandler, type Context, type Options$1 as Options, cleanMarkdown, createActionsPlugin, createPlugin, sanitizeLlmResponse };
package/dist/index.js CHANGED
@@ -33,7 +33,8 @@ __export(src_exports, {
33
33
  CommentHandler: () => CommentHandler,
34
34
  cleanMarkdown: () => cleanMarkdown,
35
35
  createActionsPlugin: () => createActionsPlugin,
36
- createPlugin: () => createPlugin
36
+ createPlugin: () => createPlugin,
37
+ sanitizeLlmResponse: () => sanitizeLlmResponse
37
38
  });
38
39
  module.exports = __toCommonJS(src_exports);
39
40
 
@@ -62,7 +63,11 @@ var PluginRuntimeInfo = class _PluginRuntimeInfo {
62
63
  _PluginRuntimeInfo._instance = new CfRuntimeInfo(env);
63
64
  break;
64
65
  case "deno":
65
- _PluginRuntimeInfo._instance = new DenoRuntimeInfo(env);
66
+ if (process.env.CI) {
67
+ _PluginRuntimeInfo._instance = new NodeRuntimeInfo(env);
68
+ } else {
69
+ _PluginRuntimeInfo._instance = new DenoRuntimeInfo(env);
70
+ }
66
71
  break;
67
72
  case "node":
68
73
  _PluginRuntimeInfo._instance = new NodeRuntimeInfo(env);
@@ -152,6 +157,24 @@ JQIDAQAB
152
157
  function sanitizeMetadata(obj) {
153
158
  return JSON.stringify(obj, null, 2).replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/--/g, "&#45;&#45;");
154
159
  }
160
+ function sanitizeLlmResponse(input) {
161
+ const trimmed = input.trim();
162
+ if (!trimmed) {
163
+ return trimmed;
164
+ }
165
+ if (trimmed.startsWith("```")) {
166
+ let result = trimmed.replace(/^```[a-z0-9+-]*\s*(?:\r\n|\n)?/i, "");
167
+ if (result.endsWith("```")) {
168
+ result = result.slice(0, -3);
169
+ result = result.replace(/[\r\n]+$/, "");
170
+ }
171
+ return result.trim();
172
+ }
173
+ if (trimmed.startsWith("`") && trimmed.endsWith("`")) {
174
+ return trimmed.slice(1, -1).trim();
175
+ }
176
+ return trimmed;
177
+ }
155
178
  function getPluginOptions(options) {
156
179
  return {
157
180
  // Important to use || and not ?? to not consider empty strings
@@ -549,6 +572,59 @@ async function returnDataToKernel(repoToken, stateId, output) {
549
572
  });
550
573
  }
551
574
 
575
+ // src/markdown.ts
576
+ var VOID_TAGS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
577
+ function cleanMarkdown(md, options = {}) {
578
+ const codeBlockRegex = /(```[\s\S]*?```|~~~[\s\S]*?~~~)/g;
579
+ const { tags = [], shouldCollapseEmptyLines = false } = options;
580
+ const segments = [];
581
+ let lastIndex = 0;
582
+ const matches = [...md.matchAll(codeBlockRegex)];
583
+ for (const match of matches) {
584
+ if (match.index > lastIndex) {
585
+ segments.push(processSegment(md.slice(lastIndex, match.index), tags, shouldCollapseEmptyLines));
586
+ }
587
+ segments.push(match[0]);
588
+ lastIndex = match.index + match[0].length;
589
+ }
590
+ if (lastIndex < md.length) {
591
+ segments.push(processSegment(md.slice(lastIndex), tags, shouldCollapseEmptyLines));
592
+ }
593
+ return segments.join("");
594
+ }
595
+ function processSegment(segment, extraTags, shouldCollapseEmptyLines) {
596
+ const inlineCodeRegex = /`[^`]*`/g;
597
+ const inlineCodes = [];
598
+ let s = segment.replace(inlineCodeRegex, (m) => {
599
+ inlineCodes.push(m);
600
+ return `__INLINE_CODE_${inlineCodes.length - 1}__`;
601
+ });
602
+ s = s.replace(/<!--[\s\S]*?-->/g, "");
603
+ for (const raw of extraTags) {
604
+ if (!raw) continue;
605
+ const tag = raw.toLowerCase().trim().replace(/[^\w:-]/g, "");
606
+ if (!tag) continue;
607
+ if (VOID_TAGS.has(tag)) {
608
+ const voidRe = new RegExp(`<${tag}\\b[^>]*\\/?>`, "gi");
609
+ s = s.replace(voidRe, "");
610
+ continue;
611
+ }
612
+ const pairRe = new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`, "gi");
613
+ let prev;
614
+ do {
615
+ prev = s;
616
+ s = s.replace(pairRe, "");
617
+ } while (s !== prev);
618
+ const openCloseRe = new RegExp(`<\\/?${tag}\\b[^>]*>`, "gi");
619
+ s = s.replace(openCloseRe, "");
620
+ }
621
+ s = s.replace(/__INLINE_CODE_(\d+)__/g, (str, idx) => inlineCodes[+idx]);
622
+ if (shouldCollapseEmptyLines) {
623
+ s = s.replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, "\n\n");
624
+ }
625
+ return s;
626
+ }
627
+
552
628
  // src/server.ts
553
629
  var import_value4 = require("@sinclair/typebox/value");
554
630
  var import_ubiquity_os_logger4 = require("@ubiquity-os/ubiquity-os-logger");
@@ -629,63 +705,11 @@ function createPlugin(handler, manifest, options) {
629
705
  });
630
706
  return app;
631
707
  }
632
-
633
- // src/markdown.ts
634
- var VOID_TAGS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
635
- function cleanMarkdown(md, options = {}) {
636
- const codeBlockRegex = /(```[\s\S]*?```|~~~[\s\S]*?~~~)/g;
637
- const { tags = [], shouldCollapseEmptyLines = false } = options;
638
- const segments = [];
639
- let lastIndex = 0;
640
- const matches = [...md.matchAll(codeBlockRegex)];
641
- for (const match of matches) {
642
- if (match.index > lastIndex) {
643
- segments.push(processSegment(md.slice(lastIndex, match.index), tags, shouldCollapseEmptyLines));
644
- }
645
- segments.push(match[0]);
646
- lastIndex = match.index + match[0].length;
647
- }
648
- if (lastIndex < md.length) {
649
- segments.push(processSegment(md.slice(lastIndex), tags, shouldCollapseEmptyLines));
650
- }
651
- return segments.join("");
652
- }
653
- function processSegment(segment, extraTags, shouldCollapseEmptyLines) {
654
- const inlineCodeRegex = /`[^`]*`/g;
655
- const inlineCodes = [];
656
- let s = segment.replace(inlineCodeRegex, (m) => {
657
- inlineCodes.push(m);
658
- return `__INLINE_CODE_${inlineCodes.length - 1}__`;
659
- });
660
- s = s.replace(/<!--[\s\S]*?-->/g, "");
661
- for (const raw of extraTags) {
662
- if (!raw) continue;
663
- const tag = raw.toLowerCase().trim().replace(/[^\w:-]/g, "");
664
- if (!tag) continue;
665
- if (VOID_TAGS.has(tag)) {
666
- const voidRe = new RegExp(`<${tag}\\b[^>]*\\/?>`, "gi");
667
- s = s.replace(voidRe, "");
668
- continue;
669
- }
670
- const pairRe = new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`, "gi");
671
- let prev;
672
- do {
673
- prev = s;
674
- s = s.replace(pairRe, "");
675
- } while (s !== prev);
676
- const openCloseRe = new RegExp(`<\\/?${tag}\\b[^>]*>`, "gi");
677
- s = s.replace(openCloseRe, "");
678
- }
679
- s = s.replace(/__INLINE_CODE_(\d+)__/g, (str, idx) => inlineCodes[+idx]);
680
- if (shouldCollapseEmptyLines) {
681
- s = s.replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, "\n\n");
682
- }
683
- return s;
684
- }
685
708
  // Annotate the CommonJS export names for ESM import in node:
686
709
  0 && (module.exports = {
687
710
  CommentHandler,
688
711
  cleanMarkdown,
689
712
  createActionsPlugin,
690
- createPlugin
713
+ createPlugin,
714
+ sanitizeLlmResponse
691
715
  });
package/dist/index.mjs CHANGED
@@ -23,7 +23,11 @@ var PluginRuntimeInfo = class _PluginRuntimeInfo {
23
23
  _PluginRuntimeInfo._instance = new CfRuntimeInfo(env);
24
24
  break;
25
25
  case "deno":
26
- _PluginRuntimeInfo._instance = new DenoRuntimeInfo(env);
26
+ if (process.env.CI) {
27
+ _PluginRuntimeInfo._instance = new NodeRuntimeInfo(env);
28
+ } else {
29
+ _PluginRuntimeInfo._instance = new DenoRuntimeInfo(env);
30
+ }
27
31
  break;
28
32
  case "node":
29
33
  _PluginRuntimeInfo._instance = new NodeRuntimeInfo(env);
@@ -113,6 +117,24 @@ JQIDAQAB
113
117
  function sanitizeMetadata(obj) {
114
118
  return JSON.stringify(obj, null, 2).replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/--/g, "&#45;&#45;");
115
119
  }
120
+ function sanitizeLlmResponse(input) {
121
+ const trimmed = input.trim();
122
+ if (!trimmed) {
123
+ return trimmed;
124
+ }
125
+ if (trimmed.startsWith("```")) {
126
+ let result = trimmed.replace(/^```[a-z0-9+-]*\s*(?:\r\n|\n)?/i, "");
127
+ if (result.endsWith("```")) {
128
+ result = result.slice(0, -3);
129
+ result = result.replace(/[\r\n]+$/, "");
130
+ }
131
+ return result.trim();
132
+ }
133
+ if (trimmed.startsWith("`") && trimmed.endsWith("`")) {
134
+ return trimmed.slice(1, -1).trim();
135
+ }
136
+ return trimmed;
137
+ }
116
138
  function getPluginOptions(options) {
117
139
  return {
118
140
  // Important to use || and not ?? to not consider empty strings
@@ -510,6 +532,59 @@ async function returnDataToKernel(repoToken, stateId, output) {
510
532
  });
511
533
  }
512
534
 
535
+ // src/markdown.ts
536
+ var VOID_TAGS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
537
+ function cleanMarkdown(md, options = {}) {
538
+ const codeBlockRegex = /(```[\s\S]*?```|~~~[\s\S]*?~~~)/g;
539
+ const { tags = [], shouldCollapseEmptyLines = false } = options;
540
+ const segments = [];
541
+ let lastIndex = 0;
542
+ const matches = [...md.matchAll(codeBlockRegex)];
543
+ for (const match of matches) {
544
+ if (match.index > lastIndex) {
545
+ segments.push(processSegment(md.slice(lastIndex, match.index), tags, shouldCollapseEmptyLines));
546
+ }
547
+ segments.push(match[0]);
548
+ lastIndex = match.index + match[0].length;
549
+ }
550
+ if (lastIndex < md.length) {
551
+ segments.push(processSegment(md.slice(lastIndex), tags, shouldCollapseEmptyLines));
552
+ }
553
+ return segments.join("");
554
+ }
555
+ function processSegment(segment, extraTags, shouldCollapseEmptyLines) {
556
+ const inlineCodeRegex = /`[^`]*`/g;
557
+ const inlineCodes = [];
558
+ let s = segment.replace(inlineCodeRegex, (m) => {
559
+ inlineCodes.push(m);
560
+ return `__INLINE_CODE_${inlineCodes.length - 1}__`;
561
+ });
562
+ s = s.replace(/<!--[\s\S]*?-->/g, "");
563
+ for (const raw of extraTags) {
564
+ if (!raw) continue;
565
+ const tag = raw.toLowerCase().trim().replace(/[^\w:-]/g, "");
566
+ if (!tag) continue;
567
+ if (VOID_TAGS.has(tag)) {
568
+ const voidRe = new RegExp(`<${tag}\\b[^>]*\\/?>`, "gi");
569
+ s = s.replace(voidRe, "");
570
+ continue;
571
+ }
572
+ const pairRe = new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`, "gi");
573
+ let prev;
574
+ do {
575
+ prev = s;
576
+ s = s.replace(pairRe, "");
577
+ } while (s !== prev);
578
+ const openCloseRe = new RegExp(`<\\/?${tag}\\b[^>]*>`, "gi");
579
+ s = s.replace(openCloseRe, "");
580
+ }
581
+ s = s.replace(/__INLINE_CODE_(\d+)__/g, (str, idx) => inlineCodes[+idx]);
582
+ if (shouldCollapseEmptyLines) {
583
+ s = s.replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, "\n\n");
584
+ }
585
+ return s;
586
+ }
587
+
513
588
  // src/server.ts
514
589
  import { Value as Value4 } from "@sinclair/typebox/value";
515
590
  import { Logs as Logs2 } from "@ubiquity-os/ubiquity-os-logger";
@@ -590,62 +665,10 @@ function createPlugin(handler, manifest, options) {
590
665
  });
591
666
  return app;
592
667
  }
593
-
594
- // src/markdown.ts
595
- var VOID_TAGS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
596
- function cleanMarkdown(md, options = {}) {
597
- const codeBlockRegex = /(```[\s\S]*?```|~~~[\s\S]*?~~~)/g;
598
- const { tags = [], shouldCollapseEmptyLines = false } = options;
599
- const segments = [];
600
- let lastIndex = 0;
601
- const matches = [...md.matchAll(codeBlockRegex)];
602
- for (const match of matches) {
603
- if (match.index > lastIndex) {
604
- segments.push(processSegment(md.slice(lastIndex, match.index), tags, shouldCollapseEmptyLines));
605
- }
606
- segments.push(match[0]);
607
- lastIndex = match.index + match[0].length;
608
- }
609
- if (lastIndex < md.length) {
610
- segments.push(processSegment(md.slice(lastIndex), tags, shouldCollapseEmptyLines));
611
- }
612
- return segments.join("");
613
- }
614
- function processSegment(segment, extraTags, shouldCollapseEmptyLines) {
615
- const inlineCodeRegex = /`[^`]*`/g;
616
- const inlineCodes = [];
617
- let s = segment.replace(inlineCodeRegex, (m) => {
618
- inlineCodes.push(m);
619
- return `__INLINE_CODE_${inlineCodes.length - 1}__`;
620
- });
621
- s = s.replace(/<!--[\s\S]*?-->/g, "");
622
- for (const raw of extraTags) {
623
- if (!raw) continue;
624
- const tag = raw.toLowerCase().trim().replace(/[^\w:-]/g, "");
625
- if (!tag) continue;
626
- if (VOID_TAGS.has(tag)) {
627
- const voidRe = new RegExp(`<${tag}\\b[^>]*\\/?>`, "gi");
628
- s = s.replace(voidRe, "");
629
- continue;
630
- }
631
- const pairRe = new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`, "gi");
632
- let prev;
633
- do {
634
- prev = s;
635
- s = s.replace(pairRe, "");
636
- } while (s !== prev);
637
- const openCloseRe = new RegExp(`<\\/?${tag}\\b[^>]*>`, "gi");
638
- s = s.replace(openCloseRe, "");
639
- }
640
- s = s.replace(/__INLINE_CODE_(\d+)__/g, (str, idx) => inlineCodes[+idx]);
641
- if (shouldCollapseEmptyLines) {
642
- s = s.replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, "\n\n");
643
- }
644
- return s;
645
- }
646
668
  export {
647
669
  CommentHandler,
648
670
  cleanMarkdown,
649
671
  createActionsPlugin,
650
- createPlugin
672
+ createPlugin,
673
+ sanitizeLlmResponse
651
674
  };
package/dist/signature.js CHANGED
@@ -25,6 +25,16 @@ __export(signature_exports, {
25
25
  verifySignature: () => verifySignature
26
26
  });
27
27
  module.exports = __toCommonJS(signature_exports);
28
+
29
+ // src/helpers/compression.ts
30
+ var import_node_zlib = require("zlib");
31
+ function compressString(str) {
32
+ const input = Buffer.from(str, "utf8");
33
+ const compressed = (0, import_node_zlib.brotliCompressSync)(input);
34
+ return Buffer.from(compressed).toString("base64");
35
+ }
36
+
37
+ // src/signature.ts
28
38
  var PluginInput = class {
29
39
  _privateKey;
30
40
  stateId;
@@ -48,7 +58,7 @@ var PluginInput = class {
48
58
  const inputs = {
49
59
  stateId: this.stateId,
50
60
  eventName: this.eventName,
51
- eventPayload: JSON.stringify(this.eventPayload),
61
+ eventPayload: compressString(JSON.stringify(this.eventPayload)),
52
62
  settings: JSON.stringify(this.settings),
53
63
  authToken: this.authToken,
54
64
  ref: this.ref,
@@ -1,3 +1,11 @@
1
+ // src/helpers/compression.ts
2
+ import { brotliCompressSync, brotliDecompressSync } from "node:zlib";
3
+ function compressString(str) {
4
+ const input = Buffer.from(str, "utf8");
5
+ const compressed = brotliCompressSync(input);
6
+ return Buffer.from(compressed).toString("base64");
7
+ }
8
+
1
9
  // src/signature.ts
2
10
  var PluginInput = class {
3
11
  _privateKey;
@@ -22,7 +30,7 @@ var PluginInput = class {
22
30
  const inputs = {
23
31
  stateId: this.stateId,
24
32
  eventName: this.eventName,
25
- eventPayload: JSON.stringify(this.eventPayload),
33
+ eventPayload: compressString(JSON.stringify(this.eventPayload)),
26
34
  settings: JSON.stringify(this.settings),
27
35
  authToken: this.authToken,
28
36
  ref: this.ref,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubiquity-os/plugin-sdk",
3
- "version": "3.3.0",
3
+ "version": "3.4.0",
4
4
  "description": "SDK for plugin support.",
5
5
  "author": "Ubiquity DAO",
6
6
  "license": "MIT",