@fragola-ai/prompt 1.0.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/README.md +207 -0
- package/dist/index.js +187 -0
- package/dist/index.js.map +7 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Prompt
|
|
2
|
+
|
|
3
|
+
The best way to work with and manage prompts in your code-base. Universal and library-agnostic, Prompt is compatible your favorite SDK such as Vercel's AI SDK, Openai SDK, langchain, Openai api and more
|
|
4
|
+
|
|
5
|
+
## ✨ Features
|
|
6
|
+
|
|
7
|
+
- 📝 **String Templates** - Create prompts from strings with simple variable syntax
|
|
8
|
+
- 🔄 **Variable Interpolation** - Dynamic content using `{{variable}}` syntax
|
|
9
|
+
- 📁 **File-based Prompts** - Load prompts from files for better organization
|
|
10
|
+
- 🗂️ **Path Aliasing** - Create shortcuts to frequently used prompt directories
|
|
11
|
+
- 🛡️ **Type Safety** - Built with TypeScript for type-safe variable handling
|
|
12
|
+
- 🔍 **Code Block Awareness** - Preserves code blocks in markdown
|
|
13
|
+
- ❌ **Error Handling** - Clear errors when variables are missing
|
|
14
|
+
- 🔌 **Universal** - Works with any LLM SDK or API
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install prompt
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
### Using with Strings
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import Prompt from 'prompt';
|
|
28
|
+
|
|
29
|
+
// Basic AI instruction template
|
|
30
|
+
const assistantTemplate = `You are a {{role}} assistant. Your task is to {{task}}.`;
|
|
31
|
+
const assistantPrompt = new Prompt(assistantTemplate, {
|
|
32
|
+
role: 'technical',
|
|
33
|
+
task: 'explain complex programming concepts in simple terms'
|
|
34
|
+
});
|
|
35
|
+
console.log(assistantPrompt.value);
|
|
36
|
+
// Output: You are a technical assistant. Your task is to explain complex programming concepts in simple terms.
|
|
37
|
+
|
|
38
|
+
// Complex prompt with context and examples
|
|
39
|
+
const codeReviewTemplate = `As a code reviewer, analyze the following {{language}} code:
|
|
40
|
+
{{codeSnippet}}
|
|
41
|
+
|
|
42
|
+
Consider these aspects:
|
|
43
|
+
- Code style and best practices
|
|
44
|
+
- Potential bugs or issues
|
|
45
|
+
- Performance implications
|
|
46
|
+
- Security concerns
|
|
47
|
+
|
|
48
|
+
Programming language: {{language}}
|
|
49
|
+
Experience level: {{experienceLevel}}`
|
|
50
|
+
|
|
51
|
+
const codeReviewPrompt = new Prompt(codeReviewTemplate, {
|
|
52
|
+
language: 'TypeScript',
|
|
53
|
+
codeSnippet: 'function add(a: number, b: number) { return a + b }',
|
|
54
|
+
experienceLevel: 'intermediate'
|
|
55
|
+
});
|
|
56
|
+
console.log(codeReviewPrompt.value);
|
|
57
|
+
// Output:
|
|
58
|
+
// As a code reviewer, analyze the following TypeScript code:
|
|
59
|
+
// function add(a: number, b: number) { return a + b }
|
|
60
|
+
//
|
|
61
|
+
// Consider these aspects:
|
|
62
|
+
// - Code style and best practices
|
|
63
|
+
// - Potential bugs or issues
|
|
64
|
+
// - Performance implications
|
|
65
|
+
// - Security concerns
|
|
66
|
+
//
|
|
67
|
+
// Programming language: TypeScript
|
|
68
|
+
// Experience level: intermediate
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Using with Files
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import Prompt, { load } from 'prompt';
|
|
75
|
+
|
|
76
|
+
// Content of prompts/shopBrowser.md:
|
|
77
|
+
/*
|
|
78
|
+
You are an AI shopping assistant helping customers browse products.
|
|
79
|
+
|
|
80
|
+
Customer Information:
|
|
81
|
+
- Name: {{customerName}}
|
|
82
|
+
- Previous purchases: {{previousPurchases}}
|
|
83
|
+
- Preferred categories: {{preferences}}
|
|
84
|
+
|
|
85
|
+
Available products in {{category}}:
|
|
86
|
+
{{productList}}
|
|
87
|
+
|
|
88
|
+
Task: Help the customer find products based on their preferences and purchase history.
|
|
89
|
+
Consider factors like:
|
|
90
|
+
1. Price range
|
|
91
|
+
2. Style preferences
|
|
92
|
+
3. Previous buying patterns
|
|
93
|
+
4. Current seasonal trends
|
|
94
|
+
|
|
95
|
+
Remember to maintain a helpful and professional tone.
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
// Load prompt from a file
|
|
99
|
+
const shoppingPrompt = new Prompt(load('./prompts/shopBrowser.md'), {
|
|
100
|
+
customerName: 'Sarah',
|
|
101
|
+
previousPurchases: ['Denim Jacket', 'Summer Dress'],
|
|
102
|
+
preferences: ['Casual Wear', 'Sustainable Fashion'],
|
|
103
|
+
category: 'Summer Collection',
|
|
104
|
+
productList: [
|
|
105
|
+
'Organic Cotton T-shirt',
|
|
106
|
+
'Linen Shorts',
|
|
107
|
+
'Bamboo Sundress'
|
|
108
|
+
]
|
|
109
|
+
});
|
|
110
|
+
console.log(shoppingPrompt.value);
|
|
111
|
+
// Output: (the content of shopBrowser.md with interpolated variables)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Using with Path Aliases
|
|
115
|
+
Aliases allows you to use prompt files from various location in your code-base with less overhead
|
|
116
|
+
```typescript
|
|
117
|
+
import Prompt, { load } from 'prompt';
|
|
118
|
+
|
|
119
|
+
// Define path aliases for frequently used directories
|
|
120
|
+
Prompt.pathAlias = {
|
|
121
|
+
chat: 'prompts/chat', // Maps to chat-related prompts
|
|
122
|
+
support: 'prompts/customer', // Maps to customer support prompts
|
|
123
|
+
system: 'prompts/system' // Maps to system-level prompts
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// You can use aliases in different ways:
|
|
127
|
+
|
|
128
|
+
// 1. Direct file access using an alias
|
|
129
|
+
const welcomePrompt = new Prompt(load('@chat/welcome.md'), {
|
|
130
|
+
username: 'Alice'
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// 2. Nested directory structure with an alias
|
|
134
|
+
const ticketPrompt = new Prompt(load('@support/tickets/create.md'), {
|
|
135
|
+
priority: 'high'
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
### Clone a prompt
|
|
139
|
+
You can clone an existing prompt's template and variables in two ways:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import Prompt from 'prompt';
|
|
143
|
+
|
|
144
|
+
// Basic AI instruction template
|
|
145
|
+
const assistantTemplate = `You are a {{role}} assistant. Your task is to {{task}}.`;
|
|
146
|
+
const assistantPrompt = new Prompt(assistantTemplate, {
|
|
147
|
+
role: 'technical',
|
|
148
|
+
task: 'explain complex programming concepts in simple terms'
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Complete clone - copies both template and variables
|
|
152
|
+
const completeClone = new Prompt(assistantPrompt.promptString, assistantPrompt.variables);
|
|
153
|
+
console.log(completeClone.value);
|
|
154
|
+
// Output: You are a technical assistant. Your task is to explain complex programming concepts in simple terms.
|
|
155
|
+
|
|
156
|
+
// Partial clone - reuses template with new variables
|
|
157
|
+
const partialClone = new Prompt(assistantPrompt.promptString, {
|
|
158
|
+
role: "bug-finder",
|
|
159
|
+
task: "find any logic flaws or bug in this code"
|
|
160
|
+
});
|
|
161
|
+
console.log(partialClone.value);
|
|
162
|
+
// Output: You are a bug-finder assistant. Your task is to find any logic flaws or bug in this code.
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## API Reference
|
|
166
|
+
|
|
167
|
+
### Static Properties
|
|
168
|
+
|
|
169
|
+
| Name | Type | Description |
|
|
170
|
+
|------|------|-------------|
|
|
171
|
+
| `pathAlias` | `Record<string, string>` | A map of aliases to file paths for shortcut access to prompt directories |
|
|
172
|
+
|
|
173
|
+
### Instance Properties
|
|
174
|
+
|
|
175
|
+
| Name | Type | Description |
|
|
176
|
+
|------|------|-------------|
|
|
177
|
+
| `promptString` | `string` | Gets the original unprocessed prompt template |
|
|
178
|
+
| `variables` | `Variables` | Gets the current variables map |
|
|
179
|
+
| `value` | `string` | Gets the interpolated prompt with all variables replaced |
|
|
180
|
+
|
|
181
|
+
### Outside of class functions
|
|
182
|
+
|
|
183
|
+
| Name | Params | Return Type | Description |
|
|
184
|
+
|------|--------|-------------|-------------|
|
|
185
|
+
| `load()` | `relativePath: string` | `Load` | Creates a Load object for file-based prompts. Path can include aliases starting with '@'. Can throw `NamespaceUndefinedError` when using an undefined alias |
|
|
186
|
+
|
|
187
|
+
### Instance Methods
|
|
188
|
+
|
|
189
|
+
| Name | Params | Return Type | Description |
|
|
190
|
+
|------|--------|-------------|-------------|
|
|
191
|
+
| `constructor()` | `prompt: string \| Load`<br>`variables?: Variables` | `Prompt` | Creates a new Prompt instance from string or file. Throws `LoadFileReadError` when file reading fails |
|
|
192
|
+
| `setVariables()` | `variables: Variables` | `void` | Updates the variables used for interpolation. Throws `MissingVariablesError` if required variables are missing |
|
|
193
|
+
|
|
194
|
+
### Types
|
|
195
|
+
|
|
196
|
+
| Name | Type | Description |
|
|
197
|
+
|------|------|-------------|
|
|
198
|
+
| `Variables` | `Record<string, any>` | Type for variable key-value pairs used in templates |
|
|
199
|
+
| `Load` | `{ load: true, relativePath: string }` | Configuration object for file-based prompts |
|
|
200
|
+
|
|
201
|
+
## Documentation
|
|
202
|
+
|
|
203
|
+
For detailed documentation and examples, visit our [GitHub repository](https://github.com/shadokan87/prompt).
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
MIT
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// Prompt.ts
|
|
8
|
+
var Prompt_exports = {};
|
|
9
|
+
__export(Prompt_exports, {
|
|
10
|
+
LoadFileReadError: () => LoadFileReadError,
|
|
11
|
+
MissingVariablesError: () => MissingVariablesError,
|
|
12
|
+
NamespaceUndefinedError: () => NamespaceUndefinedError,
|
|
13
|
+
default: () => Prompt,
|
|
14
|
+
load: () => load
|
|
15
|
+
});
|
|
16
|
+
import { readFileSync } from "fs";
|
|
17
|
+
import path from "path";
|
|
18
|
+
var MissingVariablesError = class extends Error {
|
|
19
|
+
constructor(variables, prompt) {
|
|
20
|
+
super(`Missing variables: ${variables.map((v) => `'${v}'`).join(", ")}. For prompt: ${prompt}`);
|
|
21
|
+
this.variables = variables;
|
|
22
|
+
this.name = "MissingVariablesError";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var NamespaceUndefinedError = class extends Error {
|
|
26
|
+
constructor(namespace) {
|
|
27
|
+
super(`Tried to acess undefined namespace when using load() function: '${namespace}' does not exist`);
|
|
28
|
+
this.namespace = namespace;
|
|
29
|
+
this.name = "NamespaceUndefinedError";
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var LoadFileReadError = class extends Error {
|
|
33
|
+
constructor(filePath, originalError) {
|
|
34
|
+
super(`Failed to load prompt from ${filePath}: ${originalError.message}`);
|
|
35
|
+
this.filePath = filePath;
|
|
36
|
+
this.originalError = originalError;
|
|
37
|
+
this.name = "LoadFileReadError";
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var load = (relativePath) => ({ load: true, relativePath });
|
|
41
|
+
var Prompt = class _Prompt {
|
|
42
|
+
static defaultVariableRegex = /\{\{(\s*[\w.]+\s*)\}\}/g;
|
|
43
|
+
/**
|
|
44
|
+
* A map of aliases to file paths for use with the {@link load} function.
|
|
45
|
+
* Allows defining shortcuts for commonly used prompt file paths.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* Prompt.pathAlias = {
|
|
50
|
+
* browse: "prompts", // Maps "@browse" to "prompts/"
|
|
51
|
+
* refund: "prompts/refund" // Maps "@refund" to "prompts/refund/"
|
|
52
|
+
* }
|
|
53
|
+
*
|
|
54
|
+
* // Usage with load():
|
|
55
|
+
* load("@refund/shopRefund.md") // Resolves to "prompts/refund/shopRefund.md"
|
|
56
|
+
* ```
|
|
57
|
+
* @see {@link load}
|
|
58
|
+
*/
|
|
59
|
+
static pathAlias = {};
|
|
60
|
+
#originalPrompt = "";
|
|
61
|
+
#value = "";
|
|
62
|
+
#variableRegex = _Prompt.defaultVariableRegex;
|
|
63
|
+
#variables = {};
|
|
64
|
+
#basePath = process.env["PWD"];
|
|
65
|
+
constructor(prompt, variables = {}) {
|
|
66
|
+
if (!process.env["PWD"])
|
|
67
|
+
console.warn("PWD env variable not set");
|
|
68
|
+
if (typeof prompt == "string") {
|
|
69
|
+
this.#originalPrompt = prompt;
|
|
70
|
+
this.#value = prompt;
|
|
71
|
+
} else {
|
|
72
|
+
this.#originalPrompt = this.#load(prompt.relativePath);
|
|
73
|
+
this.#value = this.#originalPrompt;
|
|
74
|
+
}
|
|
75
|
+
this.setVariables(variables);
|
|
76
|
+
}
|
|
77
|
+
#stringify(value) {
|
|
78
|
+
switch (typeof value) {
|
|
79
|
+
case "object":
|
|
80
|
+
return JSON.stringify(value);
|
|
81
|
+
default:
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
#isInsideCodeBlock(index, text) {
|
|
86
|
+
const codeBlockRegex = /```[\s\S]*?```/g;
|
|
87
|
+
let match;
|
|
88
|
+
while ((match = codeBlockRegex.exec(text)) !== null) {
|
|
89
|
+
const start = match.index;
|
|
90
|
+
const end = start + match[0].length;
|
|
91
|
+
if (index >= start && index < end) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Updates the variables used for string interpolation and re-processes the prompt template.
|
|
99
|
+
*
|
|
100
|
+
* @param variables - Your new variables
|
|
101
|
+
* @throws {MissingVariablesError} When required variables are not provided in the variables object
|
|
102
|
+
*/
|
|
103
|
+
setVariables(variables) {
|
|
104
|
+
this.#variables = variables;
|
|
105
|
+
const allMatch = Array.from(this.#originalPrompt.matchAll(this.#variableRegex)).filter((match) => !this.#isInsideCodeBlock(match.index, this.#originalPrompt)).map((match) => {
|
|
106
|
+
return {
|
|
107
|
+
placeholder: match[0],
|
|
108
|
+
index: match.index
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
const getVariableNameFromPlaceholder = (placeholder) => {
|
|
112
|
+
return placeholder.replaceAll(/[{}]/g, "").trim();
|
|
113
|
+
};
|
|
114
|
+
let missingVariables = [];
|
|
115
|
+
let applyReplace = [];
|
|
116
|
+
allMatch.forEach((match) => {
|
|
117
|
+
const variableName = getVariableNameFromPlaceholder(match.placeholder);
|
|
118
|
+
if (variableName in variables)
|
|
119
|
+
applyReplace.push(() => this.#value = this.#value.replace(match.placeholder, this.#stringify(this.#variables[variableName])));
|
|
120
|
+
else
|
|
121
|
+
missingVariables.push(variableName);
|
|
122
|
+
});
|
|
123
|
+
if (missingVariables.length)
|
|
124
|
+
throw new MissingVariablesError(missingVariables, this.#originalPrompt);
|
|
125
|
+
applyReplace.forEach((replace) => replace());
|
|
126
|
+
}
|
|
127
|
+
#load(relativePath) {
|
|
128
|
+
let _relativePath = (() => {
|
|
129
|
+
const split = relativePath.split("/");
|
|
130
|
+
if (split.length > 1) {
|
|
131
|
+
const namespace = split[0].trim();
|
|
132
|
+
if (namespace[0] == "@") {
|
|
133
|
+
const name = split[0].slice(1);
|
|
134
|
+
if (name in _Prompt.pathAlias) {
|
|
135
|
+
return path.join(_Prompt.pathAlias[name], split[1]);
|
|
136
|
+
} else
|
|
137
|
+
throw new NamespaceUndefinedError(namespace);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return relativePath;
|
|
141
|
+
})();
|
|
142
|
+
let fullPath = path.join(this.#basePath || "./", _relativePath);
|
|
143
|
+
if (!fullPath.split("/").at(-1)?.includes("."))
|
|
144
|
+
fullPath = `${fullPath}.md`;
|
|
145
|
+
try {
|
|
146
|
+
const content = readFileSync(fullPath, "utf-8");
|
|
147
|
+
return content;
|
|
148
|
+
} catch (error) {
|
|
149
|
+
if (error instanceof Error) {
|
|
150
|
+
throw new LoadFileReadError(fullPath, error);
|
|
151
|
+
}
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Gets the original prompt string used for this instance. Before any processing
|
|
157
|
+
* @returns {string} The original prompt string
|
|
158
|
+
*/
|
|
159
|
+
get promptString() {
|
|
160
|
+
return this.#originalPrompt;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Gets the variables currently in use for this prompt.
|
|
164
|
+
* @returns {Map<string, any>} A map containing the prompt variables and their values.
|
|
165
|
+
*/
|
|
166
|
+
get variables() {
|
|
167
|
+
return this.#variables;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Gets the interpolated value of the prompt.
|
|
171
|
+
* @returns {string} The resulting string after all variable interpolation has been applied.
|
|
172
|
+
*/
|
|
173
|
+
get value() {
|
|
174
|
+
return this.#value;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// index.ts
|
|
179
|
+
var index_default = Prompt_exports;
|
|
180
|
+
export {
|
|
181
|
+
LoadFileReadError,
|
|
182
|
+
MissingVariablesError,
|
|
183
|
+
NamespaceUndefinedError,
|
|
184
|
+
index_default as default,
|
|
185
|
+
load
|
|
186
|
+
};
|
|
187
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../Prompt.ts", "../index.ts"],
|
|
4
|
+
"sourcesContent": ["import { readFileSync } from \"fs\";\nimport path from \"path\";\n\n/**\n * Represents a record of variables used for string interpolation in prompts.\n * Each key in the record is a variable name to interpolate in the prompt template,\n * and its value can be any type (object, array, number, string, etc.) which will replace the placeholder.\n */\nexport type Variables = Record<string, any>;\n\nexport class MissingVariablesError extends Error {\n constructor(public variables: string[], prompt: string) {\n super(`Missing variables: ${variables.map(v => `'${v}'`).join(', ')}. For prompt: ${prompt}`);\n this.name = 'MissingVariablesError';\n }\n}\n\nexport class NamespaceUndefinedError extends Error {\n constructor(public namespace: string) {\n super(`Tried to acess undefined namespace when using load() function: '${namespace}' does not exist`)\n this.name = \"NamespaceUndefinedError\";\n }\n}\n\nexport class LoadFileReadError extends Error {\n constructor(public filePath: string, public originalError: Error) {\n super(`Failed to load prompt from ${filePath}: ${originalError.message}`);\n this.name = \"LoadFileReadError\";\n }\n}\n\nexport type Load = { load: true, relativePath: string };\n\n/**\n * Creates a Load object to specify a prompt file location.\n * This function is used when the prompt is located in a file system.\n * The process working directory (PWD) is used as the base path by default.\n * Path aliases can be used to reduce path overhead.\n * \n * @param {string} relativePath - The relative path to the prompt file. Can include path aliases.\n * @returns {Load} An object containing the load flag and the relative path to the prompt file\n * \n * @example\n * // Using relative path\n * load('./prompts/myPrompt.txt')\n * \n * @example\n * // Using path alias\n * load('prompts:myPrompt.txt')\n */\nexport const load = (relativePath: string): Load => ({ load: true, relativePath });\n\nexport default class Prompt {\n private static defaultVariableRegex = /\\{\\{(\\s*[\\w.]+\\s*)\\}\\}/g;\n /**\n * A map of aliases to file paths for use with the {@link load} function.\n * Allows defining shortcuts for commonly used prompt file paths.\n * \n * @example\n * ```typescript\n * Prompt.pathAlias = {\n * browse: \"prompts\", // Maps \"@browse\" to \"prompts/\"\n * refund: \"prompts/refund\" // Maps \"@refund\" to \"prompts/refund/\"\n * }\n * \n * // Usage with load():\n * load(\"@refund/shopRefund.md\") // Resolves to \"prompts/refund/shopRefund.md\"\n * ```\n * @see {@link load}\n */\n public static pathAlias: Record<string, string> = {};\n\n #originalPrompt: string = \"\";\n #value: string = \"\";\n #variableRegex: RegExp = Prompt.defaultVariableRegex;\n #variables: Variables = {};\n #basePath = process.env[\"PWD\"];\n\n constructor(prompt: string | Load, variables: Variables = {}) {\n if (!process.env[\"PWD\"])\n console.warn(\"PWD env variable not set\");\n if (typeof prompt == 'string') {\n this.#originalPrompt = prompt;\n this.#value = prompt;\n } else {\n this.#originalPrompt = this.#load(prompt.relativePath);\n this.#value = this.#originalPrompt;\n }\n this.setVariables(variables);\n }\n\n #stringify(value: any) {\n switch (typeof value) {\n case \"object\":\n return JSON.stringify(value);\n default:\n return value;\n }\n }\n\n #isInsideCodeBlock(index: number, text: string): boolean {\n const codeBlockRegex = /```[\\s\\S]*?```/g;\n let match;\n\n while ((match = codeBlockRegex.exec(text)) !== null) {\n const start = match.index;\n const end = start + match[0].length;\n\n if (index >= start && index < end) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Updates the variables used for string interpolation and re-processes the prompt template.\n * \n * @param variables - Your new variables\n * @throws {MissingVariablesError} When required variables are not provided in the variables object\n */\n setVariables(variables: Variables) {\n this.#variables = variables;\n const allMatch = Array.from(this.#originalPrompt.matchAll(this.#variableRegex))\n .filter(match => !this.#isInsideCodeBlock(match.index!, this.#originalPrompt))\n .map(match => {\n return {\n placeholder: match[0],\n index: match.index\n }\n });\n\n const getVariableNameFromPlaceholder = (placeholder: string) => {\n return placeholder.replaceAll(/[{}]/g, \"\").trim();\n }\n\n let missingVariables: string[] = [];\n let applyReplace: (() => {})[] = [];\n\n allMatch.forEach(match => {\n const variableName = getVariableNameFromPlaceholder(match.placeholder);\n if (variableName in variables)\n applyReplace.push(() => this.#value = this.#value.replace(match.placeholder, this.#stringify(this.#variables[variableName])));\n else\n missingVariables.push(variableName);\n });\n\n if (missingVariables.length)\n throw new MissingVariablesError(missingVariables, this.#originalPrompt);\n applyReplace.forEach(replace => replace());\n }\n\n #load(relativePath: string): string {\n let _relativePath = ((): string => {\n const split = relativePath.split(\"/\");\n if (split.length > 1) {\n const namespace = split[0].trim();\n if (namespace[0] == \"@\") {\n const name = split[0].slice(1);\n if (name in Prompt.pathAlias) {\n return path.join(Prompt.pathAlias[name], split[1]);\n } else\n throw new NamespaceUndefinedError(namespace);\n }\n }\n return relativePath;\n })();\n\n let fullPath = path.join(this.#basePath || \"./\", _relativePath);\n if (!fullPath.split(\"/\").at(-1)?.includes(\".\"))\n fullPath = `${fullPath}.md`;\n try {\n const content = readFileSync(fullPath, 'utf-8');\n return content;\n } catch (error) {\n if (error instanceof Error) {\n throw new LoadFileReadError(fullPath, error);\n }\n throw error;\n }\n }\n\n /**\n * Gets the original prompt string used for this instance. Before any processing\n * @returns {string} The original prompt string\n */\n get promptString() {\n return this.#originalPrompt;\n }\n\n /**\n * Gets the variables currently in use for this prompt.\n * @returns {Map<string, any>} A map containing the prompt variables and their values.\n */\n get variables() {\n return this.#variables;\n }\n\n /**\n * Gets the interpolated value of the prompt.\n * @returns {string} The resulting string after all variable interpolation has been applied.\n */\n get value() {\n return this.#value;\n }\n}", "import * as PromptModule from \"./Prompt\";\nexport * from \"./Prompt\";\nexport default PromptModule;\n"],
|
|
5
|
+
"mappings": ";;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,oBAAoB;AAC7B,OAAO,UAAU;AASV,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAC7C,YAAmB,WAAqB,QAAgB;AACpD,UAAM,sBAAsB,UAAU,IAAI,OAAK,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,iBAAiB,MAAM,EAAE;AAD7E;AAEf,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,IAAM,0BAAN,cAAsC,MAAM;AAAA,EAC/C,YAAmB,WAAmB;AAClC,UAAM,mEAAmE,SAAS,kBAAkB;AADrF;AAEf,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EACzC,YAAmB,UAAyB,eAAsB;AAC9D,UAAM,8BAA8B,QAAQ,KAAK,cAAc,OAAO,EAAE;AADzD;AAAyB;AAExC,SAAK,OAAO;AAAA,EAChB;AACJ;AAqBO,IAAM,OAAO,CAAC,kBAAgC,EAAE,MAAM,MAAM,aAAa;AAEhF,IAAqB,SAArB,MAAqB,QAAO;AAAA,EACxB,OAAe,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBtC,OAAc,YAAoC,CAAC;AAAA,EAEnD,kBAA0B;AAAA,EAC1B,SAAiB;AAAA,EACjB,iBAAyB,QAAO;AAAA,EAChC,aAAwB,CAAC;AAAA,EACzB,YAAY,QAAQ,IAAI,KAAK;AAAA,EAE7B,YAAY,QAAuB,YAAuB,CAAC,GAAG;AAC1D,QAAI,CAAC,QAAQ,IAAI,KAAK;AAClB,cAAQ,KAAK,0BAA0B;AAC3C,QAAI,OAAO,UAAU,UAAU;AAC3B,WAAK,kBAAkB;AACvB,WAAK,SAAS;AAAA,IAClB,OAAO;AACH,WAAK,kBAAkB,KAAK,MAAM,OAAO,YAAY;AACrD,WAAK,SAAS,KAAK;AAAA,IACvB;AACA,SAAK,aAAa,SAAS;AAAA,EAC/B;AAAA,EAEA,WAAW,OAAY;AACnB,YAAQ,OAAO,OAAO;AAAA,MAClB,KAAK;AACD,eAAO,KAAK,UAAU,KAAK;AAAA,MAC/B;AACI,eAAO;AAAA,IACf;AAAA,EACJ;AAAA,EAEA,mBAAmB,OAAe,MAAuB;AACrD,UAAM,iBAAiB;AACvB,QAAI;AAEJ,YAAQ,QAAQ,eAAe,KAAK,IAAI,OAAO,MAAM;AACjD,YAAM,QAAQ,MAAM;AACpB,YAAM,MAAM,QAAQ,MAAM,CAAC,EAAE;AAE7B,UAAI,SAAS,SAAS,QAAQ,KAAK;AAC/B,eAAO;AAAA,MACX;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,WAAsB;AAC/B,SAAK,aAAa;AAClB,UAAM,WAAW,MAAM,KAAK,KAAK,gBAAgB,SAAS,KAAK,cAAc,CAAC,EACzE,OAAO,WAAS,CAAC,KAAK,mBAAmB,MAAM,OAAQ,KAAK,eAAe,CAAC,EAC5E,IAAI,WAAS;AACV,aAAO;AAAA,QACH,aAAa,MAAM,CAAC;AAAA,QACpB,OAAO,MAAM;AAAA,MACjB;AAAA,IACJ,CAAC;AAEL,UAAM,iCAAiC,CAAC,gBAAwB;AAC5D,aAAO,YAAY,WAAW,SAAS,EAAE,EAAE,KAAK;AAAA,IACpD;AAEA,QAAI,mBAA6B,CAAC;AAClC,QAAI,eAA6B,CAAC;AAElC,aAAS,QAAQ,WAAS;AACtB,YAAM,eAAe,+BAA+B,MAAM,WAAW;AACrE,UAAI,gBAAgB;AAChB,qBAAa,KAAK,MAAM,KAAK,SAAS,KAAK,OAAO,QAAQ,MAAM,aAAa,KAAK,WAAW,KAAK,WAAW,YAAY,CAAC,CAAC,CAAC;AAAA;AAE5H,yBAAiB,KAAK,YAAY;AAAA,IAC1C,CAAC;AAED,QAAI,iBAAiB;AACjB,YAAM,IAAI,sBAAsB,kBAAkB,KAAK,eAAe;AAC1E,iBAAa,QAAQ,aAAW,QAAQ,CAAC;AAAA,EAC7C;AAAA,EAEA,MAAM,cAA8B;AAChC,QAAI,iBAAiB,MAAc;AAC/B,YAAM,QAAQ,aAAa,MAAM,GAAG;AACpC,UAAI,MAAM,SAAS,GAAG;AAClB,cAAM,YAAY,MAAM,CAAC,EAAE,KAAK;AAChC,YAAI,UAAU,CAAC,KAAK,KAAK;AACrB,gBAAM,OAAO,MAAM,CAAC,EAAE,MAAM,CAAC;AAC7B,cAAI,QAAQ,QAAO,WAAW;AAC1B,mBAAO,KAAK,KAAK,QAAO,UAAU,IAAI,GAAG,MAAM,CAAC,CAAC;AAAA,UACrD;AACI,kBAAM,IAAI,wBAAwB,SAAS;AAAA,QACnD;AAAA,MACJ;AACA,aAAO;AAAA,IACX,GAAG;AAEH,QAAI,WAAW,KAAK,KAAK,KAAK,aAAa,MAAM,aAAa;AAC9D,QAAI,CAAC,SAAS,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,SAAS,GAAG;AACzC,iBAAW,GAAG,QAAQ;AAC1B,QAAI;AACA,YAAM,UAAU,aAAa,UAAU,OAAO;AAC9C,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,UAAI,iBAAiB,OAAO;AACxB,cAAM,IAAI,kBAAkB,UAAU,KAAK;AAAA,MAC/C;AACA,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,eAAe;AACf,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,YAAY;AACZ,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,QAAQ;AACR,WAAO,KAAK;AAAA,EAChB;AACJ;;;AC5MA,IAAO,gBAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fragola-ai/prompt",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Prompt interpolation and loading library for Node.js/TypeScript.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"type": "module",
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "node build.js",
|
|
21
|
+
"prepublishOnly": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/bun": "latest",
|
|
28
|
+
"esbuild": "^0.25.9"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"typescript": "^5.0.0"
|
|
32
|
+
},
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/shadokan87/prompt.git"
|
|
36
|
+
},
|
|
37
|
+
"author": "shadokan87",
|
|
38
|
+
"license": "MIT"
|
|
39
|
+
}
|