@mate-academy/llm-gateway 2.1.4 → 2.1.5

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/README.md CHANGED
@@ -424,12 +424,14 @@ Interface for converting text to speech audio.
424
424
 
425
425
  ### Prompt Builder
426
426
 
427
- The LLM Gateway includes a powerful prompt template system that provides type-safe string templates with dynamic replacements. This allows you to create reusable prompt templates with placeholders that can be replaced with actual values at runtime.
427
+ The LLM Gateway includes a powerful prompt template system that provides type-safe string templates with dynamic replacements and conditional sections. This allows you to create reusable prompt templates with placeholders that can be replaced with actual values at runtime.
428
428
 
429
429
  #### Features
430
430
 
431
431
  - **Type Safety**: Automatic extraction and validation of placeholder keys from template strings
432
432
  - **Dynamic Replacements**: Replace placeholders like `{{variableName}}` with actual values
433
+ - **Conditional Sections**: Show or hide content based on variable values using `{{#condition}}...{{/condition}}` syntax
434
+ - **Nested Conditionals**: Support for nested conditional sections for complex logic
433
435
  - **Template Reusability**: Create templates once and use them multiple times with different values
434
436
  - **Zero Runtime Dependencies**: Pure TypeScript utility functions
435
437
 
@@ -454,6 +456,74 @@ const instruction = welcomePrompt({
454
456
  // Result: "Generate a welcome message for a user who has just started their auto tech check attempt on JavaScript Basics. The user's experience level is beginner and they prefer hands-on learning."
455
457
  ```
456
458
 
459
+ #### Conditional Sections
460
+
461
+ Conditional sections allow you to show or hide parts of the template based on variable values:
462
+
463
+ ```typescript
464
+ // Template with conditional sections
465
+ const coursePrompt = createPromptTemplate(`
466
+ Generate a lesson plan for {{topicTitle}}.
467
+ {{#hasPrerequisites}}
468
+ Prerequisites: {{prerequisites}}
469
+ {{/hasPrerequisites}}
470
+
471
+ {{#includeExercises}}
472
+ Include practical exercises and code examples.
473
+ {{/includeExercises}}
474
+
475
+ {{#difficultyLevel}}
476
+ Adjust content for {{difficultyLevel}} level students.
477
+ {{/difficultyLevel}}
478
+ `);
479
+
480
+ // Usage with all sections visible
481
+ const fullLesson = coursePrompt({
482
+ topicTitle: 'React Hooks',
483
+ hasPrerequisites: true,
484
+ prerequisites: 'Basic React knowledge',
485
+ includeExercises: true,
486
+ difficultyLevel: 'intermediate'
487
+ });
488
+
489
+ // Usage with some sections hidden
490
+ const basicLesson = coursePrompt({
491
+ topicTitle: 'React Hooks',
492
+ hasPrerequisites: false,
493
+ includeExercises: false,
494
+ difficultyLevel: 'beginner'
495
+ });
496
+ ```
497
+
498
+ #### Nested Conditional Sections
499
+
500
+ You can nest conditional sections for more complex logic:
501
+
502
+ ```typescript
503
+ const reviewPrompt = createPromptTemplate(`
504
+ Review the {{language}} code for {{focusArea}}.
505
+ {{#includeMetrics}}
506
+ Provide performance metrics.
507
+ {{#includeDetailed}}
508
+ Include detailed benchmark analysis and memory usage patterns.
509
+ {{/includeDetailed}}
510
+ {{/includeMetrics}}
511
+
512
+ {{#suggestImprovements}}
513
+ Suggest specific improvements for better {{improvementFocus}}.
514
+ {{/suggestImprovements}}
515
+ `);
516
+
517
+ const detailedReview = reviewPrompt({
518
+ language: 'TypeScript',
519
+ focusArea: 'performance',
520
+ includeMetrics: true,
521
+ includeDetailed: true,
522
+ suggestImprovements: true,
523
+ improvementFocus: 'scalability'
524
+ });
525
+ ```
526
+
457
527
  #### Advanced Usage
458
528
 
459
529
  ```typescript
@@ -463,21 +533,32 @@ const staticPrompt = createPromptTemplate(`
463
533
  `);
464
534
  const staticInstruction = staticPrompt(); // No parameters needed
465
535
 
466
- // Template with multiple placeholders
536
+ // Template with multiple placeholders and conditional sections
467
537
  const codeReviewPrompt = createPromptTemplate(`
468
538
  Review the {{language}} code below for {{focusArea}}.
539
+ {{#includeCriteria}}
469
540
  Pay special attention to {{criteria}} and provide {{outputFormat}} feedback.
541
+ {{/includeCriteria}}
470
542
 
543
+ {{#includeCode}}
471
544
  Code:
472
545
  {{codeSnippet}}
546
+ {{/includeCode}}
547
+
548
+ {{#provideExamples}}
549
+ Include examples of best practices for {{language}}.
550
+ {{/provideExamples}}
473
551
  `);
474
552
 
475
553
  const reviewInstruction = codeReviewPrompt({
476
554
  language: 'TypeScript',
477
555
  focusArea: 'performance optimization',
556
+ includeCriteria: true,
478
557
  criteria: 'algorithmic efficiency and memory usage',
479
558
  outputFormat: 'structured',
559
+ includeCode: true,
480
560
  codeSnippet: 'function example() { /* code here */ }',
561
+ provideExamples: false
481
562
  });
482
563
  ```
483
564
 
@@ -495,32 +576,58 @@ import {
495
576
  const PROMPTS = {
496
577
  codeExplanation: createPromptTemplate(`
497
578
  Explain the following {{language}} code in simple terms for a {{level}} developer:
579
+ {{#includeContext}}
580
+ Context: {{context}}
581
+ {{/includeContext}}
582
+
498
583
  {{code}}
584
+
585
+ {{#includeExamples}}
586
+ Provide practical examples of how this code would be used.
587
+ {{/includeExamples}}
499
588
  `),
500
589
 
501
590
  bugFinding: createPromptTemplate(`
502
591
  Find potential bugs in this {{language}} code and suggest fixes:
592
+ {{#focusArea}}
593
+ Focus specifically on {{focusArea}} issues.
594
+ {{/focusArea}}
595
+
503
596
  {{code}}
597
+
598
+ {{#includeSeverity}}
599
+ Rate the severity of each issue from 1-5.
600
+ {{/includeSeverity}}
504
601
  `),
505
602
 
506
603
  optimization: createPromptTemplate(`
507
604
  Optimize the following code for {{optimizationType}}:
508
605
  {{code}}
606
+
607
+ {{#includeMetrics}}
608
+ Provide before/after performance metrics.
609
+ {{/includeMetrics}}
610
+
611
+ {{#includeAlternatives}}
612
+ Suggest alternative approaches and explain trade-offs.
613
+ {{/includeAlternatives}}
509
614
  `),
510
615
  };
511
616
 
512
617
  // Use with completion service
513
- async function explainCode(code: string, language: string, level: string) {
618
+ async function explainCode(code: string, language: string, level: string, includeExamples = false) {
514
619
  const prompt = PROMPTS.codeExplanation({
515
620
  code,
516
621
  language,
517
622
  level,
623
+ includeContext: false,
624
+ includeExamples,
518
625
  });
519
626
 
520
627
  return await completionService.sendMessage({
521
628
  message: {
522
629
  role: LLMRoles.User,
523
- content: [prompt],
630
+ content: [{ type: LLMMessageContentType.TEXT, text: prompt }],
524
631
  },
525
632
  model: preferredModel,
526
633
  });
@@ -529,20 +636,41 @@ async function explainCode(code: string, language: string, level: string) {
529
636
 
530
637
  #### Type Safety Features
531
638
 
532
- The prompt builder provides compile-time type checking for template placeholders:
639
+ The prompt builder provides compile-time type checking for template placeholders and conditional sections:
533
640
 
534
641
  ```typescript
535
642
  // This will show TypeScript errors for missing or incorrect parameters
536
- const template = createPromptTemplate(`Hello {{name}}, welcome to {{platform}}!`);
643
+ const template = createPromptTemplate(`
644
+ Hello {{name}}, welcome to {{platform}}!
645
+ {{#showBonus}}You have a bonus: {{bonusAmount}}{{/showBonus}}
646
+ `);
537
647
 
538
- // ✅ Correct usage
539
- template({ name: 'John', platform: 'LLM Gateway' });
648
+ // ✅ Correct usage with all required variables
649
+ template({
650
+ name: 'John',
651
+ platform: 'LLM Gateway',
652
+ showBonus: true,
653
+ bonusAmount: '$50'
654
+ });
655
+
656
+ // ✅ Correct usage with conditional section hidden
657
+ template({
658
+ name: 'John',
659
+ platform: 'LLM Gateway',
660
+ showBonus: false
661
+ // bonusAmount is not required when showBonus is false
662
+ });
540
663
 
541
664
  // ❌ TypeScript error: missing required parameter 'platform'
542
- template({ name: 'John' });
665
+ template({ name: 'John', showBonus: false });
543
666
 
544
667
  // ❌ TypeScript error: unknown parameter 'age'
545
- template({ name: 'John', platform: 'LLM Gateway', age: 25 });
668
+ template({
669
+ name: 'John',
670
+ platform: 'LLM Gateway',
671
+ showBonus: false,
672
+ age: 25
673
+ });
546
674
  ```
547
675
 
548
676
  #### API Reference
@@ -552,16 +680,30 @@ template({ name: 'John', platform: 'LLM Gateway', age: 25 });
552
680
  Creates a prompt template function from a template string.
553
681
 
554
682
  - **Parameters:**
555
- - `template: T` - The template string with placeholders in `{{variableName}}` format
683
+ - `template: T` - The template string with placeholders and conditional sections
556
684
  - **Returns:** A function that accepts replacement values and returns the processed string
557
- - **Type Safety:** Automatically extracts placeholder names from the template string for type checking
685
+ - **Type Safety:** Automatically extracts placeholder names and conditional section names from the template string for type checking
558
686
 
559
- **Template Placeholder Format**
687
+ **Template Syntax**
560
688
 
689
+ **Variable Placeholders:**
561
690
  - Placeholders must be enclosed in double curly braces: `{{variableName}}`
562
691
  - Whitespace around variable names is ignored: `{{ variableName }}` works the same as `{{variableName}}`
563
692
  - Variable names can contain letters, numbers, and underscores
564
- - Replacement values can be strings or numbers (automatically converted to strings)
693
+ - Replacement values can be strings, numbers, or booleans (automatically converted to strings)
694
+
695
+ **Conditional Sections:**
696
+ - Conditional sections use the syntax: `{{#conditionName}}content{{/conditionName}}`
697
+ - The section content is included only if the condition variable is truthy
698
+ - Truthy values: `true`, non-empty strings, non-zero numbers
699
+ - Falsy values: `false`, empty strings, `0`, `null`, `undefined`
700
+ - Conditional variables are optional in the type system when used only as conditions
701
+ - Variables used both as conditions and values are required in the type system
702
+
703
+ **Nested Conditionals:**
704
+ - Conditional sections can be nested for complex logic
705
+ - Inner sections are processed only if outer sections are visible
706
+ - Variables inside nested sections follow the same truthy/falsy rules
565
707
 
566
708
  ## Supported Providers
567
709
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Utility types and functions for handling prompts with dynamic replacements.
2
+ * Utility types and functions for handling prompts with dynamic replacements and conditional sections.
3
3
  * This allows for type-safe string templates with placeholders that can be replaced with actual values.
4
4
  * The `createPromptTemplate` function helps create typed prompts with automatic extraction of replacement keys.
5
5
  *
@@ -9,20 +9,41 @@
9
9
  * const PROMPTS = {
10
10
  * welcomeMessage: createPromptTemplate(`
11
11
  * Generate a welcome message for a user who has just started their auto tech check attempt on {{topicTitle}}.
12
+ * {{#hasBonus}}
13
+ * This topic includes bonus content: {{bonusContent}}
14
+ * {{/hasBonus}}
15
+ *
16
+ * {{#valueAsCondition}}
17
+ * This is a conditional section that will only appear if the value is truthy.
18
+ * Value can be used inside the section: {{valueAsCondition}}
19
+ * {{/valueAsCondition}}
12
20
  * `),
13
21
  * };
14
22
  *
15
- * const instruction = PROMPTS.welcomeMessage({ topicTitle: 'JavaScript Basics' });
23
+ * const instruction = PROMPTS.welcomeMessage({
24
+ * topicTitle: 'JavaScript Basics',
25
+ * hasBonus: true,
26
+ * bonusContent: 'Advanced debugging techniques',
27
+ * });
16
28
  *
17
29
  * // This will generate a prompt:
18
- * // "Generate a welcome message for a user who has just started their auto tech check attempt on JavaScript Basics."
30
+ * // "Generate a welcome message for a user who has just started their auto tech check attempt on JavaScript Basics.
31
+ * // This topic includes bonus content: Advanced debugging techniques"
19
32
  */
20
- type ExtractReplacements<T extends string> = T extends `${string}{{${infer Key}}}${infer Rest}` ? Key extends `${infer CleanKey}` ? CleanKey | ExtractReplacements<Rest> : never : never;
33
+ type Value = string | number | boolean;
34
+ type ExtractAllVariables<T extends string> = T extends `${string}{{${infer Key}}}${infer Rest}` ? Key extends `${infer CleanKey}` ? CleanKey | ExtractAllVariables<Rest> : never : never;
35
+ type ExtractSectionVariables<T extends string> = T extends `${string}{{#${infer Key}}}${infer Rest}` ? Key | ExtractSectionVariables<Rest> : T extends `${string}{{/${infer Key}}}${infer Rest}` ? Key | ExtractSectionVariables<Rest> : never;
36
+ type ExtractRegularVariables<T extends string> = ExtractAllVariables<T> extends infer All ? All extends string ? All extends `#${string}` | `/${string}` ? never : All : never : never;
37
+ type CreateVariableRecord<T extends string> = ExtractRegularVariables<T> extends never ? ExtractSectionVariables<T> extends never ? Record<string, never> : Record<ExtractSectionVariables<T>, Value> : ExtractSectionVariables<T> extends never ? Record<ExtractRegularVariables<T>, Value> : Omit<Record<ExtractRegularVariables<T>, Value>, ExtractSectionVariables<T>> & Partial<Record<ExtractSectionVariables<T>, Value>>;
38
+ type HasVariables<T extends string> = ExtractAllVariables<T> extends never ? false : true;
21
39
  /**
22
- * Creates a prompt template function that can be used to generate prompts with dynamic replacements.
40
+ * Creates a prompt template function that can be used to generate prompts with dynamic replacements and conditional sections.
23
41
  * @template T The type of the template string. Inferred from the provided template.
24
- * @param {T} template The template string with placeholders for dynamic values (e.g., `{{topicTitle}}`).
42
+ * @param {T} template The template string with placeholders:
43
+ * - for dynamic values (e.g., `{{topicTitle}}`)
44
+ * - for conditional sections (e.g., `{{#section}}...{{/section}}`)
45
+ * - for sections that use conditional variables as values (e.g., `{{#bonus}}...{{bonus}}...{{/bonus}}`)
25
46
  * @returns A function that takes the dynamic values and returns the generated prompt.
26
47
  */
27
- export declare function createPromptTemplate<T extends string>(template: T): (...args: ExtractReplacements<T> extends never ? [] : [variables: Record<ExtractReplacements<T>, string | number>]) => string;
48
+ export declare function createPromptTemplate<T extends string>(template: T): (...args: HasVariables<T> extends false ? [] : [variables: CreateVariableRecord<T>]) => string;
28
49
  export {};
@@ -1 +1 @@
1
- "use strict";function promptBuilder(e,t){return t?Object.entries(t).reduce((e,[t,r])=>e.replace(new RegExp(`{{\\s*${t}\\s*}}`,"g"),String(r)),e):e}function createPromptTemplate(e){const t=e.trim();return(...e)=>promptBuilder(t,...e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.createPromptTemplate=createPromptTemplate;
1
+ "use strict";function promptBuilder(e,t){if(!t)return e;const r=e=>Object.entries(t).reduce((e,[t,r])=>e.replace(new RegExp(`{{\\s*${t}\\s*}}`,"g"),String(r)),e),n=e=>e.replace(/{{#(\w+)}}([\s\S]*?){{\/\1}}/g,(e,p,c)=>{if(t[p]){const e=n(c);return r(e)}return""});let p=e;return p=n(p),p=r(p),p}function createPromptTemplate(e){const t=e.trim();return(...e)=>promptBuilder(t,...e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.createPromptTemplate=createPromptTemplate;
@@ -1 +1 @@
1
- {"version":3,"file":"promptBuilder.js","sourceRoot":"","sources":["../src/promptBuilder.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;AA2CH,oDAQC;AA1BD,SAAS,aAAa,CACpB,MAAc,EACd,SAA2C;IAE3C,OAAO,SAAS;QACd,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,CAChC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,GAAG,QAAQ,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EACxF,MAAM,CACP;QACD,CAAC,CAAC,MAAM,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAmB,QAAW;IAChE,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,EAAO,CAAC;IAE7C,OAAO,CACL,GAAG,IAE6D,EACxD,EAAE,CAAC,aAAa,CAAC,eAAe,EAAE,GAAG,IAAI,CAAC,CAAC;AACvD,CAAC"}
1
+ {"version":3,"file":"promptBuilder.js","sourceRoot":"","sources":["../src/promptBuilder.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;;AAoHH,oDAQC;AA1DD,SAAS,aAAa,CACpB,MAAc,EACd,SAAiC;IAEjC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,gBAAgB,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC;IACnD,+DAA+D;IAC/D,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CACtD,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,GAAG,QAAQ,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAClE,EAAE,MAAM,CAAC,CACX,CAAC;IAEF,MAAM,0BAA0B,GAAG,CAAC,MAAc,EAAU,EAAE;QAC5D,qEAAqE;QACrE,OAAO,MAAM,CAAC,OAAO,CAAC,+BAA+B,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE;YACjF,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;YAErC,IAAI,KAAK,EAAE,CAAC;gBACV,6EAA6E;gBAC7E,MAAM,gBAAgB,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;gBAC7D,OAAO,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;YAC5C,CAAC;YAED,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,IAAI,MAAM,GAAG,MAAM,CAAC;IAEpB,mFAAmF;IACnF,MAAM,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAE5C,6CAA6C;IAC7C,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,oBAAoB,CAAmB,QAAW;IAChE,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,EAAO,CAAC;IAE7C,OAAO,CACL,GAAG,IAEqC,EAChC,EAAE,CAAC,aAAa,CAAC,eAAe,EAAE,GAAG,IAAI,CAAC,CAAC;AACvD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mate-academy/llm-gateway",
3
- "version": "2.1.4",
3
+ "version": "2.1.5",
4
4
  "description": "A gateway package for LLM services.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",