@quilltap/plugin-utils 1.2.5 → 1.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
@@ -3,6 +3,52 @@ export { ToolCallFormat, ToolConvertTarget, applyDescriptionLimit, convertFromAn
3
3
  export { PluginLoggerWithChild, __clearCoreLoggerFactory, __injectCoreLoggerFactory, createPluginLogger, getLogLevelFromEnv, hasCoreLogger } from './logging/index.mjs';
4
4
  export { OpenAICompatibleProvider, OpenAICompatibleProviderConfig } from './providers/index.mjs';
5
5
  export { CreateRoleplayTemplatePluginOptions, CreateSingleTemplatePluginOptions, createRoleplayTemplatePlugin, createSingleTemplatePlugin, validateRoleplayTemplatePlugin, validateTemplateConfig } from './roleplay-templates/index.mjs';
6
+ export { isVMEnvironment, resolveHostGateway, rewriteLocalhostUrl } from './host-rewrite.mjs';
7
+
8
+ /**
9
+ * Built-in tool names for Quilltap
10
+ *
11
+ * These are the tool names used by Quilltap's built-in tools.
12
+ * Plugins that provide dynamic tools (like MCP connectors) should use
13
+ * this list for collision detection to avoid shadowing built-in functionality.
14
+ *
15
+ * @module @quilltap/plugin-utils/builtin-tools
16
+ */
17
+ /**
18
+ * Names of all built-in Quilltap tools
19
+ *
20
+ * This set contains the function names of tools that are built into Quilltap:
21
+ * - `generate_image` - AI image generation
22
+ * - `search_memories` - Search character/chat memories
23
+ * - `search_web` - Web search (when enabled)
24
+ * - `project_info` - Get project metadata
25
+ * - `file_management` - Read/write project files
26
+ * - `request_full_context` - Request full context reload (context compression)
27
+ * - `search_help` - Search Quilltap help documentation
28
+ */
29
+ declare const BUILTIN_TOOL_NAMES: Set<string>;
30
+ /**
31
+ * Get the set of built-in tool names
32
+ *
33
+ * Use this function to get the current list of reserved tool names
34
+ * when implementing collision detection in plugins that provide
35
+ * dynamic tools (e.g., MCP server connectors, external tool bridges).
36
+ *
37
+ * @returns Set of tool names that are reserved by Quilltap's built-in tools
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * import { getBuiltinToolNames } from '@quilltap/plugin-utils';
42
+ *
43
+ * // When generating tool names from external sources:
44
+ * const builtinNames = getBuiltinToolNames();
45
+ * if (builtinNames.has(proposedToolName)) {
46
+ * // Rename or prefix the tool to avoid collision
47
+ * proposedToolName = `external_${proposedToolName}`;
48
+ * }
49
+ * ```
50
+ */
51
+ declare function getBuiltinToolNames(): Set<string>;
6
52
 
7
53
  /**
8
54
  * @quilltap/plugin-utils
@@ -24,6 +70,6 @@ export { CreateRoleplayTemplatePluginOptions, CreateSingleTemplatePluginOptions,
24
70
  * Version of the plugin-utils package.
25
71
  * Can be used at runtime to check compatibility.
26
72
  */
27
- declare const PLUGIN_UTILS_VERSION = "1.2.0";
73
+ declare const PLUGIN_UTILS_VERSION = "1.4.0";
28
74
 
29
- export { PLUGIN_UTILS_VERSION };
75
+ export { BUILTIN_TOOL_NAMES, PLUGIN_UTILS_VERSION, getBuiltinToolNames };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,52 @@ export { ToolCallFormat, ToolConvertTarget, applyDescriptionLimit, convertFromAn
3
3
  export { PluginLoggerWithChild, __clearCoreLoggerFactory, __injectCoreLoggerFactory, createPluginLogger, getLogLevelFromEnv, hasCoreLogger } from './logging/index.js';
4
4
  export { OpenAICompatibleProvider, OpenAICompatibleProviderConfig } from './providers/index.js';
5
5
  export { CreateRoleplayTemplatePluginOptions, CreateSingleTemplatePluginOptions, createRoleplayTemplatePlugin, createSingleTemplatePlugin, validateRoleplayTemplatePlugin, validateTemplateConfig } from './roleplay-templates/index.js';
6
+ export { isVMEnvironment, resolveHostGateway, rewriteLocalhostUrl } from './host-rewrite.js';
7
+
8
+ /**
9
+ * Built-in tool names for Quilltap
10
+ *
11
+ * These are the tool names used by Quilltap's built-in tools.
12
+ * Plugins that provide dynamic tools (like MCP connectors) should use
13
+ * this list for collision detection to avoid shadowing built-in functionality.
14
+ *
15
+ * @module @quilltap/plugin-utils/builtin-tools
16
+ */
17
+ /**
18
+ * Names of all built-in Quilltap tools
19
+ *
20
+ * This set contains the function names of tools that are built into Quilltap:
21
+ * - `generate_image` - AI image generation
22
+ * - `search_memories` - Search character/chat memories
23
+ * - `search_web` - Web search (when enabled)
24
+ * - `project_info` - Get project metadata
25
+ * - `file_management` - Read/write project files
26
+ * - `request_full_context` - Request full context reload (context compression)
27
+ * - `search_help` - Search Quilltap help documentation
28
+ */
29
+ declare const BUILTIN_TOOL_NAMES: Set<string>;
30
+ /**
31
+ * Get the set of built-in tool names
32
+ *
33
+ * Use this function to get the current list of reserved tool names
34
+ * when implementing collision detection in plugins that provide
35
+ * dynamic tools (e.g., MCP server connectors, external tool bridges).
36
+ *
37
+ * @returns Set of tool names that are reserved by Quilltap's built-in tools
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * import { getBuiltinToolNames } from '@quilltap/plugin-utils';
42
+ *
43
+ * // When generating tool names from external sources:
44
+ * const builtinNames = getBuiltinToolNames();
45
+ * if (builtinNames.has(proposedToolName)) {
46
+ * // Rename or prefix the tool to avoid collision
47
+ * proposedToolName = `external_${proposedToolName}`;
48
+ * }
49
+ * ```
50
+ */
51
+ declare function getBuiltinToolNames(): Set<string>;
6
52
 
7
53
  /**
8
54
  * @quilltap/plugin-utils
@@ -24,6 +70,6 @@ export { CreateRoleplayTemplatePluginOptions, CreateSingleTemplatePluginOptions,
24
70
  * Version of the plugin-utils package.
25
71
  * Can be used at runtime to check compatibility.
26
72
  */
27
- declare const PLUGIN_UTILS_VERSION = "1.2.0";
73
+ declare const PLUGIN_UTILS_VERSION = "1.4.0";
28
74
 
29
- export { PLUGIN_UTILS_VERSION };
75
+ export { BUILTIN_TOOL_NAMES, PLUGIN_UTILS_VERSION, getBuiltinToolNames };
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
+ BUILTIN_TOOL_NAMES: () => BUILTIN_TOOL_NAMES,
33
34
  OpenAICompatibleProvider: () => OpenAICompatibleProvider,
34
35
  PLUGIN_UTILS_VERSION: () => PLUGIN_UTILS_VERSION,
35
36
  __clearCoreLoggerFactory: () => __clearCoreLoggerFactory,
@@ -49,13 +50,17 @@ __export(src_exports, {
49
50
  createRoleplayTemplatePlugin: () => createRoleplayTemplatePlugin,
50
51
  createSingleTemplatePlugin: () => createSingleTemplatePlugin,
51
52
  detectToolCallFormat: () => detectToolCallFormat,
53
+ getBuiltinToolNames: () => getBuiltinToolNames,
52
54
  getLogLevelFromEnv: () => getLogLevelFromEnv,
53
55
  hasCoreLogger: () => hasCoreLogger,
54
56
  hasToolCalls: () => hasToolCalls,
57
+ isVMEnvironment: () => isVMEnvironment,
55
58
  parseAnthropicToolCalls: () => parseAnthropicToolCalls,
56
59
  parseGoogleToolCalls: () => parseGoogleToolCalls,
57
60
  parseOpenAIToolCalls: () => parseOpenAIToolCalls,
58
61
  parseToolCalls: () => parseToolCalls,
62
+ resolveHostGateway: () => resolveHostGateway,
63
+ rewriteLocalhostUrl: () => rewriteLocalhostUrl,
59
64
  validateRoleplayTemplatePlugin: () => validateRoleplayTemplatePlugin,
60
65
  validateTemplateConfig: () => validateTemplateConfig
61
66
  });
@@ -731,10 +736,139 @@ function validateRoleplayTemplatePlugin(plugin) {
731
736
  return true;
732
737
  }
733
738
 
739
+ // src/builtin-tools.ts
740
+ var BUILTIN_TOOL_NAMES = /* @__PURE__ */ new Set([
741
+ "generate_image",
742
+ "search_memories",
743
+ "search_web",
744
+ "project_info",
745
+ "file_management",
746
+ "request_full_context",
747
+ "search_help"
748
+ ]);
749
+ function getBuiltinToolNames() {
750
+ return new Set(BUILTIN_TOOL_NAMES);
751
+ }
752
+
753
+ // src/host-rewrite.ts
754
+ var import_node_fs = require("fs");
755
+ var LOCALHOST_HOSTS = /* @__PURE__ */ new Set([
756
+ "localhost",
757
+ "127.0.0.1",
758
+ "[::1]",
759
+ "::1"
760
+ ]);
761
+ var cachedGatewayHost;
762
+ var rewriteLogger = createPluginLogger("host-rewrite");
763
+ function isLimaEnvironment() {
764
+ return process.env.LIMA_CONTAINER === "true";
765
+ }
766
+ function isDockerEnvironment() {
767
+ if (process.env.DOCKER_CONTAINER === "true") {
768
+ return true;
769
+ }
770
+ try {
771
+ if ((0, import_node_fs.existsSync)("/.dockerenv")) {
772
+ return true;
773
+ }
774
+ const appStat = (0, import_node_fs.statSync)("/app");
775
+ if (appStat.isDirectory()) {
776
+ return true;
777
+ }
778
+ } catch {
779
+ }
780
+ return false;
781
+ }
782
+ function isVMEnvironment() {
783
+ return isDockerEnvironment() || isLimaEnvironment();
784
+ }
785
+ function resolveHostGateway() {
786
+ if (cachedGatewayHost !== void 0) {
787
+ return cachedGatewayHost;
788
+ }
789
+ const envIP = process.env.QUILLTAP_HOST_IP;
790
+ if (envIP) {
791
+ rewriteLogger.info("Host gateway from QUILLTAP_HOST_IP", { host: envIP });
792
+ cachedGatewayHost = envIP;
793
+ return cachedGatewayHost;
794
+ }
795
+ if (isDockerEnvironment() && !isLimaEnvironment()) {
796
+ rewriteLogger.info("Docker environment detected \u2014 using host.docker.internal as gateway hostname");
797
+ cachedGatewayHost = "host.docker.internal";
798
+ return cachedGatewayHost;
799
+ }
800
+ try {
801
+ const routeTable = (0, import_node_fs.readFileSync)("/proc/net/route", "utf-8");
802
+ for (const line of routeTable.split("\n").slice(1)) {
803
+ const fields = line.trim().split(" ");
804
+ if (fields.length >= 3 && fields[1] === "00000000") {
805
+ const hexGateway = fields[2];
806
+ const ip = [
807
+ parseInt(hexGateway.substring(6, 8), 16),
808
+ parseInt(hexGateway.substring(4, 6), 16),
809
+ parseInt(hexGateway.substring(2, 4), 16),
810
+ parseInt(hexGateway.substring(0, 2), 16)
811
+ ].join(".");
812
+ rewriteLogger.info("Host gateway IP from /proc/net/route", { ip });
813
+ cachedGatewayHost = ip;
814
+ return cachedGatewayHost;
815
+ }
816
+ }
817
+ } catch {
818
+ rewriteLogger.debug("Could not read /proc/net/route for default gateway lookup");
819
+ }
820
+ try {
821
+ const hosts = (0, import_node_fs.readFileSync)("/etc/hosts", "utf-8");
822
+ for (const line of hosts.split("\n")) {
823
+ const trimmed = line.trim();
824
+ if (trimmed.startsWith("#") || trimmed === "") continue;
825
+ const parts = trimmed.split(/\s+/);
826
+ if (parts.length >= 2 && parts.slice(1).includes("host.docker.internal")) {
827
+ const ip = parts[0];
828
+ rewriteLogger.info("Host gateway IP from /etc/hosts (host.docker.internal)", { ip });
829
+ cachedGatewayHost = ip;
830
+ return cachedGatewayHost;
831
+ }
832
+ }
833
+ } catch {
834
+ rewriteLogger.debug("Could not read /etc/hosts for host.docker.internal lookup");
835
+ }
836
+ rewriteLogger.warn("Could not resolve host gateway \u2014 localhost URLs will not be rewritten");
837
+ cachedGatewayHost = null;
838
+ return cachedGatewayHost;
839
+ }
840
+ function rewriteLocalhostUrl(url) {
841
+ if (!isVMEnvironment()) {
842
+ return url;
843
+ }
844
+ let parsed;
845
+ try {
846
+ parsed = new URL(url);
847
+ } catch {
848
+ return url;
849
+ }
850
+ if (!LOCALHOST_HOSTS.has(parsed.hostname)) {
851
+ return url;
852
+ }
853
+ const gatewayHost = resolveHostGateway();
854
+ if (!gatewayHost) {
855
+ return url;
856
+ }
857
+ parsed.hostname = gatewayHost;
858
+ const rewritten = parsed.toString();
859
+ rewriteLogger.debug("Rewrote localhost URL", {
860
+ original: url,
861
+ rewritten,
862
+ gatewayHost
863
+ });
864
+ return rewritten;
865
+ }
866
+
734
867
  // src/index.ts
735
- var PLUGIN_UTILS_VERSION = "1.2.0";
868
+ var PLUGIN_UTILS_VERSION = "1.4.0";
736
869
  // Annotate the CommonJS export names for ESM import in node:
737
870
  0 && (module.exports = {
871
+ BUILTIN_TOOL_NAMES,
738
872
  OpenAICompatibleProvider,
739
873
  PLUGIN_UTILS_VERSION,
740
874
  __clearCoreLoggerFactory,
@@ -754,13 +888,17 @@ var PLUGIN_UTILS_VERSION = "1.2.0";
754
888
  createRoleplayTemplatePlugin,
755
889
  createSingleTemplatePlugin,
756
890
  detectToolCallFormat,
891
+ getBuiltinToolNames,
757
892
  getLogLevelFromEnv,
758
893
  hasCoreLogger,
759
894
  hasToolCalls,
895
+ isVMEnvironment,
760
896
  parseAnthropicToolCalls,
761
897
  parseGoogleToolCalls,
762
898
  parseOpenAIToolCalls,
763
899
  parseToolCalls,
900
+ resolveHostGateway,
901
+ rewriteLocalhostUrl,
764
902
  validateRoleplayTemplatePlugin,
765
903
  validateTemplateConfig
766
904
  });