@quilltap/plugin-utils 1.2.4 → 1.3.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/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to @quilltap/plugin-utils will be documented in this file.
4
4
 
5
+ ## [1.2.5] - 2026-01-25
6
+
7
+ ### Fixed
8
+
9
+ - **Environment Variable Typo**
10
+ - Fixed spelling of environment variable from QUIL-T-T-AP to QUIL-L-T-AP (correct: `QUILLTAP_LOG_LEVEL`)
11
+ - **Unused Variable Cleanup**
12
+ - Removed unused `finalFinishReason` variable in OpenAI-compatible provider streaming
13
+ - Removed unused `enableLogging` functionality in roleplay template builder (option retained in API for future use)
14
+
5
15
  ## [1.2.4] - 2026-01-21
6
16
 
7
17
  ### Fixed
package/dist/index.d.mts CHANGED
@@ -4,6 +4,50 @@ export { PluginLoggerWithChild, __clearCoreLoggerFactory, __injectCoreLoggerFact
4
4
  export { OpenAICompatibleProvider, OpenAICompatibleProviderConfig } from './providers/index.mjs';
5
5
  export { CreateRoleplayTemplatePluginOptions, CreateSingleTemplatePluginOptions, createRoleplayTemplatePlugin, createSingleTemplatePlugin, validateRoleplayTemplatePlugin, validateTemplateConfig } from './roleplay-templates/index.mjs';
6
6
 
7
+ /**
8
+ * Built-in tool names for Quilltap
9
+ *
10
+ * These are the tool names used by Quilltap's built-in tools.
11
+ * Plugins that provide dynamic tools (like MCP connectors) should use
12
+ * this list for collision detection to avoid shadowing built-in functionality.
13
+ *
14
+ * @module @quilltap/plugin-utils/builtin-tools
15
+ */
16
+ /**
17
+ * Names of all built-in Quilltap tools
18
+ *
19
+ * This set contains the function names of tools that are built into Quilltap:
20
+ * - `generate_image` - AI image generation
21
+ * - `search_memories` - Search character/chat memories
22
+ * - `search_web` - Web search (when enabled)
23
+ * - `project_info` - Get project metadata
24
+ * - `file_management` - Read/write project files
25
+ * - `request_full_context` - Request full context reload (context compression)
26
+ */
27
+ declare const BUILTIN_TOOL_NAMES: Set<string>;
28
+ /**
29
+ * Get the set of built-in tool names
30
+ *
31
+ * Use this function to get the current list of reserved tool names
32
+ * when implementing collision detection in plugins that provide
33
+ * dynamic tools (e.g., MCP server connectors, external tool bridges).
34
+ *
35
+ * @returns Set of tool names that are reserved by Quilltap's built-in tools
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * import { getBuiltinToolNames } from '@quilltap/plugin-utils';
40
+ *
41
+ * // When generating tool names from external sources:
42
+ * const builtinNames = getBuiltinToolNames();
43
+ * if (builtinNames.has(proposedToolName)) {
44
+ * // Rename or prefix the tool to avoid collision
45
+ * proposedToolName = `external_${proposedToolName}`;
46
+ * }
47
+ * ```
48
+ */
49
+ declare function getBuiltinToolNames(): Set<string>;
50
+
7
51
  /**
8
52
  * @quilltap/plugin-utils
9
53
  *
@@ -24,6 +68,6 @@ export { CreateRoleplayTemplatePluginOptions, CreateSingleTemplatePluginOptions,
24
68
  * Version of the plugin-utils package.
25
69
  * Can be used at runtime to check compatibility.
26
70
  */
27
- declare const PLUGIN_UTILS_VERSION = "1.2.0";
71
+ declare const PLUGIN_UTILS_VERSION = "1.3.0";
28
72
 
29
- export { PLUGIN_UTILS_VERSION };
73
+ export { BUILTIN_TOOL_NAMES, PLUGIN_UTILS_VERSION, getBuiltinToolNames };
package/dist/index.d.ts CHANGED
@@ -4,6 +4,50 @@ export { PluginLoggerWithChild, __clearCoreLoggerFactory, __injectCoreLoggerFact
4
4
  export { OpenAICompatibleProvider, OpenAICompatibleProviderConfig } from './providers/index.js';
5
5
  export { CreateRoleplayTemplatePluginOptions, CreateSingleTemplatePluginOptions, createRoleplayTemplatePlugin, createSingleTemplatePlugin, validateRoleplayTemplatePlugin, validateTemplateConfig } from './roleplay-templates/index.js';
6
6
 
7
+ /**
8
+ * Built-in tool names for Quilltap
9
+ *
10
+ * These are the tool names used by Quilltap's built-in tools.
11
+ * Plugins that provide dynamic tools (like MCP connectors) should use
12
+ * this list for collision detection to avoid shadowing built-in functionality.
13
+ *
14
+ * @module @quilltap/plugin-utils/builtin-tools
15
+ */
16
+ /**
17
+ * Names of all built-in Quilltap tools
18
+ *
19
+ * This set contains the function names of tools that are built into Quilltap:
20
+ * - `generate_image` - AI image generation
21
+ * - `search_memories` - Search character/chat memories
22
+ * - `search_web` - Web search (when enabled)
23
+ * - `project_info` - Get project metadata
24
+ * - `file_management` - Read/write project files
25
+ * - `request_full_context` - Request full context reload (context compression)
26
+ */
27
+ declare const BUILTIN_TOOL_NAMES: Set<string>;
28
+ /**
29
+ * Get the set of built-in tool names
30
+ *
31
+ * Use this function to get the current list of reserved tool names
32
+ * when implementing collision detection in plugins that provide
33
+ * dynamic tools (e.g., MCP server connectors, external tool bridges).
34
+ *
35
+ * @returns Set of tool names that are reserved by Quilltap's built-in tools
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * import { getBuiltinToolNames } from '@quilltap/plugin-utils';
40
+ *
41
+ * // When generating tool names from external sources:
42
+ * const builtinNames = getBuiltinToolNames();
43
+ * if (builtinNames.has(proposedToolName)) {
44
+ * // Rename or prefix the tool to avoid collision
45
+ * proposedToolName = `external_${proposedToolName}`;
46
+ * }
47
+ * ```
48
+ */
49
+ declare function getBuiltinToolNames(): Set<string>;
50
+
7
51
  /**
8
52
  * @quilltap/plugin-utils
9
53
  *
@@ -24,6 +68,6 @@ export { CreateRoleplayTemplatePluginOptions, CreateSingleTemplatePluginOptions,
24
68
  * Version of the plugin-utils package.
25
69
  * Can be used at runtime to check compatibility.
26
70
  */
27
- declare const PLUGIN_UTILS_VERSION = "1.2.0";
71
+ declare const PLUGIN_UTILS_VERSION = "1.3.0";
28
72
 
29
- export { PLUGIN_UTILS_VERSION };
73
+ 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,6 +50,7 @@ __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,
@@ -361,7 +363,7 @@ function createPluginLogger(pluginName, minLevel = "debug") {
361
363
  }
362
364
  function getLogLevelFromEnv() {
363
365
  if (typeof process !== "undefined" && process.env) {
364
- const envLevel = process.env.LOG_LEVEL || process.env.QUILTTAP_LOG_LEVEL;
366
+ const envLevel = process.env.LOG_LEVEL || process.env.QUILLTAP_LOG_LEVEL;
365
367
  if (envLevel && ["debug", "info", "warn", "error"].includes(envLevel)) {
366
368
  return envLevel;
367
369
  }
@@ -401,10 +403,6 @@ var OpenAICompatibleProvider = class {
401
403
  this.attachmentErrorMessage = config.attachmentErrorMessage ?? "OpenAI-compatible provider file attachment support varies by implementation (not yet implemented)";
402
404
  }
403
405
  this.logger = createPluginLogger(`${this.providerName}Provider`);
404
- this.logger.debug(`${this.providerName} provider instantiated`, {
405
- context: `${this.providerName}Provider.constructor`,
406
- baseUrl: this.baseUrl
407
- });
408
406
  }
409
407
  /**
410
408
  * Collects attachment failures for messages with attachments.
@@ -451,11 +449,6 @@ var OpenAICompatibleProvider = class {
451
449
  * @returns Complete LLM response with content and usage statistics
452
450
  */
453
451
  async sendMessage(params, apiKey) {
454
- this.logger.debug(`${this.providerName} sendMessage called`, {
455
- context: `${this.providerName}Provider.sendMessage`,
456
- model: params.model,
457
- baseUrl: this.baseUrl
458
- });
459
452
  this.validateApiKeyRequirement(apiKey);
460
453
  const attachmentResults = this.collectAttachmentFailures(params);
461
454
  const client = new import_openai.default({
@@ -476,12 +469,6 @@ var OpenAICompatibleProvider = class {
476
469
  stop: params.stop
477
470
  });
478
471
  const choice = response.choices[0];
479
- this.logger.debug(`Received ${this.providerName} response`, {
480
- context: `${this.providerName}Provider.sendMessage`,
481
- finishReason: choice.finish_reason,
482
- promptTokens: response.usage?.prompt_tokens,
483
- completionTokens: response.usage?.completion_tokens
484
- });
485
472
  return {
486
473
  content: choice.message.content ?? "",
487
474
  finishReason: choice.finish_reason,
@@ -510,11 +497,6 @@ var OpenAICompatibleProvider = class {
510
497
  * @yields Stream chunks with content and final usage statistics
511
498
  */
512
499
  async *streamMessage(params, apiKey) {
513
- this.logger.debug(`${this.providerName} streamMessage called`, {
514
- context: `${this.providerName}Provider.streamMessage`,
515
- model: params.model,
516
- baseUrl: this.baseUrl
517
- });
518
500
  this.validateApiKeyRequirement(apiKey);
519
501
  const attachmentResults = this.collectAttachmentFailures(params);
520
502
  const client = new import_openai.default({
@@ -537,26 +519,16 @@ var OpenAICompatibleProvider = class {
537
519
  });
538
520
  let chunkCount = 0;
539
521
  let accumulatedUsage = null;
540
- let finalFinishReason = null;
541
522
  for await (const chunk of stream) {
542
523
  chunkCount++;
543
524
  const content = chunk.choices[0]?.delta?.content;
544
- const finishReason = chunk.choices[0]?.finish_reason;
545
525
  const hasUsage = chunk.usage;
546
- if (finishReason) {
547
- finalFinishReason = finishReason;
548
- }
549
526
  if (hasUsage) {
550
527
  accumulatedUsage = {
551
528
  prompt_tokens: chunk.usage?.prompt_tokens,
552
529
  completion_tokens: chunk.usage?.completion_tokens,
553
530
  total_tokens: chunk.usage?.total_tokens
554
531
  };
555
- this.logger.debug("Received usage data in stream", {
556
- context: `${this.providerName}Provider.streamMessage`,
557
- promptTokens: chunk.usage?.prompt_tokens,
558
- completionTokens: chunk.usage?.completion_tokens
559
- });
560
532
  }
561
533
  if (content) {
562
534
  yield {
@@ -565,14 +537,6 @@ var OpenAICompatibleProvider = class {
565
537
  };
566
538
  }
567
539
  }
568
- this.logger.debug("Stream completed", {
569
- context: `${this.providerName}Provider.streamMessage`,
570
- finishReason: finalFinishReason,
571
- chunks: chunkCount,
572
- promptTokens: accumulatedUsage?.prompt_tokens,
573
- completionTokens: accumulatedUsage?.completion_tokens,
574
- hasUsage: !!accumulatedUsage
575
- });
576
540
  yield {
577
541
  content: "",
578
542
  done: true,
@@ -599,10 +563,6 @@ var OpenAICompatibleProvider = class {
599
563
  * @returns true if the API key is valid, false otherwise
600
564
  */
601
565
  async validateApiKey(apiKey) {
602
- this.logger.debug(`Validating ${this.providerName} API connection`, {
603
- context: `${this.providerName}Provider.validateApiKey`,
604
- baseUrl: this.baseUrl
605
- });
606
566
  if (this.requireApiKey && !apiKey) {
607
567
  return false;
608
568
  }
@@ -612,9 +572,6 @@ var OpenAICompatibleProvider = class {
612
572
  baseURL: this.baseUrl
613
573
  });
614
574
  await client.models.list();
615
- this.logger.debug(`${this.providerName} API validation successful`, {
616
- context: `${this.providerName}Provider.validateApiKey`
617
- });
618
575
  return true;
619
576
  } catch (error) {
620
577
  this.logger.error(
@@ -632,10 +589,6 @@ var OpenAICompatibleProvider = class {
632
589
  * @returns Sorted array of model IDs, or empty array on failure
633
590
  */
634
591
  async getAvailableModels(apiKey) {
635
- this.logger.debug(`Fetching ${this.providerName} models`, {
636
- context: `${this.providerName}Provider.getAvailableModels`,
637
- baseUrl: this.baseUrl
638
- });
639
592
  if (this.requireApiKey && !apiKey) {
640
593
  this.logger.error(`${this.providerName} provider requires an API key to fetch models`, {
641
594
  context: `${this.providerName}Provider.getAvailableModels`
@@ -649,10 +602,6 @@ var OpenAICompatibleProvider = class {
649
602
  });
650
603
  const models = await client.models.list();
651
604
  const modelList = models.data.map((m) => m.id).sort();
652
- this.logger.debug(`Retrieved ${this.providerName} models`, {
653
- context: `${this.providerName}Provider.getAvailableModels`,
654
- modelCount: modelList.length
655
- });
656
605
  return modelList;
657
606
  } catch (error) {
658
607
  this.logger.error(
@@ -676,7 +625,7 @@ var OpenAICompatibleProvider = class {
676
625
 
677
626
  // src/roleplay-templates/builder.ts
678
627
  function createRoleplayTemplatePlugin(options) {
679
- const { metadata, templates, initialize, enableLogging = false } = options;
628
+ const { metadata, templates, initialize, enableLogging: _enableLogging = false } = options;
680
629
  const templateArray = Array.isArray(templates) ? templates : [templates];
681
630
  if (templateArray.length === 0) {
682
631
  throw new Error("At least one template is required");
@@ -699,21 +648,9 @@ function createRoleplayTemplatePlugin(options) {
699
648
  },
700
649
  templates: templateArray
701
650
  };
702
- if (initialize || enableLogging) {
651
+ if (initialize) {
703
652
  plugin.initialize = async () => {
704
- if (enableLogging) {
705
- const logger = createPluginLogger(metadata.templateId);
706
- logger.debug("Roleplay template plugin loaded", {
707
- context: "init",
708
- templateId: metadata.templateId,
709
- displayName: metadata.displayName,
710
- templateCount: templateArray.length,
711
- templateNames: templateArray.map((t) => t.name)
712
- });
713
- }
714
- if (initialize) {
715
- await initialize();
716
- }
653
+ await initialize();
717
654
  };
718
655
  }
719
656
  return plugin;
@@ -796,10 +733,24 @@ function validateRoleplayTemplatePlugin(plugin) {
796
733
  return true;
797
734
  }
798
735
 
736
+ // src/builtin-tools.ts
737
+ var BUILTIN_TOOL_NAMES = /* @__PURE__ */ new Set([
738
+ "generate_image",
739
+ "search_memories",
740
+ "search_web",
741
+ "project_info",
742
+ "file_management",
743
+ "request_full_context"
744
+ ]);
745
+ function getBuiltinToolNames() {
746
+ return new Set(BUILTIN_TOOL_NAMES);
747
+ }
748
+
799
749
  // src/index.ts
800
- var PLUGIN_UTILS_VERSION = "1.2.0";
750
+ var PLUGIN_UTILS_VERSION = "1.3.0";
801
751
  // Annotate the CommonJS export names for ESM import in node:
802
752
  0 && (module.exports = {
753
+ BUILTIN_TOOL_NAMES,
803
754
  OpenAICompatibleProvider,
804
755
  PLUGIN_UTILS_VERSION,
805
756
  __clearCoreLoggerFactory,
@@ -819,6 +770,7 @@ var PLUGIN_UTILS_VERSION = "1.2.0";
819
770
  createRoleplayTemplatePlugin,
820
771
  createSingleTemplatePlugin,
821
772
  detectToolCallFormat,
773
+ getBuiltinToolNames,
822
774
  getLogLevelFromEnv,
823
775
  hasCoreLogger,
824
776
  hasToolCalls,