@promptbook/core 0.100.0-4 → 0.100.0-41
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 +1 -0
- package/esm/index.es.js +2444 -321
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/components.index.d.ts +14 -0
- package/esm/typings/src/_packages/core.index.d.ts +26 -0
- package/esm/typings/src/_packages/types.index.d.ts +34 -0
- package/esm/typings/src/book-2.0/agent-source/parseAgentSource.d.ts +30 -0
- package/esm/typings/src/book-2.0/agent-source/parseAgentSource.test.d.ts +1 -0
- package/esm/typings/src/book-2.0/agent-source/string_book.d.ts +26 -0
- package/esm/typings/src/book-2.0/commitments/ACTION/ACTION.d.ts +38 -0
- package/esm/typings/src/book-2.0/commitments/FORMAT/FORMAT.d.ts +39 -0
- package/esm/typings/src/book-2.0/commitments/KNOWLEDGE/FrontendRAGService.d.ts +48 -0
- package/esm/typings/src/book-2.0/commitments/KNOWLEDGE/KNOWLEDGE.d.ts +51 -0
- package/esm/typings/src/book-2.0/commitments/KNOWLEDGE/RAGService.d.ts +54 -0
- package/esm/typings/src/book-2.0/commitments/KNOWLEDGE/processors/BaseKnowledgeProcessor.d.ts +45 -0
- package/esm/typings/src/book-2.0/commitments/KNOWLEDGE/processors/PdfProcessor.d.ts +31 -0
- package/esm/typings/src/book-2.0/commitments/KNOWLEDGE/processors/ProcessorFactory.d.ts +23 -0
- package/esm/typings/src/book-2.0/commitments/KNOWLEDGE/processors/TextProcessor.d.ts +18 -0
- package/esm/typings/src/book-2.0/commitments/KNOWLEDGE/types.d.ts +56 -0
- package/esm/typings/src/book-2.0/commitments/KNOWLEDGE/utils/ragHelper.d.ts +34 -0
- package/esm/typings/src/book-2.0/commitments/META_IMAGE/META_IMAGE.d.ts +44 -0
- package/esm/typings/src/book-2.0/commitments/META_LINK/META_LINK.d.ts +56 -0
- package/esm/typings/src/book-2.0/commitments/MODEL/MODEL.d.ts +39 -0
- package/esm/typings/src/book-2.0/commitments/NOTE/NOTE.d.ts +49 -0
- package/esm/typings/src/book-2.0/commitments/PERSONA/PERSONA.d.ts +46 -0
- package/esm/typings/src/book-2.0/commitments/RULE/RULE.d.ts +44 -0
- package/esm/typings/src/book-2.0/commitments/SAMPLE/SAMPLE.d.ts +44 -0
- package/esm/typings/src/book-2.0/commitments/STYLE/STYLE.d.ts +38 -0
- package/esm/typings/src/book-2.0/commitments/_base/BaseCommitmentDefinition.d.ts +52 -0
- package/esm/typings/src/book-2.0/commitments/_base/BookCommitment.d.ts +5 -0
- package/esm/typings/src/book-2.0/commitments/_base/CommitmentDefinition.d.ts +48 -0
- package/esm/typings/src/book-2.0/commitments/_base/NotYetImplementedCommitmentDefinition.d.ts +22 -0
- package/esm/typings/src/book-2.0/commitments/_base/createEmptyAgentModelRequirements.d.ts +19 -0
- package/esm/typings/src/book-2.0/commitments/_misc/AgentModelRequirements.d.ts +37 -0
- package/esm/typings/src/book-2.0/commitments/_misc/AgentSourceParseResult.d.ts +18 -0
- package/esm/typings/src/book-2.0/commitments/_misc/ParsedCommitment.d.ts +22 -0
- package/esm/typings/src/book-2.0/commitments/_misc/createAgentModelRequirements.d.ts +61 -0
- package/esm/typings/src/book-2.0/commitments/_misc/createAgentModelRequirementsWithCommitments.d.ts +35 -0
- package/esm/typings/src/book-2.0/commitments/_misc/createCommitmentRegex.d.ts +20 -0
- package/esm/typings/src/book-2.0/commitments/_misc/parseAgentSourceWithCommitments.d.ts +24 -0
- package/esm/typings/src/book-2.0/commitments/_misc/removeCommentsFromSystemMessage.d.ts +11 -0
- package/esm/typings/src/book-2.0/commitments/index.d.ts +56 -0
- package/esm/typings/src/book-2.0/utils/profileImageUtils.d.ts +39 -0
- package/esm/typings/src/book-components/AvatarProfile/AvatarChip/AvatarChip.d.ts +35 -0
- package/esm/typings/src/book-components/AvatarProfile/AvatarChip/AvatarChipFromSource.d.ts +21 -0
- package/esm/typings/src/book-components/AvatarProfile/AvatarChip/index.d.ts +2 -0
- package/esm/typings/src/book-components/BookEditor/BookEditor.d.ts +35 -0
- package/esm/typings/src/book-components/BookEditor/config.d.ts +10 -0
- package/esm/typings/src/book-components/BookEditor/injectCssModuleIntoShadowRoot.d.ts +11 -0
- package/esm/typings/src/book-components/_common/react-utils/classNames.d.ts +7 -0
- package/esm/typings/src/book-components/_common/react-utils/collectCssTextsForClass.d.ts +7 -0
- package/esm/typings/src/book-components/_common/react-utils/escapeHtml.d.ts +6 -0
- package/esm/typings/src/book-components/_common/react-utils/escapeRegex.d.ts +6 -0
- package/esm/typings/src/config.d.ts +6 -0
- package/esm/typings/src/execution/AvailableModel.d.ts +4 -0
- package/esm/typings/src/execution/ExecutionTask.d.ts +27 -0
- package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +6 -1
- package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +0 -5
- package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/deepseek/deepseek-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/google/google-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/ollama/ollama-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/openai-models.d.ts +1 -1
- package/esm/typings/src/pipeline/book-notation.d.ts +2 -1
- package/esm/typings/src/types/ModelRequirements.d.ts +0 -2
- package/esm/typings/src/types/typeAliases.d.ts +6 -0
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +2341 -205
- package/umd/index.umd.js.map +1 -1
package/esm/index.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import spaceTrim, { spaceTrim
|
|
1
|
+
import spaceTrim$1, { spaceTrim } from 'spacetrim';
|
|
2
2
|
import { format } from 'prettier';
|
|
3
3
|
import parserHtml from 'prettier/parser-html';
|
|
4
4
|
import { randomBytes } from 'crypto';
|
|
@@ -27,136 +27,342 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
27
27
|
* @generated
|
|
28
28
|
* @see https://github.com/webgptorg/promptbook
|
|
29
29
|
*/
|
|
30
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.100.0-
|
|
30
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.100.0-41';
|
|
31
31
|
/**
|
|
32
32
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
33
33
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
37
|
+
* Extracts profile image URL from agent definition text and returns cleaned system message
|
|
38
|
+
* @param systemMessage The original system message that may contain META IMAGE line
|
|
39
|
+
* @returns Object with profileImageUrl (if found) and cleanedSystemMessage (without META IMAGE line)
|
|
38
40
|
*
|
|
39
|
-
*
|
|
41
|
+
* @private - TODO: [🧠] Maybe should be public?
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* Generates a gravatar URL based on agent name for fallback avatar
|
|
45
|
+
* @param name The agent name to generate avatar for
|
|
46
|
+
* @returns Gravatar URL
|
|
40
47
|
*
|
|
41
|
-
* @
|
|
48
|
+
* @private - TODO: [🧠] Maybe should be public?
|
|
42
49
|
*/
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
50
|
+
function generateGravatarUrl(name) {
|
|
51
|
+
// Use a default name if none provided
|
|
52
|
+
const safeName = name || 'Anonymous Agent';
|
|
53
|
+
// Create a simple hash from the name for consistent avatar
|
|
54
|
+
let hash = 0;
|
|
55
|
+
for (let i = 0; i < safeName.length; i++) {
|
|
56
|
+
const char = safeName.charCodeAt(i);
|
|
57
|
+
hash = (hash << 5) - hash + char;
|
|
58
|
+
hash = hash & hash; // Convert to 32bit integer
|
|
59
|
+
}
|
|
60
|
+
const avatarId = Math.abs(hash).toString();
|
|
61
|
+
return `https://www.gravatar.com/avatar/${avatarId}?default=robohash&size=200&rating=x`;
|
|
47
62
|
}
|
|
48
63
|
/**
|
|
49
|
-
*
|
|
64
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
50
65
|
*/
|
|
51
66
|
|
|
52
67
|
/**
|
|
53
|
-
*
|
|
68
|
+
* Freezes the given object and all its nested objects recursively
|
|
69
|
+
*
|
|
70
|
+
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
71
|
+
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
54
72
|
*
|
|
73
|
+
* @returns The same object as the input, but deeply frozen
|
|
55
74
|
* @public exported from `@promptbook/utils`
|
|
56
75
|
*/
|
|
57
|
-
function
|
|
58
|
-
if (
|
|
59
|
-
return
|
|
76
|
+
function $deepFreeze(objectValue) {
|
|
77
|
+
if (Array.isArray(objectValue)) {
|
|
78
|
+
return Object.freeze(objectValue.map((item) => $deepFreeze(item)));
|
|
60
79
|
}
|
|
61
|
-
|
|
62
|
-
|
|
80
|
+
const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
81
|
+
for (const propertyName of propertyNames) {
|
|
82
|
+
const value = objectValue[propertyName];
|
|
83
|
+
if (value && typeof value === 'object') {
|
|
84
|
+
$deepFreeze(value);
|
|
85
|
+
}
|
|
63
86
|
}
|
|
64
|
-
|
|
87
|
+
Object.freeze(objectValue);
|
|
88
|
+
return objectValue;
|
|
65
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
92
|
+
*/
|
|
66
93
|
|
|
67
94
|
/**
|
|
68
|
-
*
|
|
95
|
+
* Generates a regex pattern to match a specific commitment
|
|
69
96
|
*
|
|
70
|
-
* Note:
|
|
71
|
-
*
|
|
97
|
+
* Note: It always creates new Regex object
|
|
98
|
+
* Note: Uses word boundaries to ensure only full words are matched (e.g., "PERSONA" matches but "PERSONALITY" does not)
|
|
99
|
+
*
|
|
100
|
+
* @private
|
|
72
101
|
*/
|
|
73
|
-
function
|
|
74
|
-
|
|
75
|
-
|
|
102
|
+
function createCommitmentRegex(commitment) {
|
|
103
|
+
const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
104
|
+
const keywordPattern = escapedCommitment.split(/\s+/).join('\\s+');
|
|
105
|
+
const regex = new RegExp(`^\\s*(?<type>${keywordPattern})\\b\\s+(?<contents>.+)$`, 'gim');
|
|
106
|
+
return regex;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Generates a regex pattern to match a specific commitment type
|
|
110
|
+
*
|
|
111
|
+
* Note: It just matches the type part of the commitment
|
|
112
|
+
* Note: It always creates new Regex object
|
|
113
|
+
* Note: Uses word boundaries to ensure only full words are matched (e.g., "PERSONA" matches but "PERSONALITY" does not)
|
|
114
|
+
*
|
|
115
|
+
* @private
|
|
116
|
+
*/
|
|
117
|
+
function createCommitmentTypeRegex(commitment) {
|
|
118
|
+
const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
119
|
+
const keywordPattern = escapedCommitment.split(/\s+/).join('\\s+');
|
|
120
|
+
const regex = new RegExp(`^\\s*(?<type>${keywordPattern})\\b`, 'gim');
|
|
121
|
+
return regex;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Base implementation of CommitmentDefinition that provides common functionality
|
|
126
|
+
* Most commitments can extend this class and only override the applyToAgentModelRequirements method
|
|
127
|
+
*
|
|
128
|
+
* @private
|
|
129
|
+
*/
|
|
130
|
+
class BaseCommitmentDefinition {
|
|
131
|
+
constructor(type) {
|
|
132
|
+
this.type = type;
|
|
76
133
|
}
|
|
77
|
-
|
|
78
|
-
|
|
134
|
+
/**
|
|
135
|
+
* Creates a regex pattern to match this commitment in agent source
|
|
136
|
+
* Uses the existing createCommitmentRegex function as internal helper
|
|
137
|
+
*/
|
|
138
|
+
createRegex() {
|
|
139
|
+
return createCommitmentRegex(this.type);
|
|
79
140
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Creates a regex pattern to match just the commitment type
|
|
143
|
+
* Uses the existing createCommitmentTypeRegex function as internal helper
|
|
144
|
+
*/
|
|
145
|
+
createTypeRegex() {
|
|
146
|
+
return createCommitmentTypeRegex(this.type);
|
|
83
147
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
148
|
+
/**
|
|
149
|
+
* Helper method to create a new requirements object with updated system message
|
|
150
|
+
* This is commonly used by many commitments
|
|
151
|
+
*/
|
|
152
|
+
updateSystemMessage(requirements, messageUpdate) {
|
|
153
|
+
const newMessage = typeof messageUpdate === 'string' ? messageUpdate : messageUpdate(requirements.systemMessage);
|
|
154
|
+
return {
|
|
155
|
+
...requirements,
|
|
156
|
+
systemMessage: newMessage,
|
|
157
|
+
};
|
|
89
158
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Helper method to append content to the system message
|
|
161
|
+
*/
|
|
162
|
+
appendToSystemMessage(requirements, content, separator = '\n\n') {
|
|
163
|
+
return this.updateSystemMessage(requirements, (currentMessage) => {
|
|
164
|
+
if (!currentMessage.trim()) {
|
|
165
|
+
return content;
|
|
166
|
+
}
|
|
167
|
+
return currentMessage + separator + content;
|
|
168
|
+
});
|
|
94
169
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Helper method to add a comment section to the system message
|
|
172
|
+
* Comments are lines starting with # that will be removed from the final system message
|
|
173
|
+
* but can be useful for organizing and structuring the message during processing
|
|
174
|
+
*/
|
|
175
|
+
addCommentSection(requirements, commentTitle, content, position = 'end') {
|
|
176
|
+
const commentSection = `# ${commentTitle.toUpperCase()}\n${content}`;
|
|
177
|
+
if (position === 'beginning') {
|
|
178
|
+
return this.updateSystemMessage(requirements, (currentMessage) => {
|
|
179
|
+
if (!currentMessage.trim()) {
|
|
180
|
+
return commentSection;
|
|
181
|
+
}
|
|
182
|
+
return commentSection + '\n\n' + currentMessage;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
return this.appendToSystemMessage(requirements, commentSection);
|
|
187
|
+
}
|
|
99
188
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* ACTION commitment definition
|
|
193
|
+
*
|
|
194
|
+
* The ACTION commitment defines specific actions or capabilities that the agent can perform.
|
|
195
|
+
* This helps define what the agent is capable of doing and how it should approach tasks.
|
|
196
|
+
*
|
|
197
|
+
* Example usage in agent source:
|
|
198
|
+
*
|
|
199
|
+
* ```book
|
|
200
|
+
* ACTION Can generate code snippets and explain programming concepts
|
|
201
|
+
* ACTION Able to analyze data and provide insights
|
|
202
|
+
* ```
|
|
203
|
+
*
|
|
204
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
205
|
+
*/
|
|
206
|
+
class ActionCommitmentDefinition extends BaseCommitmentDefinition {
|
|
207
|
+
constructor() {
|
|
208
|
+
super('ACTION');
|
|
104
209
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
210
|
+
/**
|
|
211
|
+
* Short one-line description of ACTION.
|
|
212
|
+
*/
|
|
213
|
+
get description() {
|
|
214
|
+
return 'Define agent capabilities and actions it can perform.';
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Markdown documentation for ACTION commitment.
|
|
218
|
+
*/
|
|
219
|
+
get documentation() {
|
|
220
|
+
return spaceTrim(`
|
|
221
|
+
# ACTION
|
|
222
|
+
|
|
223
|
+
Defines specific actions or capabilities that the agent can perform.
|
|
224
|
+
|
|
225
|
+
## Key behaviors
|
|
226
|
+
|
|
227
|
+
- Multiple \`ACTION\` commitments are applied sequentially.
|
|
228
|
+
- Each action adds to the agent's capability list.
|
|
229
|
+
- Actions help users understand what the agent can do.
|
|
230
|
+
|
|
231
|
+
## Examples
|
|
232
|
+
|
|
233
|
+
\`\`\`book
|
|
234
|
+
Code Assistant
|
|
235
|
+
|
|
236
|
+
PERSONA You are a programming assistant
|
|
237
|
+
ACTION Can generate code snippets and explain programming concepts
|
|
238
|
+
ACTION Able to debug existing code and suggest improvements
|
|
239
|
+
ACTION Can create unit tests for functions
|
|
240
|
+
\`\`\`
|
|
241
|
+
|
|
242
|
+
\`\`\`book
|
|
243
|
+
Data Scientist
|
|
244
|
+
|
|
245
|
+
PERSONA You are a data analysis expert
|
|
246
|
+
ACTION Able to analyze data and provide insights
|
|
247
|
+
ACTION Can create visualizations and charts
|
|
248
|
+
ACTION Capable of statistical analysis and modeling
|
|
249
|
+
KNOWLEDGE Data analysis best practices and statistical methods
|
|
250
|
+
\`\`\`
|
|
251
|
+
`);
|
|
252
|
+
}
|
|
253
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
254
|
+
const trimmedContent = content.trim();
|
|
255
|
+
if (!trimmedContent) {
|
|
256
|
+
return requirements;
|
|
257
|
+
}
|
|
258
|
+
// Add action capability to the system message
|
|
259
|
+
const actionSection = `Capability: ${trimmedContent}`;
|
|
260
|
+
return this.appendToSystemMessage(requirements, actionSection, '\n\n');
|
|
109
261
|
}
|
|
110
|
-
return false;
|
|
111
262
|
}
|
|
112
263
|
/**
|
|
113
|
-
*
|
|
264
|
+
* Singleton instance of the ACTION commitment definition
|
|
265
|
+
*
|
|
266
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
267
|
+
*/
|
|
268
|
+
new ActionCommitmentDefinition();
|
|
269
|
+
/**
|
|
270
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
114
271
|
*/
|
|
115
272
|
|
|
116
273
|
/**
|
|
117
|
-
*
|
|
274
|
+
* FORMAT commitment definition
|
|
118
275
|
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
|
|
276
|
+
* The FORMAT commitment defines the specific output structure and formatting
|
|
277
|
+
* that the agent should use in its responses. This includes data formats,
|
|
278
|
+
* response templates, and structural requirements.
|
|
123
279
|
*
|
|
124
|
-
*
|
|
280
|
+
* Example usage in agent source:
|
|
281
|
+
*
|
|
282
|
+
* ```book
|
|
283
|
+
* FORMAT Always respond in JSON format with 'status' and 'data' fields
|
|
284
|
+
* FORMAT Use markdown formatting for all code blocks
|
|
285
|
+
* ```
|
|
286
|
+
*
|
|
287
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
125
288
|
*/
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
289
|
+
class FormatCommitmentDefinition extends BaseCommitmentDefinition {
|
|
290
|
+
constructor() {
|
|
291
|
+
super('FORMAT');
|
|
129
292
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {
|
|
136
|
-
return false;
|
|
137
|
-
}
|
|
138
|
-
return true;
|
|
293
|
+
/**
|
|
294
|
+
* Short one-line description of FORMAT.
|
|
295
|
+
*/
|
|
296
|
+
get description() {
|
|
297
|
+
return 'Specify output structure or formatting requirements.';
|
|
139
298
|
}
|
|
140
|
-
|
|
141
|
-
|
|
299
|
+
/**
|
|
300
|
+
* Markdown documentation for FORMAT commitment.
|
|
301
|
+
*/
|
|
302
|
+
get documentation() {
|
|
303
|
+
return spaceTrim(`
|
|
304
|
+
# FORMAT
|
|
305
|
+
|
|
306
|
+
Defines the specific output structure and formatting for responses (data formats, templates, structure).
|
|
307
|
+
|
|
308
|
+
## Key behaviors
|
|
309
|
+
|
|
310
|
+
- Multiple \`FORMAT\` commitments are applied sequentially.
|
|
311
|
+
- If they are in conflict, the last one takes precedence.
|
|
312
|
+
- You can specify both data formats and presentation styles.
|
|
313
|
+
|
|
314
|
+
## Examples
|
|
315
|
+
|
|
316
|
+
\`\`\`book
|
|
317
|
+
Customer Support Bot
|
|
318
|
+
|
|
319
|
+
PERSONA You are a helpful customer support agent
|
|
320
|
+
FORMAT Always respond in JSON format with 'status' and 'data' fields
|
|
321
|
+
FORMAT Use markdown formatting for all code blocks
|
|
322
|
+
\`\`\`
|
|
323
|
+
|
|
324
|
+
\`\`\`book
|
|
325
|
+
Data Analyst
|
|
326
|
+
|
|
327
|
+
PERSONA You are a data analysis expert
|
|
328
|
+
FORMAT Present results in structured tables
|
|
329
|
+
FORMAT Include confidence scores for all predictions
|
|
330
|
+
STYLE Be concise and precise in explanations
|
|
331
|
+
\`\`\`
|
|
332
|
+
`);
|
|
333
|
+
}
|
|
334
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
335
|
+
const trimmedContent = content.trim();
|
|
336
|
+
if (!trimmedContent) {
|
|
337
|
+
return requirements;
|
|
338
|
+
}
|
|
339
|
+
// Add format instructions to the system message
|
|
340
|
+
const formatSection = `Output Format: ${trimmedContent}`;
|
|
341
|
+
return this.appendToSystemMessage(requirements, formatSection, '\n\n');
|
|
142
342
|
}
|
|
143
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* Singleton instance of the FORMAT commitment definition
|
|
346
|
+
*
|
|
347
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
348
|
+
*/
|
|
349
|
+
new FormatCommitmentDefinition();
|
|
350
|
+
/**
|
|
351
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
352
|
+
*/
|
|
144
353
|
|
|
145
354
|
/**
|
|
146
|
-
*
|
|
355
|
+
* Error thrown when a fetch request fails
|
|
147
356
|
*
|
|
148
357
|
* @public exported from `@promptbook/core`
|
|
149
358
|
*/
|
|
150
|
-
class
|
|
359
|
+
class PromptbookFetchError extends Error {
|
|
151
360
|
constructor(message) {
|
|
152
361
|
super(message);
|
|
153
|
-
this.name = '
|
|
154
|
-
Object.setPrototypeOf(this,
|
|
362
|
+
this.name = 'PromptbookFetchError';
|
|
363
|
+
Object.setPrototypeOf(this, PromptbookFetchError.prototype);
|
|
155
364
|
}
|
|
156
365
|
}
|
|
157
|
-
/**
|
|
158
|
-
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
159
|
-
*/
|
|
160
366
|
|
|
161
367
|
/**
|
|
162
368
|
* Available remote servers for the Promptbook
|
|
@@ -480,6 +686,12 @@ function SET_IS_VERBOSE(isVerbose) {
|
|
|
480
686
|
* @public exported from `@promptbook/core`
|
|
481
687
|
*/
|
|
482
688
|
const DEFAULT_IS_AUTO_INSTALLED = false;
|
|
689
|
+
/**
|
|
690
|
+
* Default simulated duration for a task in milliseconds (used for progress reporting)
|
|
691
|
+
*
|
|
692
|
+
* @public exported from `@promptbook/core`
|
|
693
|
+
*/
|
|
694
|
+
const DEFAULT_TASK_SIMULATED_DURATION_MS = 5 * 60 * 1000; // 5 minutes
|
|
483
695
|
/**
|
|
484
696
|
* Function name for generated function via `ptbk make` to get the pipeline collection
|
|
485
697
|
*
|
|
@@ -516,7 +728,7 @@ true);
|
|
|
516
728
|
function getErrorReportUrl(error) {
|
|
517
729
|
const report = {
|
|
518
730
|
title: `🐜 Error report from ${NAME}`,
|
|
519
|
-
body: spaceTrim((block) => `
|
|
731
|
+
body: spaceTrim$1((block) => `
|
|
520
732
|
|
|
521
733
|
|
|
522
734
|
\`${error.name || 'Error'}\` has occurred in the [${NAME}], please look into it @${ADMIN_GITHUB_NAME}.
|
|
@@ -559,7 +771,7 @@ function getErrorReportUrl(error) {
|
|
|
559
771
|
*/
|
|
560
772
|
class UnexpectedError extends Error {
|
|
561
773
|
constructor(message) {
|
|
562
|
-
super(spaceTrim
|
|
774
|
+
super(spaceTrim((block) => `
|
|
563
775
|
${block(message)}
|
|
564
776
|
|
|
565
777
|
Note: This error should not happen.
|
|
@@ -585,7 +797,7 @@ class WrappedError extends Error {
|
|
|
585
797
|
constructor(whatWasThrown) {
|
|
586
798
|
const tag = `[🤮]`;
|
|
587
799
|
console.error(tag, whatWasThrown);
|
|
588
|
-
super(spaceTrim
|
|
800
|
+
super(spaceTrim(`
|
|
589
801
|
Non-Error object was thrown
|
|
590
802
|
|
|
591
803
|
Note: Look for ${tag} in the console for more details
|
|
@@ -611,18 +823,1849 @@ function assertsError(whatWasThrown) {
|
|
|
611
823
|
const wrappedError = whatWasThrown;
|
|
612
824
|
throw wrappedError;
|
|
613
825
|
}
|
|
614
|
-
// Case 2: Handle unexpected errors
|
|
615
|
-
if (whatWasThrown instanceof UnexpectedError) {
|
|
616
|
-
const unexpectedError = whatWasThrown;
|
|
617
|
-
throw unexpectedError;
|
|
826
|
+
// Case 2: Handle unexpected errors
|
|
827
|
+
if (whatWasThrown instanceof UnexpectedError) {
|
|
828
|
+
const unexpectedError = whatWasThrown;
|
|
829
|
+
throw unexpectedError;
|
|
830
|
+
}
|
|
831
|
+
// Case 3: Handle standard errors - keep them up to consumer
|
|
832
|
+
if (whatWasThrown instanceof Error) {
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
// Case 4: Handle non-standard errors - wrap them into `WrappedError` and throw
|
|
836
|
+
throw new WrappedError(whatWasThrown);
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* The built-in `fetch' function with a lightweight error handling wrapper as default fetch function used in Promptbook scrapers
|
|
841
|
+
*
|
|
842
|
+
* @public exported from `@promptbook/core`
|
|
843
|
+
*/
|
|
844
|
+
const promptbookFetch = async (urlOrRequest, init) => {
|
|
845
|
+
try {
|
|
846
|
+
return await fetch(urlOrRequest, init);
|
|
847
|
+
}
|
|
848
|
+
catch (error) {
|
|
849
|
+
assertsError(error);
|
|
850
|
+
let url;
|
|
851
|
+
if (typeof urlOrRequest === 'string') {
|
|
852
|
+
url = urlOrRequest;
|
|
853
|
+
}
|
|
854
|
+
else if (urlOrRequest instanceof Request) {
|
|
855
|
+
url = urlOrRequest.url;
|
|
856
|
+
}
|
|
857
|
+
throw new PromptbookFetchError(spaceTrim$1((block) => `
|
|
858
|
+
Can not fetch "${url}"
|
|
859
|
+
|
|
860
|
+
Fetch error:
|
|
861
|
+
${block(error.message)}
|
|
862
|
+
|
|
863
|
+
`));
|
|
864
|
+
}
|
|
865
|
+
};
|
|
866
|
+
/**
|
|
867
|
+
* TODO: [🧠] Maybe rename because it is not used only for scrapers but also in `$getCompiledBook`
|
|
868
|
+
*/
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* Frontend RAG Service that uses backend APIs for processing
|
|
872
|
+
* This avoids Node.js dependencies in the frontend
|
|
873
|
+
*
|
|
874
|
+
* @private - TODO: [🧠] Maybe should be public?
|
|
875
|
+
*/
|
|
876
|
+
class FrontendRAGService {
|
|
877
|
+
constructor(config) {
|
|
878
|
+
this.chunks = [];
|
|
879
|
+
this.sources = [];
|
|
880
|
+
this.isInitialized = false;
|
|
881
|
+
this.config = {
|
|
882
|
+
maxChunkSize: 1000,
|
|
883
|
+
chunkOverlap: 200,
|
|
884
|
+
maxRetrievedChunks: 5,
|
|
885
|
+
minRelevanceScore: 0.1,
|
|
886
|
+
...config,
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Initialize knowledge sources by processing them on the backend
|
|
891
|
+
*/
|
|
892
|
+
async initializeKnowledgeSources(sources) {
|
|
893
|
+
if (sources.length === 0) {
|
|
894
|
+
this.isInitialized = true;
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
try {
|
|
898
|
+
const response = await promptbookFetch('/api/knowledge/process-sources', {
|
|
899
|
+
method: 'POST',
|
|
900
|
+
headers: {
|
|
901
|
+
'Content-Type': 'application/json',
|
|
902
|
+
},
|
|
903
|
+
body: JSON.stringify({
|
|
904
|
+
sources,
|
|
905
|
+
config: {
|
|
906
|
+
maxChunkSize: this.config.maxChunkSize,
|
|
907
|
+
chunkOverlap: this.config.chunkOverlap,
|
|
908
|
+
},
|
|
909
|
+
}),
|
|
910
|
+
});
|
|
911
|
+
if (!response.ok) {
|
|
912
|
+
throw new Error(`Failed to process knowledge sources: ${response.status}`);
|
|
913
|
+
}
|
|
914
|
+
const result = (await response.json());
|
|
915
|
+
if (!result.success) {
|
|
916
|
+
throw new Error(result.message || 'Failed to process knowledge sources');
|
|
917
|
+
}
|
|
918
|
+
this.chunks = result.chunks;
|
|
919
|
+
this.sources = sources;
|
|
920
|
+
this.isInitialized = true;
|
|
921
|
+
console.log(`Initialized RAG service with ${this.chunks.length} chunks from ${sources.length} sources`);
|
|
922
|
+
}
|
|
923
|
+
catch (error) {
|
|
924
|
+
console.error('Failed to initialize knowledge sources:', error);
|
|
925
|
+
// Don't throw - allow the system to continue without RAG
|
|
926
|
+
this.isInitialized = true;
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Get relevant context for a user query
|
|
931
|
+
*/
|
|
932
|
+
async getContextForQuery(query) {
|
|
933
|
+
if (!this.isInitialized) {
|
|
934
|
+
console.warn('RAG service not initialized');
|
|
935
|
+
return '';
|
|
936
|
+
}
|
|
937
|
+
if (this.chunks.length === 0) {
|
|
938
|
+
return '';
|
|
939
|
+
}
|
|
940
|
+
try {
|
|
941
|
+
const response = await promptbookFetch('/api/knowledge/retrieve-context', {
|
|
942
|
+
method: 'POST',
|
|
943
|
+
headers: {
|
|
944
|
+
'Content-Type': 'application/json',
|
|
945
|
+
},
|
|
946
|
+
body: JSON.stringify({
|
|
947
|
+
query,
|
|
948
|
+
chunks: this.chunks,
|
|
949
|
+
config: {
|
|
950
|
+
maxRetrievedChunks: this.config.maxRetrievedChunks,
|
|
951
|
+
minRelevanceScore: this.config.minRelevanceScore,
|
|
952
|
+
},
|
|
953
|
+
}),
|
|
954
|
+
});
|
|
955
|
+
if (!response.ok) {
|
|
956
|
+
console.error(`Failed to retrieve context: ${response.status}`);
|
|
957
|
+
return '';
|
|
958
|
+
}
|
|
959
|
+
const result = (await response.json());
|
|
960
|
+
if (!result.success) {
|
|
961
|
+
console.error('Context retrieval failed:', result.message);
|
|
962
|
+
return '';
|
|
963
|
+
}
|
|
964
|
+
return result.context;
|
|
965
|
+
}
|
|
966
|
+
catch (error) {
|
|
967
|
+
console.error('Error retrieving context:', error);
|
|
968
|
+
return '';
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Get relevant chunks for a query (for debugging/inspection)
|
|
973
|
+
*/
|
|
974
|
+
async getRelevantChunks(query) {
|
|
975
|
+
if (!this.isInitialized || this.chunks.length === 0) {
|
|
976
|
+
return [];
|
|
977
|
+
}
|
|
978
|
+
try {
|
|
979
|
+
const response = await promptbookFetch('/api/knowledge/retrieve-context', {
|
|
980
|
+
method: 'POST',
|
|
981
|
+
headers: {
|
|
982
|
+
'Content-Type': 'application/json',
|
|
983
|
+
},
|
|
984
|
+
body: JSON.stringify({
|
|
985
|
+
query,
|
|
986
|
+
chunks: this.chunks,
|
|
987
|
+
config: {
|
|
988
|
+
maxRetrievedChunks: this.config.maxRetrievedChunks,
|
|
989
|
+
minRelevanceScore: this.config.minRelevanceScore,
|
|
990
|
+
},
|
|
991
|
+
}),
|
|
992
|
+
});
|
|
993
|
+
if (!response.ok) {
|
|
994
|
+
return [];
|
|
995
|
+
}
|
|
996
|
+
const result = (await response.json());
|
|
997
|
+
return result.success ? result.relevantChunks : [];
|
|
998
|
+
}
|
|
999
|
+
catch (error) {
|
|
1000
|
+
console.error('Error retrieving relevant chunks:', error);
|
|
1001
|
+
return [];
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Get knowledge base statistics
|
|
1006
|
+
*/
|
|
1007
|
+
getStats() {
|
|
1008
|
+
return {
|
|
1009
|
+
sources: this.sources.length,
|
|
1010
|
+
chunks: this.chunks.length,
|
|
1011
|
+
isInitialized: this.isInitialized,
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Check if the service is ready to use
|
|
1016
|
+
*/
|
|
1017
|
+
isReady() {
|
|
1018
|
+
return this.isInitialized;
|
|
1019
|
+
}
|
|
1020
|
+
/**
|
|
1021
|
+
* Clear all knowledge sources
|
|
1022
|
+
*/
|
|
1023
|
+
clearKnowledgeBase() {
|
|
1024
|
+
this.chunks = [];
|
|
1025
|
+
this.sources = [];
|
|
1026
|
+
this.isInitialized = false;
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Add a single knowledge source (for incremental updates)
|
|
1030
|
+
*/
|
|
1031
|
+
async addKnowledgeSource(url) {
|
|
1032
|
+
if (this.sources.includes(url)) {
|
|
1033
|
+
console.log(`Knowledge source already exists: ${url}`);
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
try {
|
|
1037
|
+
const response = await promptbookFetch('/api/knowledge/process-sources', {
|
|
1038
|
+
method: 'POST',
|
|
1039
|
+
headers: {
|
|
1040
|
+
'Content-Type': 'application/json',
|
|
1041
|
+
},
|
|
1042
|
+
body: JSON.stringify({
|
|
1043
|
+
sources: [url],
|
|
1044
|
+
config: {
|
|
1045
|
+
maxChunkSize: this.config.maxChunkSize,
|
|
1046
|
+
chunkOverlap: this.config.chunkOverlap,
|
|
1047
|
+
},
|
|
1048
|
+
}),
|
|
1049
|
+
});
|
|
1050
|
+
if (!response.ok) {
|
|
1051
|
+
throw new Error(`Failed to process knowledge source: ${response.status}`);
|
|
1052
|
+
}
|
|
1053
|
+
const result = (await response.json());
|
|
1054
|
+
if (!result.success) {
|
|
1055
|
+
throw new Error(result.message || 'Failed to process knowledge source');
|
|
1056
|
+
}
|
|
1057
|
+
// Add new chunks to existing ones
|
|
1058
|
+
this.chunks.push(...result.chunks);
|
|
1059
|
+
this.sources.push(url);
|
|
1060
|
+
console.log(`Added knowledge source: ${url} (${result.chunks.length} chunks)`);
|
|
1061
|
+
}
|
|
1062
|
+
catch (error) {
|
|
1063
|
+
console.error(`Failed to add knowledge source ${url}:`, error);
|
|
1064
|
+
throw error;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* KNOWLEDGE commitment definition
|
|
1071
|
+
*
|
|
1072
|
+
* The KNOWLEDGE commitment adds specific knowledge, facts, or context to the agent
|
|
1073
|
+
* using RAG (Retrieval-Augmented Generation) approach for external sources.
|
|
1074
|
+
*
|
|
1075
|
+
* Supports both direct text knowledge and external sources like PDFs.
|
|
1076
|
+
*
|
|
1077
|
+
* Example usage in agent source:
|
|
1078
|
+
*
|
|
1079
|
+
* ```book
|
|
1080
|
+
* KNOWLEDGE The company was founded in 2020 and specializes in AI-powered solutions
|
|
1081
|
+
* KNOWLEDGE https://example.com/company-handbook.pdf
|
|
1082
|
+
* KNOWLEDGE https://example.com/product-documentation.pdf
|
|
1083
|
+
* ```
|
|
1084
|
+
*
|
|
1085
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1086
|
+
*/
|
|
1087
|
+
class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
|
|
1088
|
+
constructor() {
|
|
1089
|
+
super('KNOWLEDGE');
|
|
1090
|
+
this.ragService = new FrontendRAGService();
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Short one-line description of KNOWLEDGE.
|
|
1094
|
+
*/
|
|
1095
|
+
get description() {
|
|
1096
|
+
return 'Add domain **knowledge** via direct text or external sources (RAG).';
|
|
1097
|
+
}
|
|
1098
|
+
/**
|
|
1099
|
+
* Markdown documentation for KNOWLEDGE commitment.
|
|
1100
|
+
*/
|
|
1101
|
+
get documentation() {
|
|
1102
|
+
return spaceTrim(`
|
|
1103
|
+
# KNOWLEDGE
|
|
1104
|
+
|
|
1105
|
+
Adds specific knowledge, facts, or context to the agent using a RAG (Retrieval-Augmented Generation) approach for external sources.
|
|
1106
|
+
|
|
1107
|
+
## Key behaviors
|
|
1108
|
+
|
|
1109
|
+
- Multiple \`KNOWLEDGE\` commitments are applied sequentially.
|
|
1110
|
+
- Supports both direct text knowledge and external URLs.
|
|
1111
|
+
- External sources (PDFs, websites) are processed via RAG for context retrieval.
|
|
1112
|
+
|
|
1113
|
+
## Supported formats
|
|
1114
|
+
|
|
1115
|
+
- Direct text: Immediate knowledge incorporated into agent
|
|
1116
|
+
- URLs: External documents processed for contextual retrieval
|
|
1117
|
+
- Supported file types: PDF, text, markdown, HTML
|
|
1118
|
+
|
|
1119
|
+
## Examples
|
|
1120
|
+
|
|
1121
|
+
\`\`\`book
|
|
1122
|
+
Customer Support Bot
|
|
1123
|
+
|
|
1124
|
+
PERSONA You are a helpful customer support agent for TechCorp
|
|
1125
|
+
KNOWLEDGE TechCorp was founded in 2020 and specializes in AI-powered solutions
|
|
1126
|
+
KNOWLEDGE https://example.com/company-handbook.pdf
|
|
1127
|
+
KNOWLEDGE https://example.com/product-documentation.pdf
|
|
1128
|
+
RULE Always be polite and professional
|
|
1129
|
+
\`\`\`
|
|
1130
|
+
|
|
1131
|
+
\`\`\`book
|
|
1132
|
+
Research Assistant
|
|
1133
|
+
|
|
1134
|
+
PERSONA You are a knowledgeable research assistant
|
|
1135
|
+
KNOWLEDGE Academic research requires careful citation and verification
|
|
1136
|
+
KNOWLEDGE https://example.com/research-guidelines.pdf
|
|
1137
|
+
ACTION Can help with literature reviews and data analysis
|
|
1138
|
+
STYLE Present information in clear, academic format
|
|
1139
|
+
\`\`\`
|
|
1140
|
+
`);
|
|
1141
|
+
}
|
|
1142
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
1143
|
+
var _a;
|
|
1144
|
+
const trimmedContent = content.trim();
|
|
1145
|
+
if (!trimmedContent) {
|
|
1146
|
+
return requirements;
|
|
1147
|
+
}
|
|
1148
|
+
// Check if content is a URL (external knowledge source)
|
|
1149
|
+
if (this.isUrl(trimmedContent)) {
|
|
1150
|
+
// Store the URL for later async processing
|
|
1151
|
+
const updatedRequirements = {
|
|
1152
|
+
...requirements,
|
|
1153
|
+
metadata: {
|
|
1154
|
+
...requirements.metadata,
|
|
1155
|
+
ragService: this.ragService,
|
|
1156
|
+
knowledgeSources: [
|
|
1157
|
+
...(((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.knowledgeSources) || []),
|
|
1158
|
+
trimmedContent,
|
|
1159
|
+
],
|
|
1160
|
+
},
|
|
1161
|
+
};
|
|
1162
|
+
// Add placeholder information about knowledge sources to system message
|
|
1163
|
+
const knowledgeInfo = `Knowledge Source URL: ${trimmedContent} (will be processed for retrieval during chat)`;
|
|
1164
|
+
return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
|
|
1165
|
+
}
|
|
1166
|
+
else {
|
|
1167
|
+
// Direct text knowledge - add to system message
|
|
1168
|
+
const knowledgeSection = `Knowledge: ${trimmedContent}`;
|
|
1169
|
+
return this.appendToSystemMessage(requirements, knowledgeSection, '\n\n');
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
/**
|
|
1173
|
+
* Check if content is a URL
|
|
1174
|
+
*/
|
|
1175
|
+
isUrl(content) {
|
|
1176
|
+
try {
|
|
1177
|
+
new URL(content);
|
|
1178
|
+
return true;
|
|
1179
|
+
}
|
|
1180
|
+
catch (_a) {
|
|
1181
|
+
return false;
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Get RAG service instance for retrieving context during chat
|
|
1186
|
+
*/
|
|
1187
|
+
getRagService() {
|
|
1188
|
+
return this.ragService;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Singleton instance of the KNOWLEDGE commitment definition
|
|
1193
|
+
*
|
|
1194
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1195
|
+
*/
|
|
1196
|
+
new KnowledgeCommitmentDefinition();
|
|
1197
|
+
/**
|
|
1198
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1199
|
+
*/
|
|
1200
|
+
|
|
1201
|
+
/**
|
|
1202
|
+
* META IMAGE commitment definition
|
|
1203
|
+
*
|
|
1204
|
+
* The META IMAGE commitment sets the agent's avatar/profile image URL.
|
|
1205
|
+
* This commitment is special because it doesn't affect the system message,
|
|
1206
|
+
* but is handled separately in the parsing logic.
|
|
1207
|
+
*
|
|
1208
|
+
* Example usage in agent source:
|
|
1209
|
+
*
|
|
1210
|
+
* ```book
|
|
1211
|
+
* META IMAGE https://example.com/avatar.jpg
|
|
1212
|
+
* META IMAGE /assets/agent-avatar.png
|
|
1213
|
+
* ```
|
|
1214
|
+
*
|
|
1215
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1216
|
+
*/
|
|
1217
|
+
class MetaImageCommitmentDefinition extends BaseCommitmentDefinition {
|
|
1218
|
+
constructor() {
|
|
1219
|
+
super('META IMAGE');
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Short one-line description of META IMAGE.
|
|
1223
|
+
*/
|
|
1224
|
+
get description() {
|
|
1225
|
+
return "Set the agent's profile image URL.";
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Markdown documentation for META IMAGE commitment.
|
|
1229
|
+
*/
|
|
1230
|
+
get documentation() {
|
|
1231
|
+
return spaceTrim(`
|
|
1232
|
+
# META IMAGE
|
|
1233
|
+
|
|
1234
|
+
Sets the agent's avatar/profile image URL.
|
|
1235
|
+
|
|
1236
|
+
## Key behaviors
|
|
1237
|
+
|
|
1238
|
+
- Does not modify the agent's behavior or responses.
|
|
1239
|
+
- Only one \`META IMAGE\` should be used per agent.
|
|
1240
|
+
- If multiple are specified, the last one takes precedence.
|
|
1241
|
+
- Used for visual representation in user interfaces.
|
|
1242
|
+
|
|
1243
|
+
## Examples
|
|
1244
|
+
|
|
1245
|
+
\`\`\`book
|
|
1246
|
+
Professional Assistant
|
|
1247
|
+
|
|
1248
|
+
META IMAGE https://example.com/professional-avatar.jpg
|
|
1249
|
+
PERSONA You are a professional business assistant
|
|
1250
|
+
STYLE Maintain a formal and courteous tone
|
|
1251
|
+
\`\`\`
|
|
1252
|
+
|
|
1253
|
+
\`\`\`book
|
|
1254
|
+
Creative Helper
|
|
1255
|
+
|
|
1256
|
+
META IMAGE /assets/creative-bot-avatar.png
|
|
1257
|
+
PERSONA You are a creative and inspiring assistant
|
|
1258
|
+
STYLE Be enthusiastic and encouraging
|
|
1259
|
+
ACTION Can help with brainstorming and ideation
|
|
1260
|
+
\`\`\`
|
|
1261
|
+
`);
|
|
1262
|
+
}
|
|
1263
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
1264
|
+
// META IMAGE doesn't modify the system message or model requirements
|
|
1265
|
+
// It's handled separately in the parsing logic for profile image extraction
|
|
1266
|
+
// This method exists for consistency with the CommitmentDefinition interface
|
|
1267
|
+
return requirements;
|
|
1268
|
+
}
|
|
1269
|
+
/**
|
|
1270
|
+
* Extracts the profile image URL from the content
|
|
1271
|
+
* This is used by the parsing logic
|
|
1272
|
+
*/
|
|
1273
|
+
extractProfileImageUrl(content) {
|
|
1274
|
+
const trimmedContent = content.trim();
|
|
1275
|
+
return trimmedContent || null;
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
1279
|
+
* Singleton instance of the META IMAGE commitment definition
|
|
1280
|
+
*
|
|
1281
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1282
|
+
*/
|
|
1283
|
+
new MetaImageCommitmentDefinition();
|
|
1284
|
+
/**
|
|
1285
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1286
|
+
*/
|
|
1287
|
+
|
|
1288
|
+
/**
|
|
1289
|
+
* META LINK commitment definition
|
|
1290
|
+
*
|
|
1291
|
+
* The `META LINK` commitment represents the link to the person from whom the agent is created.
|
|
1292
|
+
* This commitment is special because it doesn't affect the system message,
|
|
1293
|
+
* but is handled separately in the parsing logic for profile display.
|
|
1294
|
+
*
|
|
1295
|
+
* Example usage in agent source:
|
|
1296
|
+
*
|
|
1297
|
+
* ```
|
|
1298
|
+
* META LINK https://twitter.com/username
|
|
1299
|
+
* META LINK https://linkedin.com/in/profile
|
|
1300
|
+
* META LINK https://github.com/username
|
|
1301
|
+
* ```
|
|
1302
|
+
*
|
|
1303
|
+
* Multiple `META LINK` commitments can be used when there are multiple sources:
|
|
1304
|
+
*
|
|
1305
|
+
* ```book
|
|
1306
|
+
* META LINK https://twitter.com/username
|
|
1307
|
+
* META LINK https://linkedin.com/in/profile
|
|
1308
|
+
* ```
|
|
1309
|
+
*
|
|
1310
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1311
|
+
*/
|
|
1312
|
+
class MetaLinkCommitmentDefinition extends BaseCommitmentDefinition {
|
|
1313
|
+
constructor() {
|
|
1314
|
+
super('META LINK');
|
|
1315
|
+
}
|
|
1316
|
+
/**
|
|
1317
|
+
* Short one-line description of META LINK.
|
|
1318
|
+
*/
|
|
1319
|
+
get description() {
|
|
1320
|
+
return 'Provide profile/source links for the person the agent models.';
|
|
1321
|
+
}
|
|
1322
|
+
/**
|
|
1323
|
+
* Markdown documentation for META LINK commitment.
|
|
1324
|
+
*/
|
|
1325
|
+
get documentation() {
|
|
1326
|
+
return spaceTrim(`
|
|
1327
|
+
# META LINK
|
|
1328
|
+
|
|
1329
|
+
Represents a profile or source link for the person the agent is modeled after.
|
|
1330
|
+
|
|
1331
|
+
## Key behaviors
|
|
1332
|
+
|
|
1333
|
+
- Does not modify the agent's behavior or responses.
|
|
1334
|
+
- Multiple \`META LINK\` commitments can be used for different social profiles.
|
|
1335
|
+
- Used for attribution and crediting the original person.
|
|
1336
|
+
- Displayed in user interfaces for transparency.
|
|
1337
|
+
|
|
1338
|
+
## Examples
|
|
1339
|
+
|
|
1340
|
+
\`\`\`book
|
|
1341
|
+
Expert Consultant
|
|
1342
|
+
|
|
1343
|
+
META LINK https://twitter.com/expertname
|
|
1344
|
+
META LINK https://linkedin.com/in/expertprofile
|
|
1345
|
+
PERSONA You are Dr. Smith, a renowned expert in artificial intelligence
|
|
1346
|
+
KNOWLEDGE Extensive background in machine learning and neural networks
|
|
1347
|
+
\`\`\`
|
|
1348
|
+
|
|
1349
|
+
\`\`\`book
|
|
1350
|
+
Open Source Developer
|
|
1351
|
+
|
|
1352
|
+
META LINK https://github.com/developer
|
|
1353
|
+
META LINK https://twitter.com/devhandle
|
|
1354
|
+
PERSONA You are an experienced open source developer
|
|
1355
|
+
ACTION Can help with code reviews and architecture decisions
|
|
1356
|
+
STYLE Be direct and technical in explanations
|
|
1357
|
+
\`\`\`
|
|
1358
|
+
`);
|
|
1359
|
+
}
|
|
1360
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
1361
|
+
// META LINK doesn't modify the system message or model requirements
|
|
1362
|
+
// It's handled separately in the parsing logic for profile link extraction
|
|
1363
|
+
// This method exists for consistency with the CommitmentDefinition interface
|
|
1364
|
+
return requirements;
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* Extracts the profile link URL from the content
|
|
1368
|
+
* This is used by the parsing logic
|
|
1369
|
+
*/
|
|
1370
|
+
extractProfileLinkUrl(content) {
|
|
1371
|
+
const trimmedContent = content.trim();
|
|
1372
|
+
return trimmedContent || null;
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* Validates if the provided content is a valid URL
|
|
1376
|
+
*/
|
|
1377
|
+
isValidUrl(content) {
|
|
1378
|
+
try {
|
|
1379
|
+
new URL(content.trim());
|
|
1380
|
+
return true;
|
|
1381
|
+
}
|
|
1382
|
+
catch (_a) {
|
|
1383
|
+
return false;
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
/**
|
|
1388
|
+
* Singleton instance of the META LINK commitment definition
|
|
1389
|
+
*
|
|
1390
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1391
|
+
*/
|
|
1392
|
+
new MetaLinkCommitmentDefinition();
|
|
1393
|
+
/**
|
|
1394
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1395
|
+
*/
|
|
1396
|
+
|
|
1397
|
+
/**
|
|
1398
|
+
* MODEL commitment definition
|
|
1399
|
+
*
|
|
1400
|
+
* The MODEL commitment specifies which AI model to use and can also set
|
|
1401
|
+
* model-specific parameters like temperature, topP, and topK.
|
|
1402
|
+
*
|
|
1403
|
+
* Example usage in agent source:
|
|
1404
|
+
*
|
|
1405
|
+
* ```book
|
|
1406
|
+
* MODEL gpt-4
|
|
1407
|
+
* MODEL claude-3-opus temperature=0.3
|
|
1408
|
+
* MODEL gpt-3.5-turbo temperature=0.8 topP=0.9
|
|
1409
|
+
* ```
|
|
1410
|
+
*
|
|
1411
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1412
|
+
*/
|
|
1413
|
+
class ModelCommitmentDefinition extends BaseCommitmentDefinition {
|
|
1414
|
+
constructor() {
|
|
1415
|
+
super('MODEL');
|
|
1416
|
+
}
|
|
1417
|
+
/**
|
|
1418
|
+
* Short one-line description of MODEL.
|
|
1419
|
+
*/
|
|
1420
|
+
get description() {
|
|
1421
|
+
return 'Select the AI model and optional decoding parameters.';
|
|
1422
|
+
}
|
|
1423
|
+
/**
|
|
1424
|
+
* Markdown documentation for MODEL commitment.
|
|
1425
|
+
*/
|
|
1426
|
+
get documentation() {
|
|
1427
|
+
return spaceTrim(`
|
|
1428
|
+
# MODEL
|
|
1429
|
+
|
|
1430
|
+
Specifies which AI model to use and optional decoding parameters.
|
|
1431
|
+
|
|
1432
|
+
## Key behaviors
|
|
1433
|
+
|
|
1434
|
+
- Only one \`MODEL\` commitment should be used per agent.
|
|
1435
|
+
- If multiple are specified, the last one takes precedence.
|
|
1436
|
+
- Parameters control the randomness and creativity of responses.
|
|
1437
|
+
|
|
1438
|
+
## Supported parameters
|
|
1439
|
+
|
|
1440
|
+
- \`temperature\`: Controls randomness (0.0 = deterministic, 1.0+ = creative)
|
|
1441
|
+
- \`topP\` (aka \`top_p\`): Nucleus sampling parameter
|
|
1442
|
+
- \`topK\` (aka \`top_k\`): Top-k sampling parameter
|
|
1443
|
+
|
|
1444
|
+
## Examples
|
|
1445
|
+
|
|
1446
|
+
\`\`\`book
|
|
1447
|
+
Precise Assistant
|
|
1448
|
+
|
|
1449
|
+
PERSONA You are a precise and accurate assistant
|
|
1450
|
+
MODEL gpt-4 temperature=0.1
|
|
1451
|
+
RULE Always provide factual information
|
|
1452
|
+
\`\`\`
|
|
1453
|
+
|
|
1454
|
+
\`\`\`book
|
|
1455
|
+
Creative Writer
|
|
1456
|
+
|
|
1457
|
+
PERSONA You are a creative writing assistant
|
|
1458
|
+
MODEL claude-3-opus temperature=0.8 topP=0.9
|
|
1459
|
+
STYLE Be imaginative and expressive
|
|
1460
|
+
ACTION Can help with storytelling and character development
|
|
1461
|
+
\`\`\`
|
|
1462
|
+
`);
|
|
1463
|
+
}
|
|
1464
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
1465
|
+
const trimmedContent = content.trim();
|
|
1466
|
+
if (!trimmedContent) {
|
|
1467
|
+
return requirements;
|
|
1468
|
+
}
|
|
1469
|
+
// Parse the model specification
|
|
1470
|
+
const parts = trimmedContent.split(/\s+/);
|
|
1471
|
+
const modelName = parts[0];
|
|
1472
|
+
if (!modelName) {
|
|
1473
|
+
return requirements;
|
|
1474
|
+
}
|
|
1475
|
+
// Start with the model name
|
|
1476
|
+
const updatedRequirements = {
|
|
1477
|
+
...requirements,
|
|
1478
|
+
modelName,
|
|
1479
|
+
};
|
|
1480
|
+
// Parse additional parameters
|
|
1481
|
+
const result = { ...updatedRequirements };
|
|
1482
|
+
for (let i = 1; i < parts.length; i++) {
|
|
1483
|
+
const param = parts[i];
|
|
1484
|
+
if (param && param.includes('=')) {
|
|
1485
|
+
const [key, value] = param.split('=');
|
|
1486
|
+
if (key && value) {
|
|
1487
|
+
const numValue = parseFloat(value);
|
|
1488
|
+
if (!isNaN(numValue)) {
|
|
1489
|
+
switch (key.toLowerCase()) {
|
|
1490
|
+
case 'temperature':
|
|
1491
|
+
result.temperature = numValue;
|
|
1492
|
+
break;
|
|
1493
|
+
case 'topp':
|
|
1494
|
+
case 'top_p':
|
|
1495
|
+
result.topP = numValue;
|
|
1496
|
+
break;
|
|
1497
|
+
case 'topk':
|
|
1498
|
+
case 'top_k':
|
|
1499
|
+
result.topK = Math.round(numValue);
|
|
1500
|
+
break;
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
return result;
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
/**
|
|
1510
|
+
* Singleton instance of the MODEL commitment definition
|
|
1511
|
+
*
|
|
1512
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1513
|
+
*/
|
|
1514
|
+
new ModelCommitmentDefinition();
|
|
1515
|
+
/**
|
|
1516
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1517
|
+
*/
|
|
1518
|
+
|
|
1519
|
+
/**
|
|
1520
|
+
* NOTE commitment definition
|
|
1521
|
+
*
|
|
1522
|
+
* The NOTE commitment is used to add comments to the agent source without making any changes
|
|
1523
|
+
* to the system message or agent model requirements. It serves as a documentation mechanism
|
|
1524
|
+
* for developers to add explanatory comments, reminders, or annotations directly in the agent source.
|
|
1525
|
+
*
|
|
1526
|
+
* Key features:
|
|
1527
|
+
* - Makes no changes to the system message
|
|
1528
|
+
* - Makes no changes to agent model requirements
|
|
1529
|
+
* - Content is preserved in metadata.NOTE for debugging and inspection
|
|
1530
|
+
* - Multiple NOTE commitments are aggregated together
|
|
1531
|
+
* - Comments (# NOTE) are removed from the final system message
|
|
1532
|
+
*
|
|
1533
|
+
* Example usage in agent source:
|
|
1534
|
+
*
|
|
1535
|
+
* ```book
|
|
1536
|
+
* NOTE This agent was designed for customer support scenarios
|
|
1537
|
+
* NOTE Remember to update the knowledge base monthly
|
|
1538
|
+
* NOTE Performance optimized for quick response times
|
|
1539
|
+
* ```
|
|
1540
|
+
*
|
|
1541
|
+
* The above notes will be stored in metadata but won't affect the agent's behavior.
|
|
1542
|
+
*
|
|
1543
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1544
|
+
*/
|
|
1545
|
+
class NoteCommitmentDefinition extends BaseCommitmentDefinition {
|
|
1546
|
+
constructor() {
|
|
1547
|
+
super('NOTE');
|
|
1548
|
+
}
|
|
1549
|
+
/**
|
|
1550
|
+
* Short one-line description of NOTE.
|
|
1551
|
+
*/
|
|
1552
|
+
get description() {
|
|
1553
|
+
return 'Add developer-facing notes without changing behavior or output.';
|
|
1554
|
+
}
|
|
1555
|
+
/**
|
|
1556
|
+
* Markdown documentation for NOTE commitment.
|
|
1557
|
+
*/
|
|
1558
|
+
get documentation() {
|
|
1559
|
+
return spaceTrim(`
|
|
1560
|
+
# NOTE
|
|
1561
|
+
|
|
1562
|
+
Adds comments for documentation without changing agent behavior.
|
|
1563
|
+
|
|
1564
|
+
## Key behaviors
|
|
1565
|
+
|
|
1566
|
+
- Does not modify the agent's behavior or responses.
|
|
1567
|
+
- Multiple \`NOTE\` commitments are aggregated for debugging.
|
|
1568
|
+
- Useful for documenting design decisions and reminders.
|
|
1569
|
+
- Content is preserved in metadata for inspection.
|
|
1570
|
+
|
|
1571
|
+
## Examples
|
|
1572
|
+
|
|
1573
|
+
\`\`\`book
|
|
1574
|
+
Customer Support Bot
|
|
1575
|
+
|
|
1576
|
+
NOTE This agent was designed for customer support scenarios
|
|
1577
|
+
NOTE Remember to update the knowledge base monthly
|
|
1578
|
+
PERSONA You are a helpful customer support representative
|
|
1579
|
+
KNOWLEDGE Company policies and procedures
|
|
1580
|
+
RULE Always be polite and professional
|
|
1581
|
+
\`\`\`
|
|
1582
|
+
|
|
1583
|
+
\`\`\`book
|
|
1584
|
+
Research Assistant
|
|
1585
|
+
|
|
1586
|
+
NOTE Performance optimized for quick response times
|
|
1587
|
+
NOTE Uses RAG for accessing latest research papers
|
|
1588
|
+
PERSONA You are a knowledgeable research assistant
|
|
1589
|
+
ACTION Can help with literature reviews and citations
|
|
1590
|
+
STYLE Present information in academic format
|
|
1591
|
+
\`\`\`
|
|
1592
|
+
`);
|
|
1593
|
+
}
|
|
1594
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
1595
|
+
var _a;
|
|
1596
|
+
// The NOTE commitment makes no changes to the system message or model requirements
|
|
1597
|
+
// It only stores the note content in metadata for documentation purposes
|
|
1598
|
+
const trimmedContent = content.trim();
|
|
1599
|
+
if (!trimmedContent) {
|
|
1600
|
+
return requirements;
|
|
1601
|
+
}
|
|
1602
|
+
// Get existing note content from metadata
|
|
1603
|
+
const existingNoteContent = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.NOTE) || '';
|
|
1604
|
+
// Merge the new content with existing note content
|
|
1605
|
+
// When multiple NOTE commitments exist, they are aggregated together
|
|
1606
|
+
const mergedNoteContent = existingNoteContent ? `${existingNoteContent}\n${trimmedContent}` : trimmedContent;
|
|
1607
|
+
// Store the merged note content in metadata for debugging and inspection
|
|
1608
|
+
const updatedMetadata = {
|
|
1609
|
+
...requirements.metadata,
|
|
1610
|
+
NOTE: mergedNoteContent,
|
|
1611
|
+
};
|
|
1612
|
+
// Return requirements with updated metadata but no changes to system message
|
|
1613
|
+
return {
|
|
1614
|
+
...requirements,
|
|
1615
|
+
metadata: updatedMetadata,
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* Singleton instance of the NOTE commitment definition
|
|
1621
|
+
*
|
|
1622
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1623
|
+
*/
|
|
1624
|
+
new NoteCommitmentDefinition();
|
|
1625
|
+
/**
|
|
1626
|
+
* [💞] Ignore a discrepancy between file name and entity name
|
|
1627
|
+
*/
|
|
1628
|
+
|
|
1629
|
+
/**
|
|
1630
|
+
* PERSONA commitment definition
|
|
1631
|
+
*
|
|
1632
|
+
* The PERSONA commitment modifies the agent's personality and character in the system message.
|
|
1633
|
+
* It defines who the agent is, their background, expertise, and personality traits.
|
|
1634
|
+
*
|
|
1635
|
+
* Key features:
|
|
1636
|
+
* - Multiple PERSONA commitments are automatically merged into one
|
|
1637
|
+
* - Content is placed at the beginning of the system message
|
|
1638
|
+
* - Original content with comments is preserved in metadata.PERSONA
|
|
1639
|
+
* - Comments (# PERSONA) are removed from the final system message
|
|
1640
|
+
*
|
|
1641
|
+
* Example usage in agent source:
|
|
1642
|
+
*
|
|
1643
|
+
* ```book
|
|
1644
|
+
* PERSONA You are a helpful programming assistant with expertise in TypeScript and React
|
|
1645
|
+
* PERSONA You have deep knowledge of modern web development practices
|
|
1646
|
+
* ```
|
|
1647
|
+
*
|
|
1648
|
+
* The above will be merged into a single persona section at the beginning of the system message.
|
|
1649
|
+
*
|
|
1650
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1651
|
+
*/
|
|
1652
|
+
class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
|
|
1653
|
+
constructor() {
|
|
1654
|
+
super('PERSONA');
|
|
1655
|
+
}
|
|
1656
|
+
/**
|
|
1657
|
+
* Short one-line description of PERSONA.
|
|
1658
|
+
*/
|
|
1659
|
+
get description() {
|
|
1660
|
+
return 'Define who the agent is: background, expertise, and personality.';
|
|
1661
|
+
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Markdown documentation for PERSONA commitment.
|
|
1664
|
+
*/
|
|
1665
|
+
get documentation() {
|
|
1666
|
+
return spaceTrim(`
|
|
1667
|
+
# PERSONA
|
|
1668
|
+
|
|
1669
|
+
Defines who the agent is, their background, expertise, and personality traits.
|
|
1670
|
+
|
|
1671
|
+
## Key behaviors
|
|
1672
|
+
|
|
1673
|
+
- Multiple \`PERSONA\` commitments are merged together.
|
|
1674
|
+
- If they are in conflict, the last one takes precedence.
|
|
1675
|
+
- You can write persona content in multiple lines.
|
|
1676
|
+
|
|
1677
|
+
## Examples
|
|
1678
|
+
|
|
1679
|
+
\`\`\`book
|
|
1680
|
+
Programming Assistant
|
|
1681
|
+
|
|
1682
|
+
PERSONA You are a helpful programming assistant with expertise in TypeScript and React
|
|
1683
|
+
PERSONA You have deep knowledge of modern web development practices
|
|
1684
|
+
\`\`\`
|
|
1685
|
+
`);
|
|
1686
|
+
}
|
|
1687
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
1688
|
+
var _a, _b;
|
|
1689
|
+
// The PERSONA commitment aggregates all persona content and places it at the beginning
|
|
1690
|
+
const trimmedContent = content.trim();
|
|
1691
|
+
if (!trimmedContent) {
|
|
1692
|
+
return requirements;
|
|
1693
|
+
}
|
|
1694
|
+
// Get existing persona content from metadata
|
|
1695
|
+
const existingPersonaContent = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.PERSONA) || '';
|
|
1696
|
+
// Merge the new content with existing persona content
|
|
1697
|
+
// When multiple PERSONA commitments exist, they are merged into one
|
|
1698
|
+
const mergedPersonaContent = existingPersonaContent
|
|
1699
|
+
? `${existingPersonaContent}\n${trimmedContent}`
|
|
1700
|
+
: trimmedContent;
|
|
1701
|
+
// Store the merged persona content in metadata for debugging and inspection
|
|
1702
|
+
const updatedMetadata = {
|
|
1703
|
+
...requirements.metadata,
|
|
1704
|
+
PERSONA: mergedPersonaContent,
|
|
1705
|
+
};
|
|
1706
|
+
// Get the agent name from metadata (which should contain the first line of agent source)
|
|
1707
|
+
// If not available, extract from current system message as fallback
|
|
1708
|
+
let agentName = (_b = requirements.metadata) === null || _b === void 0 ? void 0 : _b.agentName;
|
|
1709
|
+
if (!agentName) {
|
|
1710
|
+
// Fallback: extract from current system message
|
|
1711
|
+
const currentMessage = requirements.systemMessage.trim();
|
|
1712
|
+
const basicFormatMatch = currentMessage.match(/^You are (.+)$/);
|
|
1713
|
+
if (basicFormatMatch && basicFormatMatch[1]) {
|
|
1714
|
+
agentName = basicFormatMatch[1];
|
|
1715
|
+
}
|
|
1716
|
+
else {
|
|
1717
|
+
agentName = 'AI Agent'; // Final fallback
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
// Remove any existing persona content from the system message
|
|
1721
|
+
// (this handles the case where we're processing multiple PERSONA commitments)
|
|
1722
|
+
const currentMessage = requirements.systemMessage.trim();
|
|
1723
|
+
let cleanedMessage = currentMessage;
|
|
1724
|
+
// Check if current message starts with persona content or is just the basic format
|
|
1725
|
+
const basicFormatRegex = /^You are .+$/;
|
|
1726
|
+
const isBasicFormat = basicFormatRegex.test(currentMessage) && !currentMessage.includes('\n');
|
|
1727
|
+
if (isBasicFormat) {
|
|
1728
|
+
// Replace the basic format entirely
|
|
1729
|
+
cleanedMessage = '';
|
|
1730
|
+
}
|
|
1731
|
+
else if (currentMessage.startsWith('# PERSONA')) {
|
|
1732
|
+
// Remove existing persona section by finding where it ends
|
|
1733
|
+
const lines = currentMessage.split('\n');
|
|
1734
|
+
let personaEndIndex = lines.length;
|
|
1735
|
+
// Find the end of the PERSONA section (next comment or end of message)
|
|
1736
|
+
for (let i = 1; i < lines.length; i++) {
|
|
1737
|
+
const line = lines[i].trim();
|
|
1738
|
+
if (line.startsWith('#') && !line.startsWith('# PERSONA')) {
|
|
1739
|
+
personaEndIndex = i;
|
|
1740
|
+
break;
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
// Keep everything after the PERSONA section
|
|
1744
|
+
cleanedMessage = lines.slice(personaEndIndex).join('\n').trim();
|
|
1745
|
+
}
|
|
1746
|
+
// Create new system message with persona at the beginning
|
|
1747
|
+
// Format: "You are {agentName}\n{personaContent}"
|
|
1748
|
+
// The # PERSONA comment will be removed later by removeCommentsFromSystemMessage
|
|
1749
|
+
const personaSection = `# PERSONA\nYou are ${agentName}\n${mergedPersonaContent}`; // <- TODO: Use spaceTrim
|
|
1750
|
+
const newSystemMessage = cleanedMessage ? `${personaSection}\n\n${cleanedMessage}` : personaSection;
|
|
1751
|
+
return {
|
|
1752
|
+
...requirements,
|
|
1753
|
+
systemMessage: newSystemMessage,
|
|
1754
|
+
metadata: updatedMetadata,
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
/**
|
|
1759
|
+
* Singleton instance of the PERSONA commitment definition
|
|
1760
|
+
*
|
|
1761
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1762
|
+
*/
|
|
1763
|
+
new PersonaCommitmentDefinition();
|
|
1764
|
+
/**
|
|
1765
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1766
|
+
*/
|
|
1767
|
+
|
|
1768
|
+
/**
|
|
1769
|
+
* RULE commitment definition
|
|
1770
|
+
*
|
|
1771
|
+
* The RULE/RULES commitment adds behavioral constraints and guidelines that the agent must follow.
|
|
1772
|
+
* These are specific instructions about what the agent should or shouldn't do.
|
|
1773
|
+
*
|
|
1774
|
+
* Example usage in agent source:
|
|
1775
|
+
*
|
|
1776
|
+
* ```book
|
|
1777
|
+
* RULE Always ask for clarification if the user's request is ambiguous
|
|
1778
|
+
* RULES Never provide medical advice, always refer to healthcare professionals
|
|
1779
|
+
* ```
|
|
1780
|
+
*
|
|
1781
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1782
|
+
*/
|
|
1783
|
+
class RuleCommitmentDefinition extends BaseCommitmentDefinition {
|
|
1784
|
+
constructor(type = 'RULE') {
|
|
1785
|
+
super(type);
|
|
1786
|
+
}
|
|
1787
|
+
/**
|
|
1788
|
+
* Short one-line description of RULE/RULES.
|
|
1789
|
+
*/
|
|
1790
|
+
get description() {
|
|
1791
|
+
return 'Add behavioral rules the agent must follow.';
|
|
1792
|
+
}
|
|
1793
|
+
/**
|
|
1794
|
+
* Markdown documentation for RULE/RULES commitment.
|
|
1795
|
+
*/
|
|
1796
|
+
get documentation() {
|
|
1797
|
+
return spaceTrim(`
|
|
1798
|
+
# ${this.type}
|
|
1799
|
+
|
|
1800
|
+
Adds behavioral constraints and guidelines that the agent must follow.
|
|
1801
|
+
|
|
1802
|
+
## Key behaviors
|
|
1803
|
+
|
|
1804
|
+
- Multiple \`RULE\` and \`RULES\` commitments are applied sequentially.
|
|
1805
|
+
- All rules are treated equally regardless of singular/plural form.
|
|
1806
|
+
- Rules define what the agent must or must not do.
|
|
1807
|
+
|
|
1808
|
+
## Examples
|
|
1809
|
+
|
|
1810
|
+
\`\`\`book
|
|
1811
|
+
Customer Support Agent
|
|
1812
|
+
|
|
1813
|
+
PERSONA You are a helpful customer support representative
|
|
1814
|
+
RULE Always ask for clarification if the user's request is ambiguous
|
|
1815
|
+
RULE Be polite and professional in all interactions
|
|
1816
|
+
RULES Never provide medical or legal advice
|
|
1817
|
+
STYLE Maintain a friendly and helpful tone
|
|
1818
|
+
\`\`\`
|
|
1819
|
+
|
|
1820
|
+
\`\`\`book
|
|
1821
|
+
Educational Tutor
|
|
1822
|
+
|
|
1823
|
+
PERSONA You are a patient and knowledgeable tutor
|
|
1824
|
+
RULE Break down complex concepts into simple steps
|
|
1825
|
+
RULE Always encourage students and celebrate their progress
|
|
1826
|
+
RULE If you don't know something, admit it and suggest resources
|
|
1827
|
+
SAMPLE When explaining math: "Let's work through this step by step..."
|
|
1828
|
+
\`\`\`
|
|
1829
|
+
`);
|
|
1830
|
+
}
|
|
1831
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
1832
|
+
const trimmedContent = content.trim();
|
|
1833
|
+
if (!trimmedContent) {
|
|
1834
|
+
return requirements;
|
|
1835
|
+
}
|
|
1836
|
+
// Add rule to the system message
|
|
1837
|
+
const ruleSection = `Rule: ${trimmedContent}`;
|
|
1838
|
+
return this.appendToSystemMessage(requirements, ruleSection, '\n\n');
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
/**
|
|
1842
|
+
* Singleton instances of the RULE commitment definitions
|
|
1843
|
+
*
|
|
1844
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1845
|
+
*/
|
|
1846
|
+
new RuleCommitmentDefinition('RULE');
|
|
1847
|
+
/**
|
|
1848
|
+
* Singleton instances of the RULE commitment definitions
|
|
1849
|
+
*
|
|
1850
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1851
|
+
*/
|
|
1852
|
+
new RuleCommitmentDefinition('RULES');
|
|
1853
|
+
/**
|
|
1854
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1855
|
+
*/
|
|
1856
|
+
|
|
1857
|
+
/**
|
|
1858
|
+
* SAMPLE commitment definition
|
|
1859
|
+
*
|
|
1860
|
+
* The SAMPLE/EXAMPLE commitment provides examples of how the agent should respond
|
|
1861
|
+
* or behave in certain situations. These examples help guide the agent's responses.
|
|
1862
|
+
*
|
|
1863
|
+
* Example usage in agent source:
|
|
1864
|
+
*
|
|
1865
|
+
* ```book
|
|
1866
|
+
* SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
|
|
1867
|
+
* EXAMPLE For code questions, always include working code snippets
|
|
1868
|
+
* ```
|
|
1869
|
+
*
|
|
1870
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1871
|
+
*/
|
|
1872
|
+
class SampleCommitmentDefinition extends BaseCommitmentDefinition {
|
|
1873
|
+
constructor(type = 'SAMPLE') {
|
|
1874
|
+
super(type);
|
|
1875
|
+
}
|
|
1876
|
+
/**
|
|
1877
|
+
* Short one-line description of SAMPLE/EXAMPLE.
|
|
1878
|
+
*/
|
|
1879
|
+
get description() {
|
|
1880
|
+
return 'Provide example responses to guide behavior.';
|
|
1881
|
+
}
|
|
1882
|
+
/**
|
|
1883
|
+
* Markdown documentation for SAMPLE/EXAMPLE commitment.
|
|
1884
|
+
*/
|
|
1885
|
+
get documentation() {
|
|
1886
|
+
return spaceTrim(`
|
|
1887
|
+
# ${this.type}
|
|
1888
|
+
|
|
1889
|
+
Provides examples of how the agent should respond or behave in certain situations.
|
|
1890
|
+
|
|
1891
|
+
## Key behaviors
|
|
1892
|
+
|
|
1893
|
+
- Multiple \`SAMPLE\` and \`EXAMPLE\` commitments are applied sequentially.
|
|
1894
|
+
- Both terms work identically and can be used interchangeably.
|
|
1895
|
+
- Examples help guide the agent's response patterns and style.
|
|
1896
|
+
|
|
1897
|
+
## Examples
|
|
1898
|
+
|
|
1899
|
+
\`\`\`book
|
|
1900
|
+
Sales Assistant
|
|
1901
|
+
|
|
1902
|
+
PERSONA You are a knowledgeable sales representative
|
|
1903
|
+
SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
|
|
1904
|
+
SAMPLE For feature comparisons, create a clear comparison table
|
|
1905
|
+
RULE Always be honest about limitations
|
|
1906
|
+
\`\`\`
|
|
1907
|
+
|
|
1908
|
+
\`\`\`book
|
|
1909
|
+
Code Reviewer
|
|
1910
|
+
|
|
1911
|
+
PERSONA You are an experienced software engineer
|
|
1912
|
+
EXAMPLE For code questions, always include working code snippets
|
|
1913
|
+
EXAMPLE When suggesting improvements: "Here's a more efficient approach..."
|
|
1914
|
+
RULE Explain the reasoning behind your suggestions
|
|
1915
|
+
STYLE Be constructive and encouraging in feedback
|
|
1916
|
+
\`\`\`
|
|
1917
|
+
`);
|
|
1918
|
+
}
|
|
1919
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
1920
|
+
const trimmedContent = content.trim();
|
|
1921
|
+
if (!trimmedContent) {
|
|
1922
|
+
return requirements;
|
|
1923
|
+
}
|
|
1924
|
+
// Add example to the system message
|
|
1925
|
+
const exampleSection = `Example: ${trimmedContent}`;
|
|
1926
|
+
return this.appendToSystemMessage(requirements, exampleSection, '\n\n');
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
/**
|
|
1930
|
+
* Singleton instances of the SAMPLE commitment definitions
|
|
1931
|
+
*
|
|
1932
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1933
|
+
*/
|
|
1934
|
+
new SampleCommitmentDefinition('SAMPLE');
|
|
1935
|
+
/**
|
|
1936
|
+
* Singleton instances of the SAMPLE commitment definitions
|
|
1937
|
+
*
|
|
1938
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1939
|
+
*/
|
|
1940
|
+
new SampleCommitmentDefinition('EXAMPLE');
|
|
1941
|
+
/**
|
|
1942
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1943
|
+
*/
|
|
1944
|
+
|
|
1945
|
+
/**
|
|
1946
|
+
* STYLE commitment definition
|
|
1947
|
+
*
|
|
1948
|
+
* The STYLE commitment defines how the agent should format and present its responses.
|
|
1949
|
+
* This includes tone, writing style, formatting preferences, and communication patterns.
|
|
1950
|
+
*
|
|
1951
|
+
* Example usage in agent source:
|
|
1952
|
+
*
|
|
1953
|
+
* ```book
|
|
1954
|
+
* STYLE Write in a professional but friendly tone, use bullet points for lists
|
|
1955
|
+
* STYLE Always provide code examples when explaining programming concepts
|
|
1956
|
+
* ```
|
|
1957
|
+
*
|
|
1958
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
1959
|
+
*/
|
|
1960
|
+
class StyleCommitmentDefinition extends BaseCommitmentDefinition {
|
|
1961
|
+
constructor() {
|
|
1962
|
+
super('STYLE');
|
|
1963
|
+
}
|
|
1964
|
+
/**
|
|
1965
|
+
* Short one-line description of STYLE.
|
|
1966
|
+
*/
|
|
1967
|
+
get description() {
|
|
1968
|
+
return 'Control the tone and writing style of responses.';
|
|
1969
|
+
}
|
|
1970
|
+
/**
|
|
1971
|
+
* Markdown documentation for STYLE commitment.
|
|
1972
|
+
*/
|
|
1973
|
+
get documentation() {
|
|
1974
|
+
return spaceTrim(`
|
|
1975
|
+
# STYLE
|
|
1976
|
+
|
|
1977
|
+
Defines how the agent should format and present its responses (tone, writing style, formatting).
|
|
1978
|
+
|
|
1979
|
+
## Key behaviors
|
|
1980
|
+
|
|
1981
|
+
- Multiple \`STYLE\` commitments are applied sequentially.
|
|
1982
|
+
- Later style instructions can override earlier ones.
|
|
1983
|
+
- Style affects both tone and presentation format.
|
|
1984
|
+
|
|
1985
|
+
## Examples
|
|
1986
|
+
|
|
1987
|
+
\`\`\`book
|
|
1988
|
+
Technical Writer
|
|
1989
|
+
|
|
1990
|
+
PERSONA You are a technical documentation expert
|
|
1991
|
+
STYLE Write in a professional but friendly tone, use bullet points for lists
|
|
1992
|
+
STYLE Always provide code examples when explaining programming concepts
|
|
1993
|
+
FORMAT Use markdown formatting with clear headings
|
|
1994
|
+
\`\`\`
|
|
1995
|
+
|
|
1996
|
+
\`\`\`book
|
|
1997
|
+
Creative Assistant
|
|
1998
|
+
|
|
1999
|
+
PERSONA You are a creative writing helper
|
|
2000
|
+
STYLE Be enthusiastic and encouraging in your responses
|
|
2001
|
+
STYLE Use vivid metaphors and analogies to explain concepts
|
|
2002
|
+
STYLE Keep responses conversational and engaging
|
|
2003
|
+
RULE Always maintain a positive and supportive tone
|
|
2004
|
+
\`\`\`
|
|
2005
|
+
`);
|
|
2006
|
+
}
|
|
2007
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
2008
|
+
const trimmedContent = content.trim();
|
|
2009
|
+
if (!trimmedContent) {
|
|
2010
|
+
return requirements;
|
|
2011
|
+
}
|
|
2012
|
+
// Add style instructions to the system message
|
|
2013
|
+
const styleSection = `Style: ${trimmedContent}`;
|
|
2014
|
+
return this.appendToSystemMessage(requirements, styleSection, '\n\n');
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
/**
|
|
2018
|
+
* Singleton instance of the STYLE commitment definition
|
|
2019
|
+
*
|
|
2020
|
+
* @private [🪔] Maybe export the commitments through some package
|
|
2021
|
+
*/
|
|
2022
|
+
new StyleCommitmentDefinition();
|
|
2023
|
+
/**
|
|
2024
|
+
* [💞] Ignore a discrepancy between file name and entity name
|
|
2025
|
+
*/
|
|
2026
|
+
|
|
2027
|
+
/**
|
|
2028
|
+
* Placeholder commitment definition for commitments that are not yet implemented
|
|
2029
|
+
*
|
|
2030
|
+
* This commitment simply adds its content 1:1 into the system message,
|
|
2031
|
+
* preserving the original behavior until proper implementation is added.
|
|
2032
|
+
*
|
|
2033
|
+
* @public exported from `@promptbook/core`
|
|
2034
|
+
*/
|
|
2035
|
+
class NotYetImplementedCommitmentDefinition extends BaseCommitmentDefinition {
|
|
2036
|
+
constructor(type) {
|
|
2037
|
+
super(type);
|
|
2038
|
+
}
|
|
2039
|
+
/**
|
|
2040
|
+
* Short one-line description of a placeholder commitment.
|
|
2041
|
+
*/
|
|
2042
|
+
get description() {
|
|
2043
|
+
return 'Placeholder commitment that appends content verbatim to the system message.';
|
|
2044
|
+
}
|
|
2045
|
+
/**
|
|
2046
|
+
* Markdown documentation available at runtime.
|
|
2047
|
+
*/
|
|
2048
|
+
get documentation() {
|
|
2049
|
+
return spaceTrim(`
|
|
2050
|
+
# ${this.type}
|
|
2051
|
+
|
|
2052
|
+
This commitment is not yet fully implemented.
|
|
2053
|
+
|
|
2054
|
+
## Key behaviors
|
|
2055
|
+
|
|
2056
|
+
- Content is appended directly to the system message.
|
|
2057
|
+
- No special processing or validation is performed.
|
|
2058
|
+
- Behavior preserved until proper implementation is added.
|
|
2059
|
+
|
|
2060
|
+
## Status
|
|
2061
|
+
|
|
2062
|
+
- **Status:** Placeholder implementation
|
|
2063
|
+
- **Effect:** Appends content prefixed by commitment type
|
|
2064
|
+
- **Future:** Will be replaced with specialized logic
|
|
2065
|
+
|
|
2066
|
+
## Examples
|
|
2067
|
+
|
|
2068
|
+
\`\`\`book
|
|
2069
|
+
Example Agent
|
|
2070
|
+
|
|
2071
|
+
PERSONA You are a helpful assistant
|
|
2072
|
+
${this.type} Your content here
|
|
2073
|
+
RULE Always be helpful
|
|
2074
|
+
\`\`\`
|
|
2075
|
+
`);
|
|
2076
|
+
}
|
|
2077
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
2078
|
+
const trimmedContent = content.trim();
|
|
2079
|
+
if (!trimmedContent) {
|
|
2080
|
+
return requirements;
|
|
2081
|
+
}
|
|
2082
|
+
// Add the commitment content 1:1 to the system message
|
|
2083
|
+
const commitmentLine = `${this.type} ${trimmedContent}`;
|
|
2084
|
+
return this.appendToSystemMessage(requirements, commitmentLine, '\n\n');
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2088
|
+
// Import all commitment definition classes
|
|
2089
|
+
/**
|
|
2090
|
+
* Registry of all available commitment definitions
|
|
2091
|
+
* This array contains instances of all commitment definitions
|
|
2092
|
+
* This is the single source of truth for all commitments in the system
|
|
2093
|
+
*
|
|
2094
|
+
* @private Use functions to access commitments instead of this array directly
|
|
2095
|
+
*/
|
|
2096
|
+
const COMMITMENT_REGISTRY = [
|
|
2097
|
+
// Fully implemented commitments
|
|
2098
|
+
new PersonaCommitmentDefinition(),
|
|
2099
|
+
new KnowledgeCommitmentDefinition(),
|
|
2100
|
+
new StyleCommitmentDefinition(),
|
|
2101
|
+
new RuleCommitmentDefinition('RULE'),
|
|
2102
|
+
new RuleCommitmentDefinition('RULES'),
|
|
2103
|
+
new SampleCommitmentDefinition('SAMPLE'),
|
|
2104
|
+
new SampleCommitmentDefinition('EXAMPLE'),
|
|
2105
|
+
new FormatCommitmentDefinition(),
|
|
2106
|
+
new ModelCommitmentDefinition(),
|
|
2107
|
+
new ActionCommitmentDefinition(),
|
|
2108
|
+
new MetaImageCommitmentDefinition(),
|
|
2109
|
+
new MetaLinkCommitmentDefinition(),
|
|
2110
|
+
new NoteCommitmentDefinition(),
|
|
2111
|
+
// Not yet implemented commitments (using placeholder)
|
|
2112
|
+
new NotYetImplementedCommitmentDefinition('EXPECT'),
|
|
2113
|
+
new NotYetImplementedCommitmentDefinition('SCENARIO'),
|
|
2114
|
+
new NotYetImplementedCommitmentDefinition('SCENARIOS'),
|
|
2115
|
+
new NotYetImplementedCommitmentDefinition('BEHAVIOUR'),
|
|
2116
|
+
new NotYetImplementedCommitmentDefinition('BEHAVIOURS'),
|
|
2117
|
+
new NotYetImplementedCommitmentDefinition('AVOID'),
|
|
2118
|
+
new NotYetImplementedCommitmentDefinition('AVOIDANCE'),
|
|
2119
|
+
new NotYetImplementedCommitmentDefinition('GOAL'),
|
|
2120
|
+
new NotYetImplementedCommitmentDefinition('GOALS'),
|
|
2121
|
+
new NotYetImplementedCommitmentDefinition('CONTEXT'),
|
|
2122
|
+
];
|
|
2123
|
+
/**
|
|
2124
|
+
* Gets a commitment definition by its type
|
|
2125
|
+
* @param type The commitment type to look up
|
|
2126
|
+
* @returns The commitment definition or null if not found
|
|
2127
|
+
*
|
|
2128
|
+
* @public exported from `@promptbook/core`
|
|
2129
|
+
*/
|
|
2130
|
+
function getCommitmentDefinition(type) {
|
|
2131
|
+
return COMMITMENT_REGISTRY.find((commitmentDefinition) => commitmentDefinition.type === type) || null;
|
|
2132
|
+
}
|
|
2133
|
+
/**
|
|
2134
|
+
* Gets all available commitment definitions
|
|
2135
|
+
* @returns Array of all commitment definitions
|
|
2136
|
+
*
|
|
2137
|
+
* @public exported from `@promptbook/core`
|
|
2138
|
+
*/
|
|
2139
|
+
function getAllCommitmentDefinitions() {
|
|
2140
|
+
return $deepFreeze([...COMMITMENT_REGISTRY]);
|
|
2141
|
+
}
|
|
2142
|
+
/**
|
|
2143
|
+
* Gets all available commitment types
|
|
2144
|
+
* @returns Array of all commitment types
|
|
2145
|
+
*
|
|
2146
|
+
* @public exported from `@promptbook/core`
|
|
2147
|
+
*/
|
|
2148
|
+
function getAllCommitmentTypes() {
|
|
2149
|
+
return $deepFreeze(COMMITMENT_REGISTRY.map((commitmentDefinition) => commitmentDefinition.type));
|
|
2150
|
+
}
|
|
2151
|
+
/**
|
|
2152
|
+
* Checks if a commitment type is supported
|
|
2153
|
+
* @param type The commitment type to check
|
|
2154
|
+
* @returns True if the commitment type is supported
|
|
2155
|
+
*
|
|
2156
|
+
* @public exported from `@promptbook/core`
|
|
2157
|
+
*/
|
|
2158
|
+
function isCommitmentSupported(type) {
|
|
2159
|
+
return COMMITMENT_REGISTRY.some((commitmentDefinition) => commitmentDefinition.type === type);
|
|
2160
|
+
}
|
|
2161
|
+
/**
|
|
2162
|
+
* TODO: !!!! Maybe create through standardized $register
|
|
2163
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2164
|
+
*/
|
|
2165
|
+
|
|
2166
|
+
/**
|
|
2167
|
+
* Parses agent source using the new commitment system with multiline support
|
|
2168
|
+
* This function replaces the hardcoded commitment parsing in the original parseAgentSource
|
|
2169
|
+
*
|
|
2170
|
+
* @private
|
|
2171
|
+
*/
|
|
2172
|
+
function parseAgentSourceWithCommitments(agentSource) {
|
|
2173
|
+
var _a, _b, _c;
|
|
2174
|
+
if (!agentSource || !agentSource.trim()) {
|
|
2175
|
+
return {
|
|
2176
|
+
agentName: null,
|
|
2177
|
+
commitments: [],
|
|
2178
|
+
nonCommitmentLines: [],
|
|
2179
|
+
};
|
|
2180
|
+
}
|
|
2181
|
+
const lines = agentSource.split('\n');
|
|
2182
|
+
const agentName = (((_a = lines[0]) === null || _a === void 0 ? void 0 : _a.trim()) || null);
|
|
2183
|
+
const commitments = [];
|
|
2184
|
+
const nonCommitmentLines = [];
|
|
2185
|
+
// Always add the first line (agent name) to non-commitment lines
|
|
2186
|
+
if (lines[0] !== undefined) {
|
|
2187
|
+
nonCommitmentLines.push(lines[0]);
|
|
2188
|
+
}
|
|
2189
|
+
// Parse commitments with multiline support
|
|
2190
|
+
let currentCommitment = null;
|
|
2191
|
+
// Process lines starting from the second line (skip agent name)
|
|
2192
|
+
for (let i = 1; i < lines.length; i++) {
|
|
2193
|
+
const line = lines[i];
|
|
2194
|
+
if (line === undefined) {
|
|
2195
|
+
continue;
|
|
2196
|
+
}
|
|
2197
|
+
// Check if this line starts a new commitment
|
|
2198
|
+
let foundNewCommitment = false;
|
|
2199
|
+
for (const definition of COMMITMENT_REGISTRY) {
|
|
2200
|
+
const typeRegex = definition.createTypeRegex();
|
|
2201
|
+
const match = typeRegex.exec(line.trim());
|
|
2202
|
+
if (match && ((_b = match.groups) === null || _b === void 0 ? void 0 : _b.type)) {
|
|
2203
|
+
// Save the previous commitment if it exists
|
|
2204
|
+
if (currentCommitment) {
|
|
2205
|
+
const fullContent = currentCommitment.contentLines.join('\n');
|
|
2206
|
+
commitments.push({
|
|
2207
|
+
type: currentCommitment.type,
|
|
2208
|
+
content: spaceTrim(fullContent),
|
|
2209
|
+
originalLine: currentCommitment.originalStartLine,
|
|
2210
|
+
lineNumber: currentCommitment.startLineNumber,
|
|
2211
|
+
});
|
|
2212
|
+
}
|
|
2213
|
+
// Extract the initial content from the commitment line
|
|
2214
|
+
const fullRegex = definition.createRegex();
|
|
2215
|
+
const fullMatch = fullRegex.exec(line.trim());
|
|
2216
|
+
const initialContent = ((_c = fullMatch === null || fullMatch === void 0 ? void 0 : fullMatch.groups) === null || _c === void 0 ? void 0 : _c.contents) || '';
|
|
2217
|
+
// Start a new commitment
|
|
2218
|
+
currentCommitment = {
|
|
2219
|
+
type: definition.type,
|
|
2220
|
+
startLineNumber: i + 1,
|
|
2221
|
+
originalStartLine: line,
|
|
2222
|
+
contentLines: initialContent ? [initialContent] : [],
|
|
2223
|
+
};
|
|
2224
|
+
foundNewCommitment = true;
|
|
2225
|
+
break;
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
if (!foundNewCommitment) {
|
|
2229
|
+
if (currentCommitment) {
|
|
2230
|
+
// This line belongs to the current commitment
|
|
2231
|
+
currentCommitment.contentLines.push(line);
|
|
2232
|
+
}
|
|
2233
|
+
else {
|
|
2234
|
+
// This line is not part of any commitment
|
|
2235
|
+
nonCommitmentLines.push(line);
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
// Don't forget to save the last commitment if it exists
|
|
2240
|
+
if (currentCommitment) {
|
|
2241
|
+
const fullContent = currentCommitment.contentLines.join('\n');
|
|
2242
|
+
commitments.push({
|
|
2243
|
+
type: currentCommitment.type,
|
|
2244
|
+
content: spaceTrim(fullContent),
|
|
2245
|
+
originalLine: currentCommitment.originalStartLine,
|
|
2246
|
+
lineNumber: currentCommitment.startLineNumber,
|
|
2247
|
+
});
|
|
2248
|
+
}
|
|
2249
|
+
return {
|
|
2250
|
+
agentName,
|
|
2251
|
+
commitments,
|
|
2252
|
+
nonCommitmentLines,
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
/**
|
|
2256
|
+
* Extracts basic information from agent source using the new commitment system
|
|
2257
|
+
* This maintains compatibility with the original parseAgentSource interface
|
|
2258
|
+
*
|
|
2259
|
+
* @private
|
|
2260
|
+
*/
|
|
2261
|
+
function parseAgentSourceBasicInfo(agentSource) {
|
|
2262
|
+
const parseResult = parseAgentSourceWithCommitments(agentSource);
|
|
2263
|
+
// Find PERSONA and META IMAGE commitments
|
|
2264
|
+
let personaDescription = null;
|
|
2265
|
+
let profileImageUrl;
|
|
2266
|
+
for (const commitment of parseResult.commitments) {
|
|
2267
|
+
if (commitment.type === 'PERSONA' && !personaDescription) {
|
|
2268
|
+
personaDescription = commitment.content;
|
|
2269
|
+
}
|
|
2270
|
+
else if (commitment.type === 'META IMAGE' && !profileImageUrl) {
|
|
2271
|
+
profileImageUrl = commitment.content;
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
// Generate gravatar fallback if no profile image specified
|
|
2275
|
+
if (!profileImageUrl) {
|
|
2276
|
+
profileImageUrl = generateGravatarUrl(parseResult.agentName);
|
|
2277
|
+
}
|
|
2278
|
+
return {
|
|
2279
|
+
agentName: parseResult.agentName,
|
|
2280
|
+
personaDescription,
|
|
2281
|
+
profileImageUrl,
|
|
2282
|
+
};
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2285
|
+
/**
|
|
2286
|
+
* Parses agent source string into its components
|
|
2287
|
+
*/
|
|
2288
|
+
// Cache for parsed agent sources to prevent repeated parsing
|
|
2289
|
+
const parsedAgentSourceCache = new Map();
|
|
2290
|
+
/**
|
|
2291
|
+
* Parses basic information from agent source
|
|
2292
|
+
*
|
|
2293
|
+
* There are 2 similar functions:
|
|
2294
|
+
* - `parseAgentSource` which is a lightweight parser for agent source, it parses basic information and its purpose is to be quick and synchronous. The commitments there are hardcoded.
|
|
2295
|
+
* - `createAgentModelRequirements` which is an asynchronous function that creates model requirements it applies each commitment one by one and works asynchronously.
|
|
2296
|
+
*
|
|
2297
|
+
* @public exported from `@promptbook/core`
|
|
2298
|
+
*/
|
|
2299
|
+
function parseAgentSource(agentSource) {
|
|
2300
|
+
// Check if we already parsed this agent source
|
|
2301
|
+
if (parsedAgentSourceCache.has(agentSource)) {
|
|
2302
|
+
return parsedAgentSourceCache.get(agentSource);
|
|
2303
|
+
}
|
|
2304
|
+
// Use the new commitment-based parsing system
|
|
2305
|
+
const result = parseAgentSourceBasicInfo(agentSource);
|
|
2306
|
+
// Cache the result
|
|
2307
|
+
parsedAgentSourceCache.set(agentSource, result);
|
|
2308
|
+
return result;
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
/**
|
|
2312
|
+
* Type guard to check if a string is a valid agent source
|
|
2313
|
+
*
|
|
2314
|
+
* @public exported from `@promptbook/core`
|
|
2315
|
+
*/
|
|
2316
|
+
function isValidBook(value) {
|
|
2317
|
+
// Basic validation - agent source should have at least a name (first line)
|
|
2318
|
+
return typeof value === 'string' /* && value.trim().length > 0 */;
|
|
2319
|
+
}
|
|
2320
|
+
/**
|
|
2321
|
+
* Validates and converts a string to agent source branded type
|
|
2322
|
+
* This function should be used when you have a string that you know represents agent source
|
|
2323
|
+
* but need to convert it to the branded type for type safety
|
|
2324
|
+
*
|
|
2325
|
+
* @public exported from `@promptbook/core`
|
|
2326
|
+
*/
|
|
2327
|
+
function validateBook(source) {
|
|
2328
|
+
if (!isValidBook(source)) {
|
|
2329
|
+
throw new Error('Invalid agent source: must be a string');
|
|
2330
|
+
}
|
|
2331
|
+
return source;
|
|
2332
|
+
}
|
|
2333
|
+
/**
|
|
2334
|
+
* Default book
|
|
2335
|
+
*
|
|
2336
|
+
* @public exported from `@promptbook/core`
|
|
2337
|
+
*/
|
|
2338
|
+
const DEFAULT_BOOK = validateBook(spaceTrim$1(`
|
|
2339
|
+
AI Avatar
|
|
2340
|
+
|
|
2341
|
+
PERSONA A friendly AI assistant that helps you with your tasks
|
|
2342
|
+
`));
|
|
2343
|
+
|
|
2344
|
+
/**
|
|
2345
|
+
* Creates an empty/basic agent model requirements object
|
|
2346
|
+
* This serves as the starting point for the reduce-like pattern
|
|
2347
|
+
* where each commitment applies its changes to build the final requirements
|
|
2348
|
+
*
|
|
2349
|
+
* @public exported from `@promptbook/core`
|
|
2350
|
+
*/
|
|
2351
|
+
function createEmptyAgentModelRequirements() {
|
|
2352
|
+
return {
|
|
2353
|
+
systemMessage: '',
|
|
2354
|
+
modelName: '!!!!DEFAULT_MODEL_ID',
|
|
2355
|
+
temperature: 0.7,
|
|
2356
|
+
topP: 0.9,
|
|
2357
|
+
topK: 50,
|
|
2358
|
+
};
|
|
2359
|
+
}
|
|
2360
|
+
/**
|
|
2361
|
+
* Creates a basic agent model requirements with just the agent name
|
|
2362
|
+
* This is used when we have an agent name but no commitments
|
|
2363
|
+
*
|
|
2364
|
+
* @public exported from `@promptbook/core`
|
|
2365
|
+
*/
|
|
2366
|
+
function createBasicAgentModelRequirements(agentName) {
|
|
2367
|
+
const empty = createEmptyAgentModelRequirements();
|
|
2368
|
+
return {
|
|
2369
|
+
...empty,
|
|
2370
|
+
systemMessage: `You are ${agentName || 'AI Agent'}`,
|
|
2371
|
+
};
|
|
2372
|
+
}
|
|
2373
|
+
/**
|
|
2374
|
+
* TODO: !!!! Deduplicate model requirements
|
|
2375
|
+
*/
|
|
2376
|
+
|
|
2377
|
+
/**
|
|
2378
|
+
* Removes comment lines (lines starting with #) from a system message
|
|
2379
|
+
* This is used to clean up the final system message before sending it to the AI model
|
|
2380
|
+
* while preserving the original content with comments in metadata
|
|
2381
|
+
*
|
|
2382
|
+
* @param systemMessage The system message that may contain comment lines
|
|
2383
|
+
* @returns The system message with comment lines removed
|
|
2384
|
+
*
|
|
2385
|
+
* @private - TODO: [🧠] Maybe should be public?
|
|
2386
|
+
*/
|
|
2387
|
+
function removeCommentsFromSystemMessage(systemMessage) {
|
|
2388
|
+
if (!systemMessage) {
|
|
2389
|
+
return systemMessage;
|
|
2390
|
+
}
|
|
2391
|
+
const lines = systemMessage.split('\n');
|
|
2392
|
+
const filteredLines = lines.filter((line) => {
|
|
2393
|
+
const trimmedLine = line.trim();
|
|
2394
|
+
// Remove lines that start with # (comments)
|
|
2395
|
+
return !trimmedLine.startsWith('#');
|
|
2396
|
+
});
|
|
2397
|
+
return filteredLines.join('\n').trim();
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
/**
|
|
2401
|
+
* Creates agent model requirements using the new commitment system
|
|
2402
|
+
* This function uses a reduce-like pattern where each commitment applies its changes
|
|
2403
|
+
* to build the final requirements starting from a basic empty model
|
|
2404
|
+
*
|
|
2405
|
+
* @private
|
|
2406
|
+
*/
|
|
2407
|
+
async function createAgentModelRequirementsWithCommitments(agentSource, modelName) {
|
|
2408
|
+
// Parse the agent source to extract commitments
|
|
2409
|
+
const parseResult = parseAgentSourceWithCommitments(agentSource);
|
|
2410
|
+
// Start with basic agent model requirements
|
|
2411
|
+
let requirements = createBasicAgentModelRequirements(parseResult.agentName);
|
|
2412
|
+
// Store the agent name in metadata so commitments can access it
|
|
2413
|
+
requirements = {
|
|
2414
|
+
...requirements,
|
|
2415
|
+
metadata: {
|
|
2416
|
+
...requirements.metadata,
|
|
2417
|
+
agentName: parseResult.agentName,
|
|
2418
|
+
},
|
|
2419
|
+
};
|
|
2420
|
+
// Override model name if provided
|
|
2421
|
+
if (modelName) {
|
|
2422
|
+
requirements = {
|
|
2423
|
+
...requirements,
|
|
2424
|
+
modelName,
|
|
2425
|
+
};
|
|
2426
|
+
}
|
|
2427
|
+
// Apply each commitment in order using reduce-like pattern
|
|
2428
|
+
for (const commitment of parseResult.commitments) {
|
|
2429
|
+
const definition = getCommitmentDefinition(commitment.type);
|
|
2430
|
+
if (definition) {
|
|
2431
|
+
try {
|
|
2432
|
+
requirements = definition.applyToAgentModelRequirements(requirements, commitment.content);
|
|
2433
|
+
}
|
|
2434
|
+
catch (error) {
|
|
2435
|
+
console.warn(`Failed to apply commitment ${commitment.type}:`, error);
|
|
2436
|
+
// Continue with other commitments even if one fails
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
// Handle MCP servers (extract from original agent source)
|
|
2441
|
+
const mcpServers = extractMcpServers(agentSource);
|
|
2442
|
+
if (mcpServers.length > 0) {
|
|
2443
|
+
requirements = {
|
|
2444
|
+
...requirements,
|
|
2445
|
+
mcpServers,
|
|
2446
|
+
};
|
|
2447
|
+
}
|
|
2448
|
+
// Add non-commitment lines to system message if they exist
|
|
2449
|
+
const nonCommitmentContent = parseResult.nonCommitmentLines
|
|
2450
|
+
.filter((line, index) => index > 0 || !parseResult.agentName) // Skip first line if it's the agent name
|
|
2451
|
+
.filter((line) => line.trim()) // Remove empty lines
|
|
2452
|
+
.join('\n')
|
|
2453
|
+
.trim();
|
|
2454
|
+
if (nonCommitmentContent) {
|
|
2455
|
+
requirements = {
|
|
2456
|
+
...requirements,
|
|
2457
|
+
systemMessage: requirements.systemMessage + '\n\n' + nonCommitmentContent,
|
|
2458
|
+
};
|
|
2459
|
+
}
|
|
2460
|
+
// Remove comment lines (lines starting with #) from the final system message
|
|
2461
|
+
// while preserving the original content with comments in metadata
|
|
2462
|
+
const cleanedSystemMessage = removeCommentsFromSystemMessage(requirements.systemMessage);
|
|
2463
|
+
return {
|
|
2464
|
+
...requirements,
|
|
2465
|
+
systemMessage: cleanedSystemMessage,
|
|
2466
|
+
};
|
|
2467
|
+
}
|
|
2468
|
+
/**
|
|
2469
|
+
* Cache for expensive createAgentModelRequirementsWithCommitments calls
|
|
2470
|
+
* @private
|
|
2471
|
+
*/
|
|
2472
|
+
const modelRequirementsCache = new Map();
|
|
2473
|
+
/**
|
|
2474
|
+
* @private - TODO: Maybe should be public
|
|
2475
|
+
*/
|
|
2476
|
+
const CACHE_SIZE_LIMIT = 100;
|
|
2477
|
+
/**
|
|
2478
|
+
* Cached version of createAgentModelRequirementsWithCommitments
|
|
2479
|
+
* This maintains the same caching behavior as the original function
|
|
2480
|
+
*
|
|
2481
|
+
* @private
|
|
2482
|
+
*/
|
|
2483
|
+
async function createAgentModelRequirementsWithCommitmentsCached(agentSource, modelName) {
|
|
2484
|
+
// Create cache key
|
|
2485
|
+
const cacheKey = `${agentSource}|${modelName || 'default'}`;
|
|
2486
|
+
// Check cache first
|
|
2487
|
+
if (modelRequirementsCache.has(cacheKey)) {
|
|
2488
|
+
return modelRequirementsCache.get(cacheKey);
|
|
2489
|
+
}
|
|
2490
|
+
// Limit cache size to prevent memory leaks
|
|
2491
|
+
if (modelRequirementsCache.size >= CACHE_SIZE_LIMIT) {
|
|
2492
|
+
const firstKey = modelRequirementsCache.keys().next().value;
|
|
2493
|
+
if (firstKey) {
|
|
2494
|
+
modelRequirementsCache.delete(firstKey);
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
// Create requirements
|
|
2498
|
+
const requirements = await createAgentModelRequirementsWithCommitments(agentSource, modelName);
|
|
2499
|
+
// Cache the result
|
|
2500
|
+
modelRequirementsCache.set(cacheKey, requirements);
|
|
2501
|
+
return requirements;
|
|
2502
|
+
}
|
|
2503
|
+
|
|
2504
|
+
// TODO: Remove or use:
|
|
2505
|
+
//const CACHE_SIZE_LIMIT = 100; // Prevent memory leaks by limiting cache size
|
|
2506
|
+
/**
|
|
2507
|
+
* Creates model requirements for an agent based on its source
|
|
2508
|
+
* Results are cached to improve performance for repeated calls with the same agentSource and modelName
|
|
2509
|
+
*
|
|
2510
|
+
* There are 2 similar functions:
|
|
2511
|
+
* - `parseAgentSource` which is a lightweight parser for agent source, it parses basic information and its purpose is to be quick and synchronous. The commitments there are hardcoded.
|
|
2512
|
+
* - `createAgentModelRequirements` which is an asynchronous function that creates model requirements it applies each commitment one by one and works asynchronously.
|
|
2513
|
+
*
|
|
2514
|
+
* @public exported from `@promptbook/core`
|
|
2515
|
+
*/
|
|
2516
|
+
async function createAgentModelRequirements(agentSource, modelName = '!!!!DEFAULT_MODEL_ID') {
|
|
2517
|
+
// Use the new commitment-based system
|
|
2518
|
+
return createAgentModelRequirementsWithCommitmentsCached(agentSource, modelName);
|
|
2519
|
+
}
|
|
2520
|
+
/**
|
|
2521
|
+
* Extracts MCP servers from agent source
|
|
2522
|
+
*
|
|
2523
|
+
* @param agentSource The agent source string that may contain MCP lines
|
|
2524
|
+
* @returns Array of MCP server identifiers
|
|
2525
|
+
*
|
|
2526
|
+
* @private TODO: [🧠] Maybe should be public
|
|
2527
|
+
*/
|
|
2528
|
+
function extractMcpServers(agentSource) {
|
|
2529
|
+
if (!agentSource) {
|
|
2530
|
+
return [];
|
|
2531
|
+
}
|
|
2532
|
+
const lines = agentSource.split('\n');
|
|
2533
|
+
const mcpRegex = /^\s*MCP\s+(.+)$/i;
|
|
2534
|
+
const mcpServers = [];
|
|
2535
|
+
// Look for MCP lines
|
|
2536
|
+
for (const line of lines) {
|
|
2537
|
+
const match = line.match(mcpRegex);
|
|
2538
|
+
if (match && match[1]) {
|
|
2539
|
+
mcpServers.push(match[1].trim());
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
return mcpServers;
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
/**
|
|
2546
|
+
* Converts PipelineCollection to serialized JSON
|
|
2547
|
+
*
|
|
2548
|
+
* Note: Functions `collectionToJson` and `createCollectionFromJson` are complementary
|
|
2549
|
+
*
|
|
2550
|
+
* @public exported from `@promptbook/core`
|
|
2551
|
+
*/
|
|
2552
|
+
async function collectionToJson(collection) {
|
|
2553
|
+
const pipelineUrls = await collection.listPipelines();
|
|
2554
|
+
const promptbooks = await Promise.all(pipelineUrls.map((url) => collection.getPipelineByUrl(url)));
|
|
2555
|
+
return promptbooks;
|
|
2556
|
+
}
|
|
2557
|
+
/**
|
|
2558
|
+
* TODO: [🧠] Maybe clear `sourceFile` or clear when exposing through API or remote server
|
|
2559
|
+
*/
|
|
2560
|
+
|
|
2561
|
+
/**
|
|
2562
|
+
* Checks if value is valid email
|
|
2563
|
+
*
|
|
2564
|
+
* @public exported from `@promptbook/utils`
|
|
2565
|
+
*/
|
|
2566
|
+
function isValidEmail(email) {
|
|
2567
|
+
if (typeof email !== 'string') {
|
|
2568
|
+
return false;
|
|
2569
|
+
}
|
|
2570
|
+
if (email.split('\n').length > 1) {
|
|
2571
|
+
return false;
|
|
2572
|
+
}
|
|
2573
|
+
return /^.+@.+\..+$/.test(email);
|
|
2574
|
+
}
|
|
2575
|
+
|
|
2576
|
+
/**
|
|
2577
|
+
* Tests if given string is valid URL.
|
|
2578
|
+
*
|
|
2579
|
+
* Note: This does not check if the file exists only if the path is valid
|
|
2580
|
+
* @public exported from `@promptbook/utils`
|
|
2581
|
+
*/
|
|
2582
|
+
function isValidFilePath(filename) {
|
|
2583
|
+
if (typeof filename !== 'string') {
|
|
2584
|
+
return false;
|
|
2585
|
+
}
|
|
2586
|
+
if (filename.split('\n').length > 1) {
|
|
2587
|
+
return false;
|
|
2588
|
+
}
|
|
2589
|
+
if (filename.split(' ').length >
|
|
2590
|
+
5 /* <- TODO: [🧠][🈷] Make some better non-arbitrary way how to distinct filenames from informational texts */) {
|
|
2591
|
+
return false;
|
|
2592
|
+
}
|
|
2593
|
+
const filenameSlashes = filename.split('\\').join('/');
|
|
2594
|
+
// Absolute Unix path: /hello.txt
|
|
2595
|
+
if (/^(\/)/i.test(filenameSlashes)) {
|
|
2596
|
+
// console.log(filename, 'Absolute Unix path: /hello.txt');
|
|
2597
|
+
return true;
|
|
2598
|
+
}
|
|
2599
|
+
// Absolute Windows path: /hello.txt
|
|
2600
|
+
if (/^([A-Z]{1,2}:\/?)\//i.test(filenameSlashes)) {
|
|
2601
|
+
// console.log(filename, 'Absolute Windows path: /hello.txt');
|
|
2602
|
+
return true;
|
|
2603
|
+
}
|
|
2604
|
+
// Relative path: ./hello.txt
|
|
2605
|
+
if (/^(\.\.?\/)+/i.test(filenameSlashes)) {
|
|
2606
|
+
// console.log(filename, 'Relative path: ./hello.txt');
|
|
2607
|
+
return true;
|
|
2608
|
+
}
|
|
2609
|
+
// Allow paths like foo/hello
|
|
2610
|
+
if (/^[^/]+\/[^/]+/i.test(filenameSlashes)) {
|
|
2611
|
+
// console.log(filename, 'Allow paths like foo/hello');
|
|
2612
|
+
return true;
|
|
2613
|
+
}
|
|
2614
|
+
// Allow paths like hello.book
|
|
2615
|
+
if (/^[^/]+\.[^/]+$/i.test(filenameSlashes)) {
|
|
2616
|
+
// console.log(filename, 'Allow paths like hello.book');
|
|
2617
|
+
return true;
|
|
2618
|
+
}
|
|
2619
|
+
return false;
|
|
2620
|
+
}
|
|
2621
|
+
/**
|
|
2622
|
+
* TODO: [🍏] Implement for MacOs
|
|
2623
|
+
*/
|
|
2624
|
+
|
|
2625
|
+
/**
|
|
2626
|
+
* Tests if given string is valid URL.
|
|
2627
|
+
*
|
|
2628
|
+
* Note: Dataurl are considered perfectly valid.
|
|
2629
|
+
* Note: There are two similar functions:
|
|
2630
|
+
* - `isValidUrl` which tests any URL
|
|
2631
|
+
* - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
|
|
2632
|
+
*
|
|
2633
|
+
* @public exported from `@promptbook/utils`
|
|
2634
|
+
*/
|
|
2635
|
+
function isValidUrl(url) {
|
|
2636
|
+
if (typeof url !== 'string') {
|
|
2637
|
+
return false;
|
|
2638
|
+
}
|
|
2639
|
+
try {
|
|
2640
|
+
if (url.startsWith('blob:')) {
|
|
2641
|
+
url = url.replace(/^blob:/, '');
|
|
2642
|
+
}
|
|
2643
|
+
const urlObject = new URL(url /* because fail is handled */);
|
|
2644
|
+
if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {
|
|
2645
|
+
return false;
|
|
2646
|
+
}
|
|
2647
|
+
return true;
|
|
2648
|
+
}
|
|
2649
|
+
catch (error) {
|
|
2650
|
+
return false;
|
|
618
2651
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2654
|
+
/**
|
|
2655
|
+
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
2656
|
+
*
|
|
2657
|
+
* @public exported from `@promptbook/core`
|
|
2658
|
+
*/
|
|
2659
|
+
class ParseError extends Error {
|
|
2660
|
+
constructor(message) {
|
|
2661
|
+
super(message);
|
|
2662
|
+
this.name = 'ParseError';
|
|
2663
|
+
Object.setPrototypeOf(this, ParseError.prototype);
|
|
622
2664
|
}
|
|
623
|
-
// Case 4: Handle non-standard errors - wrap them into `WrappedError` and throw
|
|
624
|
-
throw new WrappedError(whatWasThrown);
|
|
625
2665
|
}
|
|
2666
|
+
/**
|
|
2667
|
+
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
2668
|
+
*/
|
|
626
2669
|
|
|
627
2670
|
/**
|
|
628
2671
|
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
@@ -829,7 +2872,7 @@ function pipelineJsonToString(pipelineJson) {
|
|
|
829
2872
|
pipelineString += '\n\n';
|
|
830
2873
|
pipelineString += '```' + contentLanguage;
|
|
831
2874
|
pipelineString += '\n';
|
|
832
|
-
pipelineString += spaceTrim(content);
|
|
2875
|
+
pipelineString += spaceTrim$1(content);
|
|
833
2876
|
// <- TODO: [main] !!3 Escape
|
|
834
2877
|
// <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
|
|
835
2878
|
pipelineString += '\n';
|
|
@@ -873,33 +2916,6 @@ function orderJson(options) {
|
|
|
873
2916
|
return orderedValue;
|
|
874
2917
|
}
|
|
875
2918
|
|
|
876
|
-
/**
|
|
877
|
-
* Freezes the given object and all its nested objects recursively
|
|
878
|
-
*
|
|
879
|
-
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
880
|
-
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
881
|
-
*
|
|
882
|
-
* @returns The same object as the input, but deeply frozen
|
|
883
|
-
* @public exported from `@promptbook/utils`
|
|
884
|
-
*/
|
|
885
|
-
function $deepFreeze(objectValue) {
|
|
886
|
-
if (Array.isArray(objectValue)) {
|
|
887
|
-
return Object.freeze(objectValue.map((item) => $deepFreeze(item)));
|
|
888
|
-
}
|
|
889
|
-
const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
890
|
-
for (const propertyName of propertyNames) {
|
|
891
|
-
const value = objectValue[propertyName];
|
|
892
|
-
if (value && typeof value === 'object') {
|
|
893
|
-
$deepFreeze(value);
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
Object.freeze(objectValue);
|
|
897
|
-
return objectValue;
|
|
898
|
-
}
|
|
899
|
-
/**
|
|
900
|
-
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
901
|
-
*/
|
|
902
|
-
|
|
903
2919
|
/**
|
|
904
2920
|
* Checks if the value is [🚉] serializable as JSON
|
|
905
2921
|
* If not, throws an UnexpectedError with a rich error message and tracking
|
|
@@ -950,7 +2966,7 @@ function checkSerializableAsJson(options) {
|
|
|
950
2966
|
}
|
|
951
2967
|
else if (typeof value === 'object') {
|
|
952
2968
|
if (value instanceof Date) {
|
|
953
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
2969
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
954
2970
|
\`${name}\` is Date
|
|
955
2971
|
|
|
956
2972
|
Use \`string_date_iso8601\` instead
|
|
@@ -969,7 +2985,7 @@ function checkSerializableAsJson(options) {
|
|
|
969
2985
|
throw new UnexpectedError(`${name} is RegExp`);
|
|
970
2986
|
}
|
|
971
2987
|
else if (value instanceof Error) {
|
|
972
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
2988
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
973
2989
|
\`${name}\` is unserialized Error
|
|
974
2990
|
|
|
975
2991
|
Use function \`serializeError\`
|
|
@@ -992,7 +3008,7 @@ function checkSerializableAsJson(options) {
|
|
|
992
3008
|
}
|
|
993
3009
|
catch (error) {
|
|
994
3010
|
assertsError(error);
|
|
995
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
3011
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
996
3012
|
\`${name}\` is not serializable
|
|
997
3013
|
|
|
998
3014
|
${block(error.stack || error.message)}
|
|
@@ -1024,7 +3040,7 @@ function checkSerializableAsJson(options) {
|
|
|
1024
3040
|
}
|
|
1025
3041
|
}
|
|
1026
3042
|
else {
|
|
1027
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
3043
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1028
3044
|
\`${name}\` is unknown type
|
|
1029
3045
|
|
|
1030
3046
|
Additional message for \`${name}\`:
|
|
@@ -1311,7 +3327,7 @@ function validatePipeline(pipeline) {
|
|
|
1311
3327
|
if (!(error instanceof PipelineLogicError)) {
|
|
1312
3328
|
throw error;
|
|
1313
3329
|
}
|
|
1314
|
-
console.error(spaceTrim
|
|
3330
|
+
console.error(spaceTrim((block) => `
|
|
1315
3331
|
Pipeline is not valid but logic errors are temporarily disabled via \`IS_PIPELINE_LOGIC_VALIDATED\`
|
|
1316
3332
|
|
|
1317
3333
|
${block(error.message)}
|
|
@@ -1338,7 +3354,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1338
3354
|
})();
|
|
1339
3355
|
if (pipeline.pipelineUrl !== undefined && !isValidPipelineUrl(pipeline.pipelineUrl)) {
|
|
1340
3356
|
// <- Note: [🚲]
|
|
1341
|
-
throw new PipelineLogicError(spaceTrim
|
|
3357
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1342
3358
|
Invalid promptbook URL "${pipeline.pipelineUrl}"
|
|
1343
3359
|
|
|
1344
3360
|
${block(pipelineIdentification)}
|
|
@@ -1346,7 +3362,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1346
3362
|
}
|
|
1347
3363
|
if (pipeline.bookVersion !== undefined && !isValidPromptbookVersion(pipeline.bookVersion)) {
|
|
1348
3364
|
// <- Note: [🚲]
|
|
1349
|
-
throw new PipelineLogicError(spaceTrim
|
|
3365
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1350
3366
|
Invalid Promptbook Version "${pipeline.bookVersion}"
|
|
1351
3367
|
|
|
1352
3368
|
${block(pipelineIdentification)}
|
|
@@ -1355,7 +3371,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1355
3371
|
// TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
|
|
1356
3372
|
if (!Array.isArray(pipeline.parameters)) {
|
|
1357
3373
|
// TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
|
|
1358
|
-
throw new ParseError(spaceTrim
|
|
3374
|
+
throw new ParseError(spaceTrim((block) => `
|
|
1359
3375
|
Pipeline is valid JSON but with wrong structure
|
|
1360
3376
|
|
|
1361
3377
|
\`PipelineJson.parameters\` expected to be an array, but got ${typeof pipeline.parameters}
|
|
@@ -1366,7 +3382,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1366
3382
|
// TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
|
|
1367
3383
|
if (!Array.isArray(pipeline.tasks)) {
|
|
1368
3384
|
// TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
|
|
1369
|
-
throw new ParseError(spaceTrim
|
|
3385
|
+
throw new ParseError(spaceTrim((block) => `
|
|
1370
3386
|
Pipeline is valid JSON but with wrong structure
|
|
1371
3387
|
|
|
1372
3388
|
\`PipelineJson.tasks\` expected to be an array, but got ${typeof pipeline.tasks}
|
|
@@ -1392,7 +3408,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1392
3408
|
// Note: Check each parameter individually
|
|
1393
3409
|
for (const parameter of pipeline.parameters) {
|
|
1394
3410
|
if (parameter.isInput && parameter.isOutput) {
|
|
1395
|
-
throw new PipelineLogicError(spaceTrim
|
|
3411
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1396
3412
|
|
|
1397
3413
|
Parameter \`{${parameter.name}}\` can not be both input and output
|
|
1398
3414
|
|
|
@@ -1403,7 +3419,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1403
3419
|
if (!parameter.isInput &&
|
|
1404
3420
|
!parameter.isOutput &&
|
|
1405
3421
|
!pipeline.tasks.some((task) => task.dependentParameterNames.includes(parameter.name))) {
|
|
1406
|
-
throw new PipelineLogicError(spaceTrim
|
|
3422
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1407
3423
|
Parameter \`{${parameter.name}}\` is created but not used
|
|
1408
3424
|
|
|
1409
3425
|
You can declare {${parameter.name}} as output parameter by adding in the header:
|
|
@@ -1415,7 +3431,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1415
3431
|
}
|
|
1416
3432
|
// Note: Testing that parameter is either input or result of some task
|
|
1417
3433
|
if (!parameter.isInput && !pipeline.tasks.some((task) => task.resultingParameterName === parameter.name)) {
|
|
1418
|
-
throw new PipelineLogicError(spaceTrim
|
|
3434
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1419
3435
|
Parameter \`{${parameter.name}}\` is declared but not defined
|
|
1420
3436
|
|
|
1421
3437
|
You can do one of these:
|
|
@@ -1431,14 +3447,14 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1431
3447
|
// Note: Checking each task individually
|
|
1432
3448
|
for (const task of pipeline.tasks) {
|
|
1433
3449
|
if (definedParameters.has(task.resultingParameterName)) {
|
|
1434
|
-
throw new PipelineLogicError(spaceTrim
|
|
3450
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1435
3451
|
Parameter \`{${task.resultingParameterName}}\` is defined multiple times
|
|
1436
3452
|
|
|
1437
3453
|
${block(pipelineIdentification)}
|
|
1438
3454
|
`));
|
|
1439
3455
|
}
|
|
1440
3456
|
if (RESERVED_PARAMETER_NAMES.includes(task.resultingParameterName)) {
|
|
1441
|
-
throw new PipelineLogicError(spaceTrim
|
|
3457
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1442
3458
|
Parameter name {${task.resultingParameterName}} is reserved, please use different name
|
|
1443
3459
|
|
|
1444
3460
|
${block(pipelineIdentification)}
|
|
@@ -1448,7 +3464,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1448
3464
|
if (task.jokerParameterNames && task.jokerParameterNames.length > 0) {
|
|
1449
3465
|
if (!task.format &&
|
|
1450
3466
|
!task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
|
|
1451
|
-
throw new PipelineLogicError(spaceTrim
|
|
3467
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1452
3468
|
Joker parameters are used for {${task.resultingParameterName}} but no expectations are defined
|
|
1453
3469
|
|
|
1454
3470
|
${block(pipelineIdentification)}
|
|
@@ -1456,7 +3472,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1456
3472
|
}
|
|
1457
3473
|
for (const joker of task.jokerParameterNames) {
|
|
1458
3474
|
if (!task.dependentParameterNames.includes(joker)) {
|
|
1459
|
-
throw new PipelineLogicError(spaceTrim
|
|
3475
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1460
3476
|
Parameter \`{${joker}}\` is used for {${task.resultingParameterName}} as joker but not in \`dependentParameterNames\`
|
|
1461
3477
|
|
|
1462
3478
|
${block(pipelineIdentification)}
|
|
@@ -1467,21 +3483,21 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1467
3483
|
if (task.expectations) {
|
|
1468
3484
|
for (const [unit, { min, max }] of Object.entries(task.expectations)) {
|
|
1469
3485
|
if (min !== undefined && max !== undefined && min > max) {
|
|
1470
|
-
throw new PipelineLogicError(spaceTrim
|
|
3486
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1471
3487
|
Min expectation (=${min}) of ${unit} is higher than max expectation (=${max})
|
|
1472
3488
|
|
|
1473
3489
|
${block(pipelineIdentification)}
|
|
1474
3490
|
`));
|
|
1475
3491
|
}
|
|
1476
3492
|
if (min !== undefined && min < 0) {
|
|
1477
|
-
throw new PipelineLogicError(spaceTrim
|
|
3493
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1478
3494
|
Min expectation of ${unit} must be zero or positive
|
|
1479
3495
|
|
|
1480
3496
|
${block(pipelineIdentification)}
|
|
1481
3497
|
`));
|
|
1482
3498
|
}
|
|
1483
3499
|
if (max !== undefined && max <= 0) {
|
|
1484
|
-
throw new PipelineLogicError(spaceTrim
|
|
3500
|
+
throw new PipelineLogicError(spaceTrim((block) => `
|
|
1485
3501
|
Max expectation of ${unit} must be positive
|
|
1486
3502
|
|
|
1487
3503
|
${block(pipelineIdentification)}
|
|
@@ -1503,7 +3519,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1503
3519
|
while (unresovedTasks.length > 0) {
|
|
1504
3520
|
if (loopLimit-- < 0) {
|
|
1505
3521
|
// Note: Really UnexpectedError not LimitReachedError - this should not happen and be caught below
|
|
1506
|
-
throw new UnexpectedError(spaceTrim
|
|
3522
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
1507
3523
|
Loop limit reached during detection of circular dependencies in \`validatePipeline\`
|
|
1508
3524
|
|
|
1509
3525
|
${block(pipelineIdentification)}
|
|
@@ -1513,7 +3529,7 @@ function validatePipeline_InnerFunction(pipeline) {
|
|
|
1513
3529
|
if (currentlyResovedTasks.length === 0) {
|
|
1514
3530
|
throw new PipelineLogicError(
|
|
1515
3531
|
// TODO: [🐎] DRY
|
|
1516
|
-
spaceTrim
|
|
3532
|
+
spaceTrim((block) => `
|
|
1517
3533
|
|
|
1518
3534
|
Can not resolve some parameters:
|
|
1519
3535
|
Either you are using a parameter that is not defined, or there are some circular dependencies.
|
|
@@ -1677,7 +3693,7 @@ class SimplePipelineCollection {
|
|
|
1677
3693
|
for (const pipeline of pipelines) {
|
|
1678
3694
|
// TODO: [👠] DRY
|
|
1679
3695
|
if (pipeline.pipelineUrl === undefined) {
|
|
1680
|
-
throw new PipelineUrlError(spaceTrim
|
|
3696
|
+
throw new PipelineUrlError(spaceTrim(`
|
|
1681
3697
|
Pipeline with name "${pipeline.title}" does not have defined URL
|
|
1682
3698
|
|
|
1683
3699
|
File:
|
|
@@ -1699,7 +3715,7 @@ class SimplePipelineCollection {
|
|
|
1699
3715
|
pipelineJsonToString(unpreparePipeline(pipeline)) !==
|
|
1700
3716
|
pipelineJsonToString(unpreparePipeline(this.collection.get(pipeline.pipelineUrl)))) {
|
|
1701
3717
|
const existing = this.collection.get(pipeline.pipelineUrl);
|
|
1702
|
-
throw new PipelineUrlError(spaceTrim
|
|
3718
|
+
throw new PipelineUrlError(spaceTrim(`
|
|
1703
3719
|
Pipeline with URL ${pipeline.pipelineUrl} is already in the collection 🍎
|
|
1704
3720
|
|
|
1705
3721
|
Conflicting files:
|
|
@@ -1731,13 +3747,13 @@ class SimplePipelineCollection {
|
|
|
1731
3747
|
const pipeline = this.collection.get(url);
|
|
1732
3748
|
if (!pipeline) {
|
|
1733
3749
|
if (this.listPipelines().length === 0) {
|
|
1734
|
-
throw new NotFoundError(spaceTrim
|
|
3750
|
+
throw new NotFoundError(spaceTrim(`
|
|
1735
3751
|
Pipeline with url "${url}" not found
|
|
1736
3752
|
|
|
1737
3753
|
No pipelines available
|
|
1738
3754
|
`));
|
|
1739
3755
|
}
|
|
1740
|
-
throw new NotFoundError(spaceTrim
|
|
3756
|
+
throw new NotFoundError(spaceTrim((block) => `
|
|
1741
3757
|
Pipeline with url "${url}" not found
|
|
1742
3758
|
|
|
1743
3759
|
Available pipelines:
|
|
@@ -1867,7 +3883,7 @@ function createSubcollection(collection, predicate) {
|
|
|
1867
3883
|
}
|
|
1868
3884
|
async function getPipelineByUrl(url) {
|
|
1869
3885
|
if (!predicate(url)) {
|
|
1870
|
-
throw new NotFoundError(await spaceTrim
|
|
3886
|
+
throw new NotFoundError(await spaceTrim(async (block) => `
|
|
1871
3887
|
Promptbook with url "${url}" not found or not accessible
|
|
1872
3888
|
|
|
1873
3889
|
Available promptbooks:
|
|
@@ -1902,7 +3918,7 @@ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"
|
|
|
1902
3918
|
*/
|
|
1903
3919
|
class MissingToolsError extends Error {
|
|
1904
3920
|
constructor(message) {
|
|
1905
|
-
super(spaceTrim
|
|
3921
|
+
super(spaceTrim((block) => `
|
|
1906
3922
|
${block(message)}
|
|
1907
3923
|
|
|
1908
3924
|
Note: You have probably forgot to provide some tools for pipeline execution or preparation
|
|
@@ -2071,7 +4087,7 @@ class LimitReachedError extends Error {
|
|
|
2071
4087
|
*/
|
|
2072
4088
|
class NotYetImplementedError extends Error {
|
|
2073
4089
|
constructor(message) {
|
|
2074
|
-
super(spaceTrim
|
|
4090
|
+
super(spaceTrim((block) => `
|
|
2075
4091
|
${block(message)}
|
|
2076
4092
|
|
|
2077
4093
|
Note: This feature is not implemented yet but it will be soon.
|
|
@@ -2121,19 +4137,6 @@ class PipelineExecutionError extends Error {
|
|
|
2121
4137
|
* TODO: [🧠][🌂] Add id to all errors
|
|
2122
4138
|
*/
|
|
2123
4139
|
|
|
2124
|
-
/**
|
|
2125
|
-
* Error thrown when a fetch request fails
|
|
2126
|
-
*
|
|
2127
|
-
* @public exported from `@promptbook/core`
|
|
2128
|
-
*/
|
|
2129
|
-
class PromptbookFetchError extends Error {
|
|
2130
|
-
constructor(message) {
|
|
2131
|
-
super(message);
|
|
2132
|
-
this.name = 'PromptbookFetchError';
|
|
2133
|
-
Object.setPrototypeOf(this, PromptbookFetchError.prototype);
|
|
2134
|
-
}
|
|
2135
|
-
}
|
|
2136
|
-
|
|
2137
4140
|
/**
|
|
2138
4141
|
* Index of all custom errors
|
|
2139
4142
|
*
|
|
@@ -2205,7 +4208,7 @@ function serializeError(error) {
|
|
|
2205
4208
|
const { name, message, stack } = error;
|
|
2206
4209
|
const { id } = error;
|
|
2207
4210
|
if (!Object.keys(ALL_ERRORS).includes(name)) {
|
|
2208
|
-
console.error(spaceTrim((block) => `
|
|
4211
|
+
console.error(spaceTrim$1((block) => `
|
|
2209
4212
|
|
|
2210
4213
|
Cannot serialize error with name "${name}"
|
|
2211
4214
|
|
|
@@ -2238,7 +4241,7 @@ function jsonParse(value) {
|
|
|
2238
4241
|
}
|
|
2239
4242
|
else if (typeof value !== 'string') {
|
|
2240
4243
|
console.error('Can not parse JSON from non-string value.', { text: value });
|
|
2241
|
-
throw new Error(spaceTrim(`
|
|
4244
|
+
throw new Error(spaceTrim$1(`
|
|
2242
4245
|
Can not parse JSON from non-string value.
|
|
2243
4246
|
|
|
2244
4247
|
The value type: ${typeof value}
|
|
@@ -2252,7 +4255,7 @@ function jsonParse(value) {
|
|
|
2252
4255
|
if (!(error instanceof Error)) {
|
|
2253
4256
|
throw error;
|
|
2254
4257
|
}
|
|
2255
|
-
throw new Error(spaceTrim((block) => `
|
|
4258
|
+
throw new Error(spaceTrim$1((block) => `
|
|
2256
4259
|
${block(error.message)}
|
|
2257
4260
|
|
|
2258
4261
|
The expected JSON text:
|
|
@@ -2305,7 +4308,7 @@ function deserializeError(error) {
|
|
|
2305
4308
|
message = `${name}: ${message}`;
|
|
2306
4309
|
}
|
|
2307
4310
|
if (stack !== undefined && stack !== '') {
|
|
2308
|
-
message = spaceTrim((block) => `
|
|
4311
|
+
message = spaceTrim$1((block) => `
|
|
2309
4312
|
${block(message)}
|
|
2310
4313
|
|
|
2311
4314
|
Original stack trace:
|
|
@@ -2342,11 +4345,11 @@ function assertsTaskSuccessful(executionResult) {
|
|
|
2342
4345
|
throw deserializeError(errors[0]);
|
|
2343
4346
|
}
|
|
2344
4347
|
else {
|
|
2345
|
-
throw new PipelineExecutionError(spaceTrim
|
|
4348
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
2346
4349
|
Multiple errors occurred during Promptbook execution
|
|
2347
4350
|
|
|
2348
4351
|
${block(errors
|
|
2349
|
-
.map(({ name, stack, message }, index) => spaceTrim
|
|
4352
|
+
.map(({ name, stack, message }, index) => spaceTrim((block) => `
|
|
2350
4353
|
${name} ${index + 1}:
|
|
2351
4354
|
${block(stack || message)}
|
|
2352
4355
|
`))
|
|
@@ -2364,7 +4367,7 @@ function assertsTaskSuccessful(executionResult) {
|
|
|
2364
4367
|
* @private internal helper function
|
|
2365
4368
|
*/
|
|
2366
4369
|
function createTask(options) {
|
|
2367
|
-
const { taskType, taskProcessCallback } = options;
|
|
4370
|
+
const { taskType, taskProcessCallback, tldrProvider } = options;
|
|
2368
4371
|
let { title } = options;
|
|
2369
4372
|
// TODO: [🐙] DRY
|
|
2370
4373
|
const taskId = `${taskType.toLowerCase().substring(0, 4)}-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid similar char conflicts */)}`;
|
|
@@ -2437,6 +4440,78 @@ function createTask(options) {
|
|
|
2437
4440
|
return status;
|
|
2438
4441
|
// <- Note: [1] --||--
|
|
2439
4442
|
},
|
|
4443
|
+
get tldr() {
|
|
4444
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
4445
|
+
// Use custom tldr provider if available
|
|
4446
|
+
if (tldrProvider) {
|
|
4447
|
+
return tldrProvider(createdAt, status, currentValue, errors, warnings);
|
|
4448
|
+
}
|
|
4449
|
+
// Fallback to default implementation
|
|
4450
|
+
const cv = currentValue;
|
|
4451
|
+
// If explicit percent is provided, use it
|
|
4452
|
+
let percentRaw = (_f = (_d = (_b = (_a = cv === null || cv === void 0 ? void 0 : cv.tldr) === null || _a === void 0 ? void 0 : _a.percent) !== null && _b !== void 0 ? _b : (_c = cv === null || cv === void 0 ? void 0 : cv.usage) === null || _c === void 0 ? void 0 : _c.percent) !== null && _d !== void 0 ? _d : (_e = cv === null || cv === void 0 ? void 0 : cv.progress) === null || _e === void 0 ? void 0 : _e.percent) !== null && _f !== void 0 ? _f : cv === null || cv === void 0 ? void 0 : cv.percent;
|
|
4453
|
+
// Simulate progress if not provided
|
|
4454
|
+
if (typeof percentRaw !== 'number') {
|
|
4455
|
+
// Simulate progress: evenly split across subtasks, based on elapsed time
|
|
4456
|
+
const now = new Date();
|
|
4457
|
+
const elapsedMs = now.getTime() - createdAt.getTime();
|
|
4458
|
+
const totalMs = DEFAULT_TASK_SIMULATED_DURATION_MS;
|
|
4459
|
+
// If subtasks are defined, split progress evenly
|
|
4460
|
+
const subtaskCount = Array.isArray(cv === null || cv === void 0 ? void 0 : cv.subtasks) ? cv.subtasks.length : 1;
|
|
4461
|
+
const completedSubtasks = Array.isArray(cv === null || cv === void 0 ? void 0 : cv.subtasks)
|
|
4462
|
+
? cv.subtasks.filter((s) => s.done || s.completed).length
|
|
4463
|
+
: 0;
|
|
4464
|
+
// Progress from completed subtasks
|
|
4465
|
+
const subtaskProgress = subtaskCount > 0 ? completedSubtasks / subtaskCount : 0;
|
|
4466
|
+
// Progress from elapsed time for current subtask
|
|
4467
|
+
const timeProgress = Math.min(elapsedMs / totalMs, 1);
|
|
4468
|
+
// Combine: completed subtasks + time progress for current subtask
|
|
4469
|
+
percentRaw = Math.min(subtaskProgress + (1 / subtaskCount) * timeProgress, 1);
|
|
4470
|
+
if (status === 'FINISHED')
|
|
4471
|
+
percentRaw = 1;
|
|
4472
|
+
if (status === 'ERROR')
|
|
4473
|
+
percentRaw = 0;
|
|
4474
|
+
}
|
|
4475
|
+
// Clamp to [0,1]
|
|
4476
|
+
let percent = Number(percentRaw) || 0;
|
|
4477
|
+
if (percent < 0)
|
|
4478
|
+
percent = 0;
|
|
4479
|
+
if (percent > 1)
|
|
4480
|
+
percent = 1;
|
|
4481
|
+
// Build a short message: prefer explicit tldr.message, then common summary/message fields, then errors/warnings, then status
|
|
4482
|
+
const messageFromResult = (_k = (_j = (_h = (_g = cv === null || cv === void 0 ? void 0 : cv.tldr) === null || _g === void 0 ? void 0 : _g.message) !== null && _h !== void 0 ? _h : cv === null || cv === void 0 ? void 0 : cv.message) !== null && _j !== void 0 ? _j : cv === null || cv === void 0 ? void 0 : cv.summary) !== null && _k !== void 0 ? _k : cv === null || cv === void 0 ? void 0 : cv.statusMessage;
|
|
4483
|
+
let message = messageFromResult;
|
|
4484
|
+
if (!message) {
|
|
4485
|
+
// If subtasks, show current subtask
|
|
4486
|
+
if (Array.isArray(cv === null || cv === void 0 ? void 0 : cv.subtasks) && cv.subtasks.length > 0) {
|
|
4487
|
+
const current = cv.subtasks.find((s) => !s.done && !s.completed);
|
|
4488
|
+
if (current && current.title) {
|
|
4489
|
+
message = `Working on ${current.title}`;
|
|
4490
|
+
}
|
|
4491
|
+
}
|
|
4492
|
+
if (!message) {
|
|
4493
|
+
if (errors.length) {
|
|
4494
|
+
message = errors[errors.length - 1].message || 'Error';
|
|
4495
|
+
}
|
|
4496
|
+
else if (warnings.length) {
|
|
4497
|
+
message = warnings[warnings.length - 1].message || 'Warning';
|
|
4498
|
+
}
|
|
4499
|
+
else if (status === 'FINISHED') {
|
|
4500
|
+
message = 'Finished';
|
|
4501
|
+
}
|
|
4502
|
+
else if (status === 'ERROR') {
|
|
4503
|
+
message = 'Error';
|
|
4504
|
+
}
|
|
4505
|
+
else {
|
|
4506
|
+
message = 'Running';
|
|
4507
|
+
}
|
|
4508
|
+
}
|
|
4509
|
+
}
|
|
4510
|
+
return {
|
|
4511
|
+
percent: percent,
|
|
4512
|
+
message,
|
|
4513
|
+
};
|
|
4514
|
+
},
|
|
2440
4515
|
get createdAt() {
|
|
2441
4516
|
return createdAt;
|
|
2442
4517
|
// <- Note: [1] --||--
|
|
@@ -2716,7 +4791,7 @@ function extractVariablesFromJavascript(script) {
|
|
|
2716
4791
|
}
|
|
2717
4792
|
catch (error) {
|
|
2718
4793
|
assertsError(error);
|
|
2719
|
-
throw new ParseError(spaceTrim
|
|
4794
|
+
throw new ParseError(spaceTrim((block) => `
|
|
2720
4795
|
Can not extract variables from the script
|
|
2721
4796
|
${block(error.stack || error.message)}
|
|
2722
4797
|
|
|
@@ -2899,7 +4974,7 @@ const CsvFormatParser = {
|
|
|
2899
4974
|
const { value, outputParameterName, settings, mapCallback, onProgress } = options;
|
|
2900
4975
|
const csv = csvParse(value, settings);
|
|
2901
4976
|
if (csv.errors.length !== 0) {
|
|
2902
|
-
throw new CsvFormatError(spaceTrim((block) => `
|
|
4977
|
+
throw new CsvFormatError(spaceTrim$1((block) => `
|
|
2903
4978
|
CSV parsing error
|
|
2904
4979
|
|
|
2905
4980
|
Error(s) from CSV parsing:
|
|
@@ -2944,7 +5019,7 @@ const CsvFormatParser = {
|
|
|
2944
5019
|
const { value, settings, mapCallback, onProgress } = options;
|
|
2945
5020
|
const csv = csvParse(value, settings);
|
|
2946
5021
|
if (csv.errors.length !== 0) {
|
|
2947
|
-
throw new CsvFormatError(spaceTrim((block) => `
|
|
5022
|
+
throw new CsvFormatError(spaceTrim$1((block) => `
|
|
2948
5023
|
CSV parsing error
|
|
2949
5024
|
|
|
2950
5025
|
Error(s) from CSV parsing:
|
|
@@ -3154,7 +5229,7 @@ function mapAvailableToExpectedParameters(options) {
|
|
|
3154
5229
|
}
|
|
3155
5230
|
// Phase 2️⃣: Non-matching mapping
|
|
3156
5231
|
if (expectedParameterNames.size !== availableParametersNames.size) {
|
|
3157
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5232
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
3158
5233
|
Can not map available parameters to expected parameters
|
|
3159
5234
|
|
|
3160
5235
|
Mapped parameters:
|
|
@@ -3207,14 +5282,14 @@ class MultipleLlmExecutionTools {
|
|
|
3207
5282
|
if (description === undefined) {
|
|
3208
5283
|
return headLine;
|
|
3209
5284
|
}
|
|
3210
|
-
return spaceTrim((block) => `
|
|
5285
|
+
return spaceTrim$1((block) => `
|
|
3211
5286
|
${headLine}
|
|
3212
5287
|
|
|
3213
5288
|
${ /* <- Note: Indenting the description: */block(description)}
|
|
3214
5289
|
`);
|
|
3215
5290
|
})
|
|
3216
5291
|
.join('\n\n');
|
|
3217
|
-
return spaceTrim((block) => `
|
|
5292
|
+
return spaceTrim$1((block) => `
|
|
3218
5293
|
Multiple LLM Providers:
|
|
3219
5294
|
|
|
3220
5295
|
${block(innerModelsTitlesAndDescriptions)}
|
|
@@ -3305,7 +5380,7 @@ class MultipleLlmExecutionTools {
|
|
|
3305
5380
|
// 1) OpenAI throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
3306
5381
|
// 2) AnthropicClaude throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
3307
5382
|
// 3) ...
|
|
3308
|
-
spaceTrim((block) => `
|
|
5383
|
+
spaceTrim$1((block) => `
|
|
3309
5384
|
All execution tools failed:
|
|
3310
5385
|
|
|
3311
5386
|
${block(errors
|
|
@@ -3318,7 +5393,7 @@ class MultipleLlmExecutionTools {
|
|
|
3318
5393
|
throw new PipelineExecutionError(`You have not provided any \`LlmExecutionTools\``);
|
|
3319
5394
|
}
|
|
3320
5395
|
else {
|
|
3321
|
-
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
5396
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
3322
5397
|
You have not provided any \`LlmExecutionTools\` that support model variant "${prompt.modelRequirements.modelVariant}"
|
|
3323
5398
|
|
|
3324
5399
|
Available \`LlmExecutionTools\`:
|
|
@@ -3351,7 +5426,7 @@ class MultipleLlmExecutionTools {
|
|
|
3351
5426
|
*/
|
|
3352
5427
|
function joinLlmExecutionTools(...llmExecutionTools) {
|
|
3353
5428
|
if (llmExecutionTools.length === 0) {
|
|
3354
|
-
const warningMessage = spaceTrim(`
|
|
5429
|
+
const warningMessage = spaceTrim$1(`
|
|
3355
5430
|
You have not provided any \`LlmExecutionTools\`
|
|
3356
5431
|
This means that you won't be able to execute any prompts that require large language models like GPT-4 or Anthropic's Claude.
|
|
3357
5432
|
|
|
@@ -4063,7 +6138,7 @@ function validatePromptResult(options) {
|
|
|
4063
6138
|
}
|
|
4064
6139
|
catch (error) {
|
|
4065
6140
|
keepUnused(error);
|
|
4066
|
-
throw new ExpectError(spaceTrim
|
|
6141
|
+
throw new ExpectError(spaceTrim((block) => `
|
|
4067
6142
|
Expected valid JSON string
|
|
4068
6143
|
|
|
4069
6144
|
The expected JSON text:
|
|
@@ -4112,7 +6187,7 @@ function validatePromptResult(options) {
|
|
|
4112
6187
|
*/
|
|
4113
6188
|
async function executeAttempts(options) {
|
|
4114
6189
|
const { jokerParameterNames, priority, maxAttempts, // <- Note: [💂]
|
|
4115
|
-
preparedContent, parameters, task, preparedPipeline, tools, $executionReport, pipelineIdentification, maxExecutionAttempts, } = options;
|
|
6190
|
+
preparedContent, parameters, task, preparedPipeline, tools, $executionReport, pipelineIdentification, maxExecutionAttempts, onProgress, } = options;
|
|
4116
6191
|
const $ongoingTaskResult = {
|
|
4117
6192
|
$result: null,
|
|
4118
6193
|
$resultString: null,
|
|
@@ -4128,7 +6203,7 @@ async function executeAttempts(options) {
|
|
|
4128
6203
|
const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attemptIndex];
|
|
4129
6204
|
// TODO: [🧠][🍭] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
|
|
4130
6205
|
if (isJokerAttempt && !jokerParameterName) {
|
|
4131
|
-
throw new UnexpectedError(spaceTrim
|
|
6206
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
4132
6207
|
Joker not found in attempt ${attemptIndex}
|
|
4133
6208
|
|
|
4134
6209
|
${block(pipelineIdentification)}
|
|
@@ -4139,7 +6214,7 @@ async function executeAttempts(options) {
|
|
|
4139
6214
|
$ongoingTaskResult.$expectError = null;
|
|
4140
6215
|
if (isJokerAttempt) {
|
|
4141
6216
|
if (parameters[jokerParameterName] === undefined) {
|
|
4142
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6217
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
4143
6218
|
Joker parameter {${jokerParameterName}} not defined
|
|
4144
6219
|
|
|
4145
6220
|
${block(pipelineIdentification)}
|
|
@@ -4197,7 +6272,7 @@ async function executeAttempts(options) {
|
|
|
4197
6272
|
$ongoingTaskResult.$resultString = $ongoingTaskResult.$completionResult.content;
|
|
4198
6273
|
break variant;
|
|
4199
6274
|
case 'EMBEDDING':
|
|
4200
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6275
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
4201
6276
|
Embedding model can not be used in pipeline
|
|
4202
6277
|
|
|
4203
6278
|
This should be catched during parsing
|
|
@@ -4208,7 +6283,7 @@ async function executeAttempts(options) {
|
|
|
4208
6283
|
break variant;
|
|
4209
6284
|
// <- case [🤖]:
|
|
4210
6285
|
default:
|
|
4211
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6286
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
4212
6287
|
Unknown model variant "${task.modelRequirements.modelVariant}"
|
|
4213
6288
|
|
|
4214
6289
|
${block(pipelineIdentification)}
|
|
@@ -4219,14 +6294,14 @@ async function executeAttempts(options) {
|
|
|
4219
6294
|
break;
|
|
4220
6295
|
case 'SCRIPT_TASK':
|
|
4221
6296
|
if (arrayableToArray(tools.script).length === 0) {
|
|
4222
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6297
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
4223
6298
|
No script execution tools are available
|
|
4224
6299
|
|
|
4225
6300
|
${block(pipelineIdentification)}
|
|
4226
6301
|
`));
|
|
4227
6302
|
}
|
|
4228
6303
|
if (!task.contentLanguage) {
|
|
4229
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6304
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
4230
6305
|
Script language is not defined for SCRIPT TASK "${task.name}"
|
|
4231
6306
|
|
|
4232
6307
|
${block(pipelineIdentification)}
|
|
@@ -4257,7 +6332,7 @@ async function executeAttempts(options) {
|
|
|
4257
6332
|
throw $ongoingTaskResult.$scriptPipelineExecutionErrors[0];
|
|
4258
6333
|
}
|
|
4259
6334
|
else {
|
|
4260
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6335
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
4261
6336
|
Script execution failed ${$ongoingTaskResult.$scriptPipelineExecutionErrors.length}x
|
|
4262
6337
|
|
|
4263
6338
|
${block(pipelineIdentification)}
|
|
@@ -4271,7 +6346,7 @@ async function executeAttempts(options) {
|
|
|
4271
6346
|
break taskType;
|
|
4272
6347
|
case 'DIALOG_TASK':
|
|
4273
6348
|
if (tools.userInterface === undefined) {
|
|
4274
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6349
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
4275
6350
|
User interface tools are not available
|
|
4276
6351
|
|
|
4277
6352
|
${block(pipelineIdentification)}
|
|
@@ -4289,7 +6364,7 @@ async function executeAttempts(options) {
|
|
|
4289
6364
|
break taskType;
|
|
4290
6365
|
// <- case: [🅱]
|
|
4291
6366
|
default:
|
|
4292
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6367
|
+
throw new PipelineExecutionError(spaceTrim((block) => `
|
|
4293
6368
|
Unknown execution type "${task.taskType}"
|
|
4294
6369
|
|
|
4295
6370
|
${block(pipelineIdentification)}
|
|
@@ -4356,6 +6431,10 @@ async function executeAttempts(options) {
|
|
|
4356
6431
|
result: $ongoingTaskResult.$resultString,
|
|
4357
6432
|
error: error,
|
|
4358
6433
|
});
|
|
6434
|
+
// Report failed attempt
|
|
6435
|
+
onProgress({
|
|
6436
|
+
errors: [error],
|
|
6437
|
+
});
|
|
4359
6438
|
}
|
|
4360
6439
|
finally {
|
|
4361
6440
|
if (!isJokerAttempt &&
|
|
@@ -4380,7 +6459,7 @@ async function executeAttempts(options) {
|
|
|
4380
6459
|
if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
|
|
4381
6460
|
// Note: Create a summary of all failures
|
|
4382
6461
|
const failuresSummary = $ongoingTaskResult.$failedResults
|
|
4383
|
-
.map((failure) => spaceTrim
|
|
6462
|
+
.map((failure) => spaceTrim((block) => {
|
|
4384
6463
|
var _a, _b;
|
|
4385
6464
|
return `
|
|
4386
6465
|
Attempt ${failure.attemptIndex + 1}:
|
|
@@ -4390,14 +6469,14 @@ async function executeAttempts(options) {
|
|
|
4390
6469
|
Result:
|
|
4391
6470
|
${block(failure.result === null
|
|
4392
6471
|
? 'null'
|
|
4393
|
-
: spaceTrim
|
|
6472
|
+
: spaceTrim(failure.result)
|
|
4394
6473
|
.split('\n')
|
|
4395
6474
|
.map((line) => `> ${line}`)
|
|
4396
6475
|
.join('\n'))}
|
|
4397
6476
|
`;
|
|
4398
6477
|
}))
|
|
4399
6478
|
.join('\n\n---\n\n');
|
|
4400
|
-
throw new PipelineExecutionError(spaceTrim
|
|
6479
|
+
throw new PipelineExecutionError(spaceTrim((block) => {
|
|
4401
6480
|
var _a;
|
|
4402
6481
|
return `
|
|
4403
6482
|
LLM execution failed ${maxExecutionAttempts}x
|
|
@@ -4417,7 +6496,7 @@ async function executeAttempts(options) {
|
|
|
4417
6496
|
}
|
|
4418
6497
|
}
|
|
4419
6498
|
if ($ongoingTaskResult.$resultString === null) {
|
|
4420
|
-
throw new UnexpectedError(spaceTrim
|
|
6499
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
4421
6500
|
Something went wrong and prompt result is null
|
|
4422
6501
|
|
|
4423
6502
|
${block(pipelineIdentification)}
|
|
@@ -4444,7 +6523,7 @@ async function executeFormatSubvalues(options) {
|
|
|
4444
6523
|
return /* not await */ executeAttempts(options);
|
|
4445
6524
|
}
|
|
4446
6525
|
if (jokerParameterNames.length !== 0) {
|
|
4447
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
6526
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
4448
6527
|
JOKER parameters are not supported together with FOREACH command
|
|
4449
6528
|
|
|
4450
6529
|
[🧞♀️] This should be prevented in \`validatePipeline\`
|
|
@@ -4457,7 +6536,7 @@ async function executeFormatSubvalues(options) {
|
|
|
4457
6536
|
if (formatDefinition === undefined) {
|
|
4458
6537
|
throw new UnexpectedError(
|
|
4459
6538
|
// <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
|
|
4460
|
-
spaceTrim((block) => `
|
|
6539
|
+
spaceTrim$1((block) => `
|
|
4461
6540
|
Unsupported format "${task.foreach.formatName}"
|
|
4462
6541
|
|
|
4463
6542
|
Available formats:
|
|
@@ -4474,7 +6553,7 @@ async function executeFormatSubvalues(options) {
|
|
|
4474
6553
|
if (subvalueParser === undefined) {
|
|
4475
6554
|
throw new UnexpectedError(
|
|
4476
6555
|
// <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
|
|
4477
|
-
spaceTrim((block) => `
|
|
6556
|
+
spaceTrim$1((block) => `
|
|
4478
6557
|
Unsupported subformat name "${task.foreach.subformatName}" for format "${task.foreach.formatName}"
|
|
4479
6558
|
|
|
4480
6559
|
Available subformat names for format "${formatDefinition.formatName}":
|
|
@@ -4514,7 +6593,7 @@ async function executeFormatSubvalues(options) {
|
|
|
4514
6593
|
if (!(error instanceof PipelineExecutionError)) {
|
|
4515
6594
|
throw error;
|
|
4516
6595
|
}
|
|
4517
|
-
const highLevelError = new PipelineExecutionError(spaceTrim((block) => `
|
|
6596
|
+
const highLevelError = new PipelineExecutionError(spaceTrim$1((block) => `
|
|
4518
6597
|
${error.message}
|
|
4519
6598
|
|
|
4520
6599
|
This is error in FOREACH command when mapping ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
|
|
@@ -4538,7 +6617,7 @@ async function executeFormatSubvalues(options) {
|
|
|
4538
6617
|
...options,
|
|
4539
6618
|
priority: priority + index,
|
|
4540
6619
|
parameters: allSubparameters,
|
|
4541
|
-
pipelineIdentification: spaceTrim((block) => `
|
|
6620
|
+
pipelineIdentification: spaceTrim$1((block) => `
|
|
4542
6621
|
${block(pipelineIdentification)}
|
|
4543
6622
|
Subparameter index: ${index}
|
|
4544
6623
|
`),
|
|
@@ -4547,7 +6626,7 @@ async function executeFormatSubvalues(options) {
|
|
|
4547
6626
|
}
|
|
4548
6627
|
catch (error) {
|
|
4549
6628
|
if (length > BIG_DATASET_TRESHOLD) {
|
|
4550
|
-
console.error(spaceTrim((block) => `
|
|
6629
|
+
console.error(spaceTrim$1((block) => `
|
|
4551
6630
|
${error.message}
|
|
4552
6631
|
|
|
4553
6632
|
This is error in FOREACH command when processing ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
|
|
@@ -4725,7 +6804,7 @@ async function getReservedParametersForTask(options) {
|
|
|
4725
6804
|
// Note: Doublecheck that ALL reserved parameters are defined:
|
|
4726
6805
|
for (const parameterName of RESERVED_PARAMETER_NAMES) {
|
|
4727
6806
|
if (reservedParameters[parameterName] === undefined) {
|
|
4728
|
-
throw new UnexpectedError(spaceTrim
|
|
6807
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
4729
6808
|
Reserved parameter {${parameterName}} is not defined
|
|
4730
6809
|
|
|
4731
6810
|
${block(pipelineIdentification)}
|
|
@@ -4751,7 +6830,7 @@ async function executeTask(options) {
|
|
|
4751
6830
|
const dependentParameterNames = new Set(currentTask.dependentParameterNames);
|
|
4752
6831
|
// TODO: [👩🏾🤝👩🏻] Use here `mapAvailableToExpectedParameters`
|
|
4753
6832
|
if (difference(union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)), new Set(RESERVED_PARAMETER_NAMES)).size !== 0) {
|
|
4754
|
-
throw new UnexpectedError(spaceTrim
|
|
6833
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
4755
6834
|
Dependent parameters are not consistent with used parameters:
|
|
4756
6835
|
|
|
4757
6836
|
Dependent parameters:
|
|
@@ -4795,7 +6874,7 @@ async function executeTask(options) {
|
|
|
4795
6874
|
else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
|
|
4796
6875
|
// Houston, we have a problem
|
|
4797
6876
|
// Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
|
|
4798
|
-
throw new UnexpectedError(spaceTrim
|
|
6877
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
4799
6878
|
Parameter \`{${parameterName}}\` is NOT defined
|
|
4800
6879
|
BUT used in task "${currentTask.title || currentTask.name}"
|
|
4801
6880
|
|
|
@@ -4863,7 +6942,7 @@ function filterJustOutputParameters(options) {
|
|
|
4863
6942
|
for (const parameter of preparedPipeline.parameters.filter(({ isOutput }) => isOutput)) {
|
|
4864
6943
|
if (parametersToPass[parameter.name] === undefined) {
|
|
4865
6944
|
// [4]
|
|
4866
|
-
$warnings.push(new PipelineExecutionError(spaceTrim
|
|
6945
|
+
$warnings.push(new PipelineExecutionError(spaceTrim((block) => `
|
|
4867
6946
|
Parameter \`{${parameter.name}}\` should be an output parameter, but it was not generated during pipeline execution
|
|
4868
6947
|
|
|
4869
6948
|
${block(pipelineIdentification)}
|
|
@@ -4948,7 +7027,7 @@ async function executePipeline(options) {
|
|
|
4948
7027
|
for (const parameterName of Object.keys(inputParameters)) {
|
|
4949
7028
|
const parameter = preparedPipeline.parameters.find(({ name }) => name === parameterName);
|
|
4950
7029
|
if (parameter === undefined) {
|
|
4951
|
-
warnings.push(new PipelineExecutionError(spaceTrim
|
|
7030
|
+
warnings.push(new PipelineExecutionError(spaceTrim((block) => `
|
|
4952
7031
|
Extra parameter {${parameterName}} is being passed which is not part of the pipeline.
|
|
4953
7032
|
|
|
4954
7033
|
${block(pipelineIdentification)}
|
|
@@ -4963,7 +7042,7 @@ async function executePipeline(options) {
|
|
|
4963
7042
|
// TODO: [🧠] This should be also non-critical error
|
|
4964
7043
|
return exportJson({
|
|
4965
7044
|
name: 'pipelineExecutorResult',
|
|
4966
|
-
message: spaceTrim
|
|
7045
|
+
message: spaceTrim((block) => `
|
|
4967
7046
|
Unsuccessful PipelineExecutorResult (with extra parameter {${parameter.name}}) PipelineExecutorResult
|
|
4968
7047
|
|
|
4969
7048
|
${block(pipelineIdentification)}
|
|
@@ -4972,7 +7051,7 @@ async function executePipeline(options) {
|
|
|
4972
7051
|
value: {
|
|
4973
7052
|
isSuccessful: false,
|
|
4974
7053
|
errors: [
|
|
4975
|
-
new PipelineExecutionError(spaceTrim
|
|
7054
|
+
new PipelineExecutionError(spaceTrim((block) => `
|
|
4976
7055
|
Parameter \`{${parameter.name}}\` is passed as input parameter but it is not input
|
|
4977
7056
|
|
|
4978
7057
|
${block(pipelineIdentification)}
|
|
@@ -4999,7 +7078,7 @@ async function executePipeline(options) {
|
|
|
4999
7078
|
while (unresovedTasks.length > 0) {
|
|
5000
7079
|
if (loopLimit-- < 0) {
|
|
5001
7080
|
// Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
|
|
5002
|
-
throw new UnexpectedError(spaceTrim
|
|
7081
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
5003
7082
|
Loop limit reached during resolving parameters pipeline execution
|
|
5004
7083
|
|
|
5005
7084
|
${block(pipelineIdentification)}
|
|
@@ -5009,7 +7088,7 @@ async function executePipeline(options) {
|
|
|
5009
7088
|
if (!currentTask && resolving.length === 0) {
|
|
5010
7089
|
throw new UnexpectedError(
|
|
5011
7090
|
// TODO: [🐎] DRY
|
|
5012
|
-
spaceTrim
|
|
7091
|
+
spaceTrim((block) => `
|
|
5013
7092
|
Can not resolve some parameters:
|
|
5014
7093
|
|
|
5015
7094
|
${block(pipelineIdentification)}
|
|
@@ -5049,7 +7128,7 @@ async function executePipeline(options) {
|
|
|
5049
7128
|
tools,
|
|
5050
7129
|
onProgress(newOngoingResult) {
|
|
5051
7130
|
if (isReturned) {
|
|
5052
|
-
throw new UnexpectedError(spaceTrim
|
|
7131
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
5053
7132
|
Can not call \`onProgress\` after pipeline execution is finished
|
|
5054
7133
|
|
|
5055
7134
|
${block(pipelineIdentification)}
|
|
@@ -5065,7 +7144,7 @@ async function executePipeline(options) {
|
|
|
5065
7144
|
}
|
|
5066
7145
|
},
|
|
5067
7146
|
$executionReport: executionReport,
|
|
5068
|
-
pipelineIdentification: spaceTrim
|
|
7147
|
+
pipelineIdentification: spaceTrim((block) => `
|
|
5069
7148
|
${block(pipelineIdentification)}
|
|
5070
7149
|
Task name: ${currentTask.name}
|
|
5071
7150
|
Task title: ${currentTask.title}
|
|
@@ -5174,7 +7253,7 @@ function createPipelineExecutor(options) {
|
|
|
5174
7253
|
preparedPipeline = pipeline;
|
|
5175
7254
|
}
|
|
5176
7255
|
else if (isNotPreparedWarningSuppressed !== true) {
|
|
5177
|
-
console.warn(spaceTrim
|
|
7256
|
+
console.warn(spaceTrim((block) => `
|
|
5178
7257
|
Pipeline is not prepared
|
|
5179
7258
|
|
|
5180
7259
|
${block(pipelineIdentification)}
|
|
@@ -5198,7 +7277,7 @@ function createPipelineExecutor(options) {
|
|
|
5198
7277
|
inputParameters,
|
|
5199
7278
|
tools,
|
|
5200
7279
|
onProgress,
|
|
5201
|
-
pipelineIdentification: spaceTrim
|
|
7280
|
+
pipelineIdentification: spaceTrim((block) => `
|
|
5202
7281
|
${block(pipelineIdentification)}
|
|
5203
7282
|
${runCount === 1 ? '' : `Run #${runCount}`}
|
|
5204
7283
|
`),
|
|
@@ -5237,6 +7316,71 @@ function createPipelineExecutor(options) {
|
|
|
5237
7316
|
updateOngoingResult(newOngoingResult);
|
|
5238
7317
|
});
|
|
5239
7318
|
},
|
|
7319
|
+
tldrProvider(createdAt, status, currentValue, errors) {
|
|
7320
|
+
var _a;
|
|
7321
|
+
// Better progress estimation based on pipeline structure
|
|
7322
|
+
const cv = currentValue;
|
|
7323
|
+
// Handle finished/error states
|
|
7324
|
+
if (status === 'FINISHED') {
|
|
7325
|
+
return {
|
|
7326
|
+
percent: 1,
|
|
7327
|
+
message: 'Finished',
|
|
7328
|
+
};
|
|
7329
|
+
}
|
|
7330
|
+
if (status === 'ERROR') {
|
|
7331
|
+
const errorMessage = errors.length > 0 ? errors[errors.length - 1].message : 'Error';
|
|
7332
|
+
return {
|
|
7333
|
+
percent: 0,
|
|
7334
|
+
message: errorMessage,
|
|
7335
|
+
};
|
|
7336
|
+
}
|
|
7337
|
+
// Calculate progress based on pipeline tasks
|
|
7338
|
+
const totalTasks = pipeline.tasks.length;
|
|
7339
|
+
let completedTasks = 0;
|
|
7340
|
+
let currentTaskName = '';
|
|
7341
|
+
// Check execution report for completed tasks
|
|
7342
|
+
if ((_a = cv === null || cv === void 0 ? void 0 : cv.executionReport) === null || _a === void 0 ? void 0 : _a.promptExecutions) {
|
|
7343
|
+
const executedTaskTitles = new Set(cv.executionReport.promptExecutions.map((execution) => execution.prompt.title));
|
|
7344
|
+
// Count completed tasks by matching titles
|
|
7345
|
+
const completedTasksByTitle = pipeline.tasks.filter(task => executedTaskTitles.has(task.title));
|
|
7346
|
+
completedTasks = completedTasksByTitle.length;
|
|
7347
|
+
// Find current task being executed (first task not yet completed)
|
|
7348
|
+
const remainingTasks = pipeline.tasks.filter(task => !executedTaskTitles.has(task.title));
|
|
7349
|
+
if (remainingTasks.length > 0) {
|
|
7350
|
+
currentTaskName = remainingTasks[0].name;
|
|
7351
|
+
}
|
|
7352
|
+
}
|
|
7353
|
+
// Calculate progress percentage
|
|
7354
|
+
let percent = totalTasks > 0 ? completedTasks / totalTasks : 0;
|
|
7355
|
+
// Add time-based progress for current task (assuming 5 minutes total)
|
|
7356
|
+
if (completedTasks < totalTasks) {
|
|
7357
|
+
const elapsedMs = new Date().getTime() - createdAt.getTime();
|
|
7358
|
+
const totalMs = 5 * 60 * 1000; // 5 minutes
|
|
7359
|
+
const timeProgress = Math.min(elapsedMs / totalMs, 1);
|
|
7360
|
+
// Add partial progress for current task
|
|
7361
|
+
percent += (1 / totalTasks) * timeProgress;
|
|
7362
|
+
}
|
|
7363
|
+
// Clamp to [0,1]
|
|
7364
|
+
percent = Math.min(Math.max(percent, 0), 1);
|
|
7365
|
+
// Generate message
|
|
7366
|
+
let message = '';
|
|
7367
|
+
if (currentTaskName) {
|
|
7368
|
+
// Find the task to get its title
|
|
7369
|
+
const currentTask = pipeline.tasks.find(task => task.name === currentTaskName);
|
|
7370
|
+
const taskTitle = (currentTask === null || currentTask === void 0 ? void 0 : currentTask.title) || currentTaskName;
|
|
7371
|
+
message = `Working on task ${taskTitle}`;
|
|
7372
|
+
}
|
|
7373
|
+
else if (completedTasks === 0) {
|
|
7374
|
+
message = 'Starting pipeline execution';
|
|
7375
|
+
}
|
|
7376
|
+
else {
|
|
7377
|
+
message = `Processing pipeline (${completedTasks}/${totalTasks} tasks completed)`;
|
|
7378
|
+
}
|
|
7379
|
+
return {
|
|
7380
|
+
percent,
|
|
7381
|
+
message,
|
|
7382
|
+
};
|
|
7383
|
+
},
|
|
5240
7384
|
});
|
|
5241
7385
|
// <- TODO: Make types such as there is no need to do `as` for `createTask`
|
|
5242
7386
|
return pipelineExecutor;
|
|
@@ -5609,14 +7753,14 @@ function $registeredScrapersMessage(availableScrapers) {
|
|
|
5609
7753
|
return { ...metadata, isMetadataAviailable, isInstalled, isAvailableInTools };
|
|
5610
7754
|
});
|
|
5611
7755
|
if (metadata.length === 0) {
|
|
5612
|
-
return spaceTrim(`
|
|
7756
|
+
return spaceTrim$1(`
|
|
5613
7757
|
**No scrapers are available**
|
|
5614
7758
|
|
|
5615
7759
|
This is a unexpected behavior, you are probably using some broken version of Promptbook
|
|
5616
7760
|
At least there should be available the metadata of the scrapers
|
|
5617
7761
|
`);
|
|
5618
7762
|
}
|
|
5619
|
-
return spaceTrim((block) => `
|
|
7763
|
+
return spaceTrim$1((block) => `
|
|
5620
7764
|
Available scrapers are:
|
|
5621
7765
|
${block(metadata
|
|
5622
7766
|
.map(({ packageName, className, isMetadataAviailable, isInstalled, mimeTypes, isAvailableInBrowser, isAvailableInTools, }, i) => {
|
|
@@ -5835,37 +7979,6 @@ function titleToName(value) {
|
|
|
5835
7979
|
return value;
|
|
5836
7980
|
}
|
|
5837
7981
|
|
|
5838
|
-
/**
|
|
5839
|
-
* The built-in `fetch' function with a lightweight error handling wrapper as default fetch function used in Promptbook scrapers
|
|
5840
|
-
*
|
|
5841
|
-
* @public exported from `@promptbook/core`
|
|
5842
|
-
*/
|
|
5843
|
-
const promptbookFetch = async (urlOrRequest, init) => {
|
|
5844
|
-
try {
|
|
5845
|
-
return await fetch(urlOrRequest, init);
|
|
5846
|
-
}
|
|
5847
|
-
catch (error) {
|
|
5848
|
-
assertsError(error);
|
|
5849
|
-
let url;
|
|
5850
|
-
if (typeof urlOrRequest === 'string') {
|
|
5851
|
-
url = urlOrRequest;
|
|
5852
|
-
}
|
|
5853
|
-
else if (urlOrRequest instanceof Request) {
|
|
5854
|
-
url = urlOrRequest.url;
|
|
5855
|
-
}
|
|
5856
|
-
throw new PromptbookFetchError(spaceTrim((block) => `
|
|
5857
|
-
Can not fetch "${url}"
|
|
5858
|
-
|
|
5859
|
-
Fetch error:
|
|
5860
|
-
${block(error.message)}
|
|
5861
|
-
|
|
5862
|
-
`));
|
|
5863
|
-
}
|
|
5864
|
-
};
|
|
5865
|
-
/**
|
|
5866
|
-
* TODO: [🧠] Maybe rename because it is not used only for scrapers but also in `$getCompiledBook`
|
|
5867
|
-
*/
|
|
5868
|
-
|
|
5869
7982
|
/**
|
|
5870
7983
|
* Factory function that creates a handler for processing knowledge sources.
|
|
5871
7984
|
* Provides standardized processing of different types of knowledge sources
|
|
@@ -5992,7 +8105,7 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
|
|
|
5992
8105
|
const fileExtension = getFileExtension(filename);
|
|
5993
8106
|
const mimeType = extensionToMimeType(fileExtension || '');
|
|
5994
8107
|
if (!(await isFileExisting(filename, tools.fs))) {
|
|
5995
|
-
throw new NotFoundError(spaceTrim((block) => `
|
|
8108
|
+
throw new NotFoundError(spaceTrim$1((block) => `
|
|
5996
8109
|
Can not make source handler for file which does not exist:
|
|
5997
8110
|
|
|
5998
8111
|
File:
|
|
@@ -6079,7 +8192,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
6079
8192
|
// <- TODO: [🪓] Here should be no need for spreading new array, just `partialPieces = partialPiecesUnchecked`
|
|
6080
8193
|
break;
|
|
6081
8194
|
}
|
|
6082
|
-
console.warn(spaceTrim((block) => `
|
|
8195
|
+
console.warn(spaceTrim$1((block) => `
|
|
6083
8196
|
Cannot scrape knowledge from source despite the scraper \`${scraper.metadata.className}\` supports the mime type "${sourceHandler.mimeType}".
|
|
6084
8197
|
|
|
6085
8198
|
The source:
|
|
@@ -6095,7 +8208,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
6095
8208
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
6096
8209
|
}
|
|
6097
8210
|
if (partialPieces === null) {
|
|
6098
|
-
throw new KnowledgeScrapeError(spaceTrim((block) => `
|
|
8211
|
+
throw new KnowledgeScrapeError(spaceTrim$1((block) => `
|
|
6099
8212
|
Cannot scrape knowledge
|
|
6100
8213
|
|
|
6101
8214
|
The source:
|
|
@@ -6174,7 +8287,7 @@ async function prepareTasks(pipeline, tools, options) {
|
|
|
6174
8287
|
if (task.taskType === 'PROMPT_TASK' &&
|
|
6175
8288
|
knowledgePiecesCount > 0 &&
|
|
6176
8289
|
!dependentParameterNames.includes('knowledge')) {
|
|
6177
|
-
preparedContent = spaceTrim
|
|
8290
|
+
preparedContent = spaceTrim(`
|
|
6178
8291
|
{content}
|
|
6179
8292
|
|
|
6180
8293
|
## Knowledge
|
|
@@ -6433,7 +8546,7 @@ const knowledgeCommandParser = {
|
|
|
6433
8546
|
*/
|
|
6434
8547
|
parse(input) {
|
|
6435
8548
|
const { args } = input;
|
|
6436
|
-
const knowledgeSourceContent = spaceTrim(args[0] || '');
|
|
8549
|
+
const knowledgeSourceContent = spaceTrim$1(args[0] || '');
|
|
6437
8550
|
if (knowledgeSourceContent === '') {
|
|
6438
8551
|
throw new ParseError(`Source is not defined`);
|
|
6439
8552
|
}
|
|
@@ -6577,7 +8690,7 @@ const sectionCommandParser = {
|
|
|
6577
8690
|
normalized = normalized.split('DIALOGUE').join('DIALOG');
|
|
6578
8691
|
const taskTypes = SectionTypes.filter((sectionType) => normalized.includes(sectionType.split('_TASK').join('')));
|
|
6579
8692
|
if (taskTypes.length !== 1) {
|
|
6580
|
-
throw new ParseError(spaceTrim((block) => `
|
|
8693
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
6581
8694
|
Unknown section type "${normalized}"
|
|
6582
8695
|
|
|
6583
8696
|
Supported section types are:
|
|
@@ -6597,7 +8710,7 @@ const sectionCommandParser = {
|
|
|
6597
8710
|
*/
|
|
6598
8711
|
$applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
6599
8712
|
if ($taskJson.isSectionTypeSet === true) {
|
|
6600
|
-
throw new ParseError(spaceTrim(`
|
|
8713
|
+
throw new ParseError(spaceTrim$1(`
|
|
6601
8714
|
Section type is already defined in the section.
|
|
6602
8715
|
It can be defined only once.
|
|
6603
8716
|
`));
|
|
@@ -6945,7 +9058,7 @@ const expectCommandParser = {
|
|
|
6945
9058
|
/**
|
|
6946
9059
|
* Description of the FORMAT command
|
|
6947
9060
|
*/
|
|
6948
|
-
description: spaceTrim(`
|
|
9061
|
+
description: spaceTrim$1(`
|
|
6949
9062
|
Expect command describes the desired output of the task *(after post-processing)*
|
|
6950
9063
|
It can set limits for the maximum/minimum length of the output, measured in characters, words, sentences, paragraphs or some other shape of the output.
|
|
6951
9064
|
`),
|
|
@@ -7019,7 +9132,7 @@ const expectCommandParser = {
|
|
|
7019
9132
|
}
|
|
7020
9133
|
catch (error) {
|
|
7021
9134
|
assertsError(error);
|
|
7022
|
-
throw new ParseError(spaceTrim((block) => `
|
|
9135
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
7023
9136
|
Invalid FORMAT command
|
|
7024
9137
|
${block(error.message)}:
|
|
7025
9138
|
`));
|
|
@@ -7204,7 +9317,7 @@ function validateParameterName(parameterName) {
|
|
|
7204
9317
|
if (!(error instanceof ParseError)) {
|
|
7205
9318
|
throw error;
|
|
7206
9319
|
}
|
|
7207
|
-
throw new ParseError(spaceTrim((block) => `
|
|
9320
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
7208
9321
|
${block(error.message)}
|
|
7209
9322
|
|
|
7210
9323
|
Tried to validate parameter name:
|
|
@@ -7263,7 +9376,7 @@ const foreachCommandParser = {
|
|
|
7263
9376
|
const assignSign = args[3];
|
|
7264
9377
|
const formatDefinition = FORMAT_DEFINITIONS.find((formatDefinition) => [formatDefinition.formatName, ...(formatDefinition.aliases || [])].includes(formatName));
|
|
7265
9378
|
if (formatDefinition === undefined) {
|
|
7266
|
-
throw new ParseError(spaceTrim((block) => `
|
|
9379
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
7267
9380
|
Unsupported format "${formatName}"
|
|
7268
9381
|
|
|
7269
9382
|
Available formats:
|
|
@@ -7275,7 +9388,7 @@ const foreachCommandParser = {
|
|
|
7275
9388
|
}
|
|
7276
9389
|
const subvalueParser = formatDefinition.subvalueParsers.find((subvalueParser) => [subvalueParser.subvalueName, ...(subvalueParser.aliases || [])].includes(subformatName));
|
|
7277
9390
|
if (subvalueParser === undefined) {
|
|
7278
|
-
throw new ParseError(spaceTrim((block) => `
|
|
9391
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
7279
9392
|
Unsupported subformat name "${subformatName}" for format "${formatName}"
|
|
7280
9393
|
|
|
7281
9394
|
Available subformat names for format "${formatDefinition.formatName}":
|
|
@@ -7323,7 +9436,7 @@ const foreachCommandParser = {
|
|
|
7323
9436
|
outputSubparameterName = 'newLine';
|
|
7324
9437
|
}
|
|
7325
9438
|
else {
|
|
7326
|
-
throw new ParseError(spaceTrim(`
|
|
9439
|
+
throw new ParseError(spaceTrim$1(`
|
|
7327
9440
|
FOREACH ${formatName} ${subformatName} must specify output subparameter
|
|
7328
9441
|
|
|
7329
9442
|
Correct example:
|
|
@@ -7399,7 +9512,7 @@ const formatCommandParser = {
|
|
|
7399
9512
|
/**
|
|
7400
9513
|
* Description of the FORMAT command
|
|
7401
9514
|
*/
|
|
7402
|
-
description: spaceTrim(`
|
|
9515
|
+
description: spaceTrim$1(`
|
|
7403
9516
|
Format command describes the desired output of the task (after post-processing)
|
|
7404
9517
|
It can set limits for the maximum/minimum length of the output, measured in characters, words, sentences, paragraphs or some other shape of the output.
|
|
7405
9518
|
`),
|
|
@@ -7771,7 +9884,7 @@ const formfactorCommandParser = {
|
|
|
7771
9884
|
const formfactorNameCandidate = args[0].toUpperCase();
|
|
7772
9885
|
const formfactor = FORMFACTOR_DEFINITIONS.find((definition) => [definition.name, ...{ aliasNames: [], ...definition }.aliasNames].includes(formfactorNameCandidate));
|
|
7773
9886
|
if (formfactor === undefined) {
|
|
7774
|
-
throw new ParseError(spaceTrim((block) => `
|
|
9887
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
7775
9888
|
Unknown formfactor name "${formfactorNameCandidate}"
|
|
7776
9889
|
|
|
7777
9890
|
Available formfactors:
|
|
@@ -7790,7 +9903,7 @@ const formfactorCommandParser = {
|
|
|
7790
9903
|
*/
|
|
7791
9904
|
$applyToPipelineJson(command, $pipelineJson) {
|
|
7792
9905
|
if ($pipelineJson.formfactorName !== undefined && $pipelineJson.formfactorName !== command.formfactorName) {
|
|
7793
|
-
throw new ParseError(spaceTrim(`
|
|
9906
|
+
throw new ParseError(spaceTrim$1(`
|
|
7794
9907
|
Redefinition of \`FORMFACTOR\` in the pipeline head
|
|
7795
9908
|
|
|
7796
9909
|
You have used:
|
|
@@ -7933,7 +10046,7 @@ const modelCommandParser = {
|
|
|
7933
10046
|
*/
|
|
7934
10047
|
parse(input) {
|
|
7935
10048
|
const { args, normalized } = input;
|
|
7936
|
-
const availableVariantsMessage = spaceTrim((block) => `
|
|
10049
|
+
const availableVariantsMessage = spaceTrim$1((block) => `
|
|
7937
10050
|
Available variants are:
|
|
7938
10051
|
${block(MODEL_VARIANTS.map((variantName) => `- ${variantName}${variantName !== 'EMBEDDING' ? '' : ' (Not available in pipeline)'}`).join('\n'))}
|
|
7939
10052
|
`);
|
|
@@ -7955,14 +10068,14 @@ const modelCommandParser = {
|
|
|
7955
10068
|
// <- Note: [🤖]
|
|
7956
10069
|
}
|
|
7957
10070
|
else if (normalized.startsWith('MODEL_VARIANT_EMBED')) {
|
|
7958
|
-
spaceTrim((block) => `
|
|
10071
|
+
spaceTrim$1((block) => `
|
|
7959
10072
|
Embedding model can not be used in pipeline
|
|
7960
10073
|
|
|
7961
10074
|
${block(availableVariantsMessage)}
|
|
7962
10075
|
`);
|
|
7963
10076
|
}
|
|
7964
10077
|
else {
|
|
7965
|
-
throw new ParseError(spaceTrim((block) => `
|
|
10078
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
7966
10079
|
Unknown model variant in command:
|
|
7967
10080
|
|
|
7968
10081
|
${block(availableVariantsMessage)}
|
|
@@ -7977,7 +10090,7 @@ const modelCommandParser = {
|
|
|
7977
10090
|
};
|
|
7978
10091
|
}
|
|
7979
10092
|
else {
|
|
7980
|
-
throw new ParseError(spaceTrim((block) => `
|
|
10093
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
7981
10094
|
Unknown model key in command.
|
|
7982
10095
|
|
|
7983
10096
|
Supported model keys are:
|
|
@@ -8004,7 +10117,7 @@ const modelCommandParser = {
|
|
|
8004
10117
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
8005
10118
|
}
|
|
8006
10119
|
else {
|
|
8007
|
-
throw new ParseError(spaceTrim(`
|
|
10120
|
+
throw new ParseError(spaceTrim$1(`
|
|
8008
10121
|
Redefinition of \`MODEL ${command.key}\` in the pipeline head
|
|
8009
10122
|
|
|
8010
10123
|
You have used:
|
|
@@ -8036,7 +10149,7 @@ const modelCommandParser = {
|
|
|
8036
10149
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
8037
10150
|
}
|
|
8038
10151
|
else {
|
|
8039
|
-
throw new ParseError(spaceTrim(`
|
|
10152
|
+
throw new ParseError(spaceTrim$1(`
|
|
8040
10153
|
Redefinition of MODEL \`${command.key}\` in the task "${$taskJson.title || $taskJson.name}"
|
|
8041
10154
|
|
|
8042
10155
|
You have used:
|
|
@@ -8046,7 +10159,7 @@ const modelCommandParser = {
|
|
|
8046
10159
|
}
|
|
8047
10160
|
}
|
|
8048
10161
|
if (command.value === ($pipelineJson.defaultModelRequirements || {})[command.key]) {
|
|
8049
|
-
console.log(spaceTrim(`
|
|
10162
|
+
console.log(spaceTrim$1(`
|
|
8050
10163
|
Setting MODEL \`${command.key}\` in the task "${$taskJson.title || $taskJson.name}" to the same value as in the pipeline head
|
|
8051
10164
|
|
|
8052
10165
|
In pipeline head:
|
|
@@ -8129,7 +10242,7 @@ const parameterCommandParser = {
|
|
|
8129
10242
|
// <- TODO: When [🥶] fixed, change to:
|
|
8130
10243
|
// > const parameterDescriptionRaw = rawArgs.split(parameterNameRaw).join('').trim();
|
|
8131
10244
|
if (parameterDescriptionRaw && parameterDescriptionRaw.match(/\{(?<embeddedParameterName>[a-z0-9_]+)\}/im)) {
|
|
8132
|
-
throw new ParseError(spaceTrim((block) => `
|
|
10245
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
8133
10246
|
Parameter \`{${parameterNameRaw}}\` can not contain another parameter in description
|
|
8134
10247
|
|
|
8135
10248
|
The description:
|
|
@@ -8311,7 +10424,7 @@ function $applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
|
8311
10424
|
persona.description = personaDescription;
|
|
8312
10425
|
return;
|
|
8313
10426
|
}
|
|
8314
|
-
console.warn(spaceTrim(`
|
|
10427
|
+
console.warn(spaceTrim$1(`
|
|
8315
10428
|
|
|
8316
10429
|
Persona "${personaName}" is defined multiple times with different description:
|
|
8317
10430
|
|
|
@@ -8322,7 +10435,7 @@ function $applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
|
8322
10435
|
${personaDescription}
|
|
8323
10436
|
|
|
8324
10437
|
`));
|
|
8325
|
-
persona.description += spaceTrim('\n\n' + personaDescription);
|
|
10438
|
+
persona.description += spaceTrim$1('\n\n' + personaDescription);
|
|
8326
10439
|
}
|
|
8327
10440
|
|
|
8328
10441
|
/**
|
|
@@ -8687,7 +10800,7 @@ const COMMANDS = [
|
|
|
8687
10800
|
function getParserForCommand(command) {
|
|
8688
10801
|
const commandParser = COMMANDS.find((commandParser) => commandParser.name === command.type);
|
|
8689
10802
|
if (commandParser === undefined) {
|
|
8690
|
-
throw new UnexpectedError(spaceTrim
|
|
10803
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
8691
10804
|
Command ${command.type} parser is not found
|
|
8692
10805
|
|
|
8693
10806
|
${block(JSON.stringify(command, null, 4)
|
|
@@ -8763,7 +10876,7 @@ function parseCommand(raw, usagePlace) {
|
|
|
8763
10876
|
.map(removeMarkdownFormatting)
|
|
8764
10877
|
.map((item) => item.trim());
|
|
8765
10878
|
if (items.length === 0 || items[0] === '') {
|
|
8766
|
-
throw new ParseError(spaceTrim
|
|
10879
|
+
throw new ParseError(spaceTrim((block) => `
|
|
8767
10880
|
Malformed command:
|
|
8768
10881
|
- ${raw}
|
|
8769
10882
|
|
|
@@ -8799,7 +10912,7 @@ function parseCommand(raw, usagePlace) {
|
|
|
8799
10912
|
return command;
|
|
8800
10913
|
}
|
|
8801
10914
|
}
|
|
8802
|
-
throw new ParseError(spaceTrim
|
|
10915
|
+
throw new ParseError(spaceTrim((block) => `
|
|
8803
10916
|
Malformed or unknown command:
|
|
8804
10917
|
- ${raw}
|
|
8805
10918
|
|
|
@@ -8850,7 +10963,7 @@ function parseCommandVariant(input) {
|
|
|
8850
10963
|
if (!(error instanceof ParseError)) {
|
|
8851
10964
|
throw error;
|
|
8852
10965
|
}
|
|
8853
|
-
throw new ParseError(spaceTrim
|
|
10966
|
+
throw new ParseError(spaceTrim((block) => `
|
|
8854
10967
|
Invalid ${commandName} command:
|
|
8855
10968
|
|
|
8856
10969
|
Your command:
|
|
@@ -9124,7 +11237,7 @@ const SUPPORTED_SCRIPT_LANGUAGES = ['javascript', 'typescript', 'python'];
|
|
|
9124
11237
|
* @public exported from `@promptbook/markdown-utils`
|
|
9125
11238
|
*/
|
|
9126
11239
|
function removeMarkdownComments(content) {
|
|
9127
|
-
return spaceTrim
|
|
11240
|
+
return spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
|
|
9128
11241
|
}
|
|
9129
11242
|
|
|
9130
11243
|
/**
|
|
@@ -9135,7 +11248,7 @@ function removeMarkdownComments(content) {
|
|
|
9135
11248
|
*/
|
|
9136
11249
|
function isFlatPipeline(pipelineString) {
|
|
9137
11250
|
pipelineString = removeMarkdownComments(pipelineString);
|
|
9138
|
-
pipelineString = spaceTrim(pipelineString);
|
|
11251
|
+
pipelineString = spaceTrim$1(pipelineString);
|
|
9139
11252
|
const isMarkdownBeginningWithHeadline = pipelineString.startsWith('# ');
|
|
9140
11253
|
//const isLastLineReturnStatement = pipelineString.split('\n').pop()!.split('`').join('').startsWith('->');
|
|
9141
11254
|
const isBacktickBlockUsed = pipelineString.includes('```');
|
|
@@ -9173,19 +11286,19 @@ function deflatePipeline(pipelineString) {
|
|
|
9173
11286
|
returnStatement = `-> {${DEFAULT_BOOK_OUTPUT_PARAMETER_NAME}}`;
|
|
9174
11287
|
pipelineStringLines.push(potentialReturnStatement);
|
|
9175
11288
|
}
|
|
9176
|
-
const prompt = spaceTrim(pipelineStringLines.join('\n'));
|
|
11289
|
+
const prompt = spaceTrim$1(pipelineStringLines.join('\n'));
|
|
9177
11290
|
let quotedPrompt;
|
|
9178
11291
|
if (prompt.split('\n').length <= 1) {
|
|
9179
11292
|
quotedPrompt = `> ${prompt}`;
|
|
9180
11293
|
}
|
|
9181
11294
|
else {
|
|
9182
|
-
quotedPrompt = spaceTrim((block) => `
|
|
11295
|
+
quotedPrompt = spaceTrim$1((block) => `
|
|
9183
11296
|
\`\`\`
|
|
9184
11297
|
${block(prompt.split('`').join('\\`'))}
|
|
9185
11298
|
\`\`\`
|
|
9186
11299
|
`);
|
|
9187
11300
|
}
|
|
9188
|
-
pipelineString = validatePipelineString(spaceTrim((block) => `
|
|
11301
|
+
pipelineString = validatePipelineString(spaceTrim$1((block) => `
|
|
9189
11302
|
# ${DEFAULT_BOOK_TITLE}
|
|
9190
11303
|
|
|
9191
11304
|
## Prompt
|
|
@@ -9249,7 +11362,7 @@ function extractAllListItemsFromMarkdown(markdown) {
|
|
|
9249
11362
|
function extractOneBlockFromMarkdown(markdown) {
|
|
9250
11363
|
const codeBlocks = extractAllBlocksFromMarkdown(markdown);
|
|
9251
11364
|
if (codeBlocks.length !== 1) {
|
|
9252
|
-
throw new ParseError(spaceTrim((block) => `
|
|
11365
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
9253
11366
|
There should be exactly 1 code block in task section, found ${codeBlocks.length} code blocks
|
|
9254
11367
|
|
|
9255
11368
|
${block(codeBlocks.map((block, i) => `Block ${i + 1}:\n${block.content}`).join('\n\n\n'))}
|
|
@@ -9274,7 +11387,7 @@ function parseMarkdownSection(value) {
|
|
|
9274
11387
|
}
|
|
9275
11388
|
const title = lines[0].replace(/^#+\s*/, '');
|
|
9276
11389
|
const level = (_b = (_a = lines[0].match(/^#+/)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
|
|
9277
|
-
const content = spaceTrim(lines.slice(1).join('\n'));
|
|
11390
|
+
const content = spaceTrim$1(lines.slice(1).join('\n'));
|
|
9278
11391
|
if (level < 1 || level > 6) {
|
|
9279
11392
|
throw new ParseError('Markdown section must have heading level between 1 and 6');
|
|
9280
11393
|
}
|
|
@@ -9302,7 +11415,7 @@ function splitMarkdownIntoSections(markdown) {
|
|
|
9302
11415
|
if (buffer.length === 0) {
|
|
9303
11416
|
return;
|
|
9304
11417
|
}
|
|
9305
|
-
let section = spaceTrim(buffer.join('\n'));
|
|
11418
|
+
let section = spaceTrim$1(buffer.join('\n'));
|
|
9306
11419
|
if (section === '') {
|
|
9307
11420
|
return;
|
|
9308
11421
|
}
|
|
@@ -9377,7 +11490,7 @@ function flattenMarkdown(markdown) {
|
|
|
9377
11490
|
flattenedMarkdown += `## ${title}` + `\n\n`;
|
|
9378
11491
|
flattenedMarkdown += content + `\n\n`; // <- [🧠] Maybe 3 new lines?
|
|
9379
11492
|
}
|
|
9380
|
-
return spaceTrim(flattenedMarkdown);
|
|
11493
|
+
return spaceTrim$1(flattenedMarkdown);
|
|
9381
11494
|
}
|
|
9382
11495
|
/**
|
|
9383
11496
|
* TODO: [🏛] This can be part of markdown builder
|
|
@@ -9439,7 +11552,7 @@ function parsePipeline(pipelineString) {
|
|
|
9439
11552
|
if (pipelineString.startsWith('#!')) {
|
|
9440
11553
|
const [shebangLine, ...restLines] = pipelineString.split('\n');
|
|
9441
11554
|
if (!(shebangLine || '').includes('ptbk')) {
|
|
9442
|
-
throw new ParseError(spaceTrim
|
|
11555
|
+
throw new ParseError(spaceTrim((block) => `
|
|
9443
11556
|
It seems that you try to parse a book file which has non-standard shebang line for book files:
|
|
9444
11557
|
Shebang line must contain 'ptbk'
|
|
9445
11558
|
|
|
@@ -9455,7 +11568,7 @@ function parsePipeline(pipelineString) {
|
|
|
9455
11568
|
pipelineString = validatePipelineString(restLines.join('\n'));
|
|
9456
11569
|
}
|
|
9457
11570
|
pipelineString = removeMarkdownComments(pipelineString);
|
|
9458
|
-
pipelineString = spaceTrim
|
|
11571
|
+
pipelineString = spaceTrim(pipelineString);
|
|
9459
11572
|
// <- TODO: [😧] `spaceTrim` should preserve discriminated type *(or at lease `PipelineString`)*
|
|
9460
11573
|
pipelineString = deflatePipeline(pipelineString);
|
|
9461
11574
|
// ==============
|
|
@@ -9467,7 +11580,7 @@ function parsePipeline(pipelineString) {
|
|
|
9467
11580
|
// ==============
|
|
9468
11581
|
// Note: 1️⃣◽4️⃣ Check markdown structure
|
|
9469
11582
|
if (pipelineHead === undefined) {
|
|
9470
|
-
throw new UnexpectedError(spaceTrim
|
|
11583
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
9471
11584
|
Pipeline head is not defined
|
|
9472
11585
|
|
|
9473
11586
|
${block(getPipelineIdentification())}
|
|
@@ -9476,7 +11589,7 @@ function parsePipeline(pipelineString) {
|
|
|
9476
11589
|
`));
|
|
9477
11590
|
}
|
|
9478
11591
|
if (pipelineHead.level !== 1) {
|
|
9479
|
-
throw new UnexpectedError(spaceTrim
|
|
11592
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
9480
11593
|
Pipeline head is not h1
|
|
9481
11594
|
|
|
9482
11595
|
${block(getPipelineIdentification())}
|
|
@@ -9485,7 +11598,7 @@ function parsePipeline(pipelineString) {
|
|
|
9485
11598
|
`));
|
|
9486
11599
|
}
|
|
9487
11600
|
if (!pipelineSections.every((section) => section.level === 2)) {
|
|
9488
|
-
throw new UnexpectedError(spaceTrim
|
|
11601
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
9489
11602
|
Not every pipeline section is h2
|
|
9490
11603
|
|
|
9491
11604
|
${block(getPipelineIdentification())}
|
|
@@ -9498,7 +11611,7 @@ function parsePipeline(pipelineString) {
|
|
|
9498
11611
|
const defineParam = (parameterCommand) => {
|
|
9499
11612
|
const { parameterName, parameterDescription, isInput, isOutput } = parameterCommand;
|
|
9500
11613
|
if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
|
|
9501
|
-
throw new ParseError(spaceTrim
|
|
11614
|
+
throw new ParseError(spaceTrim((block) => `
|
|
9502
11615
|
Parameter name {${parameterName}} is reserved and cannot be used as resulting parameter name
|
|
9503
11616
|
|
|
9504
11617
|
${block(getPipelineIdentification())}
|
|
@@ -9509,7 +11622,7 @@ function parsePipeline(pipelineString) {
|
|
|
9509
11622
|
existingParameter.description &&
|
|
9510
11623
|
existingParameter.description !== parameterDescription &&
|
|
9511
11624
|
parameterDescription) {
|
|
9512
|
-
throw new ParseError(spaceTrim
|
|
11625
|
+
throw new ParseError(spaceTrim((block) => `
|
|
9513
11626
|
Parameter \`{${parameterName}}\` is defined multiple times with different description:
|
|
9514
11627
|
|
|
9515
11628
|
${block(getPipelineIdentification())}
|
|
@@ -9547,7 +11660,7 @@ function parsePipeline(pipelineString) {
|
|
|
9547
11660
|
description = description.split(/^>.*$/gm).join('');
|
|
9548
11661
|
//Note: Remove lists and return statement - TODO: [🎾] Make util (exported from `@promptbool/utils`)
|
|
9549
11662
|
description = description.split(/^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm).join('');
|
|
9550
|
-
description = spaceTrim
|
|
11663
|
+
description = spaceTrim(description);
|
|
9551
11664
|
if (description === '') {
|
|
9552
11665
|
description = undefined;
|
|
9553
11666
|
}
|
|
@@ -9558,7 +11671,7 @@ function parsePipeline(pipelineString) {
|
|
|
9558
11671
|
const command = parseCommand(listItem, 'PIPELINE_HEAD');
|
|
9559
11672
|
const commandParser = getParserForCommand(command);
|
|
9560
11673
|
if (commandParser.isUsedInPipelineHead !== true /* <- Note: [🦦][4] */) {
|
|
9561
|
-
throw new ParseError(spaceTrim
|
|
11674
|
+
throw new ParseError(spaceTrim((block) => `
|
|
9562
11675
|
Command \`${command.type}\` is not allowed in the head of the pipeline ONLY at the pipeline task
|
|
9563
11676
|
|
|
9564
11677
|
${block(getPipelineIdentification())}
|
|
@@ -9572,7 +11685,7 @@ function parsePipeline(pipelineString) {
|
|
|
9572
11685
|
if (!(error instanceof ParseError)) {
|
|
9573
11686
|
throw error;
|
|
9574
11687
|
}
|
|
9575
|
-
throw new ParseError(spaceTrim
|
|
11688
|
+
throw new ParseError(spaceTrim((block) => `
|
|
9576
11689
|
Command ${command.type} failed to apply to the pipeline
|
|
9577
11690
|
|
|
9578
11691
|
The error:
|
|
@@ -9625,7 +11738,7 @@ function parsePipeline(pipelineString) {
|
|
|
9625
11738
|
description = description.split(/^>.*$/gm).join('');
|
|
9626
11739
|
//Note: Remove lists and return statement - TODO: [🎾]
|
|
9627
11740
|
description = description.split(/^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm).join('');
|
|
9628
|
-
description = spaceTrim
|
|
11741
|
+
description = spaceTrim(description);
|
|
9629
11742
|
if (description === '') {
|
|
9630
11743
|
description = undefined;
|
|
9631
11744
|
}
|
|
@@ -9659,7 +11772,7 @@ function parsePipeline(pipelineString) {
|
|
|
9659
11772
|
for (const { listItem, command } of commands) {
|
|
9660
11773
|
const commandParser = getParserForCommand(command);
|
|
9661
11774
|
if (commandParser.isUsedInPipelineTask !== true /* <- Note: [🦦][4] */) {
|
|
9662
|
-
throw new ParseError(spaceTrim
|
|
11775
|
+
throw new ParseError(spaceTrim((block) => `
|
|
9663
11776
|
Command \`${command.type}\` is not allowed in the task of the promptbook ONLY at the pipeline head
|
|
9664
11777
|
|
|
9665
11778
|
${block(getPipelineIdentification())}
|
|
@@ -9674,7 +11787,7 @@ function parsePipeline(pipelineString) {
|
|
|
9674
11787
|
if (!(error instanceof ParseError)) {
|
|
9675
11788
|
throw error;
|
|
9676
11789
|
}
|
|
9677
|
-
throw new ParseError(spaceTrim
|
|
11790
|
+
throw new ParseError(spaceTrim((block) => `
|
|
9678
11791
|
Command \`${command.type}\` failed to apply to the task
|
|
9679
11792
|
|
|
9680
11793
|
The error:
|
|
@@ -9705,14 +11818,14 @@ function parsePipeline(pipelineString) {
|
|
|
9705
11818
|
// TODO: [🍧] Should be done in SECTION command
|
|
9706
11819
|
if ($taskJson.taskType === 'SCRIPT_TASK') {
|
|
9707
11820
|
if (!language) {
|
|
9708
|
-
throw new ParseError(spaceTrim
|
|
11821
|
+
throw new ParseError(spaceTrim((block) => `
|
|
9709
11822
|
You must specify the language of the script in the \`SCRIPT\` task
|
|
9710
11823
|
|
|
9711
11824
|
${block(getPipelineIdentification())}
|
|
9712
11825
|
`));
|
|
9713
11826
|
}
|
|
9714
11827
|
if (!SUPPORTED_SCRIPT_LANGUAGES.includes(language)) {
|
|
9715
|
-
throw new ParseError(spaceTrim
|
|
11828
|
+
throw new ParseError(spaceTrim((block) => `
|
|
9716
11829
|
Script language ${language} is not supported.
|
|
9717
11830
|
|
|
9718
11831
|
Supported languages are:
|
|
@@ -9874,7 +11987,7 @@ function addAutoGeneratedSection(content, options) {
|
|
|
9874
11987
|
const warningLine = `<!-- ${GENERATOR_WARNING} -->`;
|
|
9875
11988
|
const sectionRegex = new RegExp(`<!--${sectionName}-->([\\s\\S]*?)<!--/${sectionName}-->`, 'g');
|
|
9876
11989
|
const sectionMatch = content.match(sectionRegex);
|
|
9877
|
-
const contentToInsert = spaceTrim
|
|
11990
|
+
const contentToInsert = spaceTrim((block) => `
|
|
9878
11991
|
<!--${sectionName}-->
|
|
9879
11992
|
${block(warningLine)}
|
|
9880
11993
|
${block(sectionContent)}
|
|
@@ -9887,7 +12000,7 @@ function addAutoGeneratedSection(content, options) {
|
|
|
9887
12000
|
const placeForSection = removeMarkdownComments(content).match(/^##.*$/im);
|
|
9888
12001
|
if (placeForSection !== null) {
|
|
9889
12002
|
const [heading] = placeForSection;
|
|
9890
|
-
return content.replace(heading, spaceTrim
|
|
12003
|
+
return content.replace(heading, spaceTrim((block) => `
|
|
9891
12004
|
${block(contentToInsert)}
|
|
9892
12005
|
|
|
9893
12006
|
${block(heading)}
|
|
@@ -9896,7 +12009,7 @@ function addAutoGeneratedSection(content, options) {
|
|
|
9896
12009
|
console.warn(`No place where to put the section <!--${sectionName}-->, using the end of the file`);
|
|
9897
12010
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
9898
12011
|
// <- TODO: [🏮] Some better way how to get warnings from pipeline parsing / logic
|
|
9899
|
-
return spaceTrim
|
|
12012
|
+
return spaceTrim((block) => `
|
|
9900
12013
|
${block(content)}
|
|
9901
12014
|
|
|
9902
12015
|
${block(contentToInsert)}
|
|
@@ -9972,7 +12085,7 @@ function renderPromptbookMermaid(pipelineJson, options) {
|
|
|
9972
12085
|
.filter(([MERMAID_NAME]) => (inputAndIntermediateParametersMermaid + outputParametersMermaid).includes(MERMAID_NAME))
|
|
9973
12086
|
.map(([MERMAID_NAME, title]) => `${MERMAID_NAME}((${title})):::${MERMAID_NAME}`)
|
|
9974
12087
|
.join('\n');
|
|
9975
|
-
const promptbookMermaid = spaceTrim
|
|
12088
|
+
const promptbookMermaid = spaceTrim((block) => `
|
|
9976
12089
|
|
|
9977
12090
|
%% 🔮 Tip: Open this on GitHub or in the VSCode website to see the Mermaid graph visually
|
|
9978
12091
|
|
|
@@ -10028,7 +12141,7 @@ async function prettifyPipelineString(pipelineString, options) {
|
|
|
10028
12141
|
return { href: `#${task.name}`, title: task.title };
|
|
10029
12142
|
},
|
|
10030
12143
|
});
|
|
10031
|
-
const promptbookMermaidBlock = spaceTrim
|
|
12144
|
+
const promptbookMermaidBlock = spaceTrim((block) => `
|
|
10032
12145
|
\`\`\`mermaid
|
|
10033
12146
|
${block(promptbookMermaid)}
|
|
10034
12147
|
\`\`\`
|
|
@@ -10066,7 +12179,7 @@ class CallbackInterfaceTools {
|
|
|
10066
12179
|
async promptDialog(options) {
|
|
10067
12180
|
const answer = await this.options.callback(options);
|
|
10068
12181
|
if (this.options.isVerbose) {
|
|
10069
|
-
console.info(spaceTrim
|
|
12182
|
+
console.info(spaceTrim((block) => `
|
|
10070
12183
|
📖 ${block(options.promptTitle)}
|
|
10071
12184
|
👤 ${block(answer)}
|
|
10072
12185
|
`));
|
|
@@ -10205,7 +12318,7 @@ function countWorkingDuration(items) {
|
|
|
10205
12318
|
function executionReportJsonToString(executionReportJson, options) {
|
|
10206
12319
|
var _a, _b, _c, _d, _e, _f;
|
|
10207
12320
|
const { taxRate, chartsWidth } = { ...ExecutionReportStringOptionsDefaults, ...(options || {}) };
|
|
10208
|
-
let executionReportString = spaceTrim
|
|
12321
|
+
let executionReportString = spaceTrim((block) => `
|
|
10209
12322
|
# ${executionReportJson.title || 'Execution report'}
|
|
10210
12323
|
|
|
10211
12324
|
${block(executionReportJson.description || '')}
|
|
@@ -10327,7 +12440,7 @@ function executionReportJsonToString(executionReportJson, options) {
|
|
|
10327
12440
|
if (just(true)) {
|
|
10328
12441
|
executionReportString +=
|
|
10329
12442
|
'\n\n\n\n' +
|
|
10330
|
-
spaceTrim
|
|
12443
|
+
spaceTrim((block) => {
|
|
10331
12444
|
var _a;
|
|
10332
12445
|
return `
|
|
10333
12446
|
|
|
@@ -10346,7 +12459,7 @@ function executionReportJsonToString(executionReportJson, options) {
|
|
|
10346
12459
|
executionReportString += '*No result*';
|
|
10347
12460
|
}
|
|
10348
12461
|
else if (typeof promptExecution.result.content === 'string') {
|
|
10349
|
-
executionReportString += spaceTrim
|
|
12462
|
+
executionReportString += spaceTrim((block) => `
|
|
10350
12463
|
\`\`\`
|
|
10351
12464
|
${block(escapeMarkdownBlock(promptExecution.result.content))}
|
|
10352
12465
|
\`\`\`
|
|
@@ -10359,7 +12472,7 @@ function executionReportJsonToString(executionReportJson, options) {
|
|
|
10359
12472
|
if (promptExecution.error && promptExecution.error.message) {
|
|
10360
12473
|
executionReportString +=
|
|
10361
12474
|
'\n\n\n\n' +
|
|
10362
|
-
spaceTrim
|
|
12475
|
+
spaceTrim((block) => `
|
|
10363
12476
|
|
|
10364
12477
|
### Error
|
|
10365
12478
|
|
|
@@ -10435,7 +12548,7 @@ function usageToHuman(usage) {
|
|
|
10435
12548
|
// Note: For negligible usage, we report at least something
|
|
10436
12549
|
reportItems.push('Negligible');
|
|
10437
12550
|
}
|
|
10438
|
-
return spaceTrim((block) => `
|
|
12551
|
+
return spaceTrim$1((block) => `
|
|
10439
12552
|
Usage:
|
|
10440
12553
|
${block(reportItems.map((item) => `- ${item}`).join('\n'))}
|
|
10441
12554
|
`);
|
|
@@ -10680,13 +12793,13 @@ function $registeredLlmToolsMessage() {
|
|
|
10680
12793
|
});
|
|
10681
12794
|
const usedEnvMessage = `Unknown \`.env\` file` ;
|
|
10682
12795
|
if (metadata.length === 0) {
|
|
10683
|
-
return spaceTrim((block) => `
|
|
12796
|
+
return spaceTrim$1((block) => `
|
|
10684
12797
|
No LLM providers are available.
|
|
10685
12798
|
|
|
10686
12799
|
${block(usedEnvMessage)}
|
|
10687
12800
|
`);
|
|
10688
12801
|
}
|
|
10689
|
-
return spaceTrim((block) => `
|
|
12802
|
+
return spaceTrim$1((block) => `
|
|
10690
12803
|
|
|
10691
12804
|
${block(usedEnvMessage)}
|
|
10692
12805
|
|
|
@@ -10732,7 +12845,7 @@ function $registeredLlmToolsMessage() {
|
|
|
10732
12845
|
morePieces.push(`Not configured`); // <- Note: Can not be configured via environment variables
|
|
10733
12846
|
}
|
|
10734
12847
|
}
|
|
10735
|
-
let providerMessage = spaceTrim(`
|
|
12848
|
+
let providerMessage = spaceTrim$1(`
|
|
10736
12849
|
${i + 1}) **${title}** \`${className}\` from \`${packageName}\`
|
|
10737
12850
|
${morePieces.join('; ')}
|
|
10738
12851
|
`);
|
|
@@ -10778,7 +12891,7 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
|
|
|
10778
12891
|
.find(({ packageName, className }) => llmConfiguration.packageName === packageName && llmConfiguration.className === className);
|
|
10779
12892
|
if (registeredItem === undefined) {
|
|
10780
12893
|
// console.log('$llmToolsRegister.list()', $llmToolsRegister.list());
|
|
10781
|
-
throw new Error(spaceTrim((block) => `
|
|
12894
|
+
throw new Error(spaceTrim$1((block) => `
|
|
10782
12895
|
There is no constructor for LLM provider \`${llmConfiguration.className}\` from \`${llmConfiguration.packageName}\`
|
|
10783
12896
|
Running in ${!$isRunningInBrowser() ? '' : 'browser environment'}${!$isRunningInNode() ? '' : 'node environment'}${!$isRunningInWebWorker() ? '' : 'worker environment'}
|
|
10784
12897
|
|
|
@@ -10915,7 +13028,7 @@ function cacheLlmTools(llmTools, options = {}) {
|
|
|
10915
13028
|
let normalizedContent = content;
|
|
10916
13029
|
normalizedContent = normalizedContent.replace(/\s+/g, ' ');
|
|
10917
13030
|
normalizedContent = normalizedContent.split('\r\n').join('\n');
|
|
10918
|
-
normalizedContent = spaceTrim(normalizedContent);
|
|
13031
|
+
normalizedContent = spaceTrim$1(normalizedContent);
|
|
10919
13032
|
// Note: Do not need to save everything in the cache, just the relevant parameters
|
|
10920
13033
|
const relevantParameterNames = extractParameterNames(content);
|
|
10921
13034
|
const relevantParameters = Object.fromEntries(Object.entries(parameters).filter(([key]) => relevantParameterNames.has(key)));
|
|
@@ -11595,7 +13708,7 @@ function isValidPipelineString(pipelineString) {
|
|
|
11595
13708
|
*/
|
|
11596
13709
|
function prompt(strings, ...values) {
|
|
11597
13710
|
if (values.length === 0) {
|
|
11598
|
-
return spaceTrim(strings.join(''));
|
|
13711
|
+
return spaceTrim$1(strings.join(''));
|
|
11599
13712
|
}
|
|
11600
13713
|
const stringsWithHiddenParameters = strings.map((stringsItem) =>
|
|
11601
13714
|
// TODO: [0] DRY
|
|
@@ -11606,7 +13719,7 @@ function prompt(strings, ...values) {
|
|
|
11606
13719
|
let pipelineString = stringsWithHiddenParameters.reduce((result, stringsItem, i) => placeholderParameterNames[i] === undefined
|
|
11607
13720
|
? `${result}${stringsItem}`
|
|
11608
13721
|
: `${result}${stringsItem}{${placeholderParameterNames[i]}}`, '');
|
|
11609
|
-
pipelineString = spaceTrim(pipelineString);
|
|
13722
|
+
pipelineString = spaceTrim$1(pipelineString);
|
|
11610
13723
|
try {
|
|
11611
13724
|
pipelineString = templateParameters(pipelineString, parameters);
|
|
11612
13725
|
}
|
|
@@ -11615,7 +13728,7 @@ function prompt(strings, ...values) {
|
|
|
11615
13728
|
throw error;
|
|
11616
13729
|
}
|
|
11617
13730
|
console.error({ pipelineString, parameters, placeholderParameterNames, error });
|
|
11618
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
13731
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
11619
13732
|
Internal error in prompt template literal
|
|
11620
13733
|
|
|
11621
13734
|
${block(JSON.stringify({ strings, values }, null, 4))}}
|
|
@@ -11649,18 +13762,28 @@ function prompt(strings, ...values) {
|
|
|
11649
13762
|
* @public exported from `@promptbook/core`
|
|
11650
13763
|
*/
|
|
11651
13764
|
function book(strings, ...values) {
|
|
11652
|
-
const
|
|
11653
|
-
if (!isValidPipelineString(
|
|
13765
|
+
const bookString = prompt(strings, ...values);
|
|
13766
|
+
if (!isValidPipelineString(bookString)) {
|
|
11654
13767
|
// TODO: Make the CustomError for this
|
|
11655
|
-
throw new Error(spaceTrim(`
|
|
13768
|
+
throw new Error(spaceTrim$1(`
|
|
11656
13769
|
The string is not a valid pipeline string
|
|
11657
13770
|
|
|
11658
13771
|
book\`
|
|
11659
|
-
${
|
|
13772
|
+
${bookString}
|
|
11660
13773
|
\`
|
|
11661
13774
|
`));
|
|
11662
13775
|
}
|
|
11663
|
-
|
|
13776
|
+
if (!isValidBook(bookString)) {
|
|
13777
|
+
// TODO: Make the CustomError for this
|
|
13778
|
+
throw new Error(spaceTrim$1(`
|
|
13779
|
+
The string is not a valid book
|
|
13780
|
+
|
|
13781
|
+
book\`
|
|
13782
|
+
${bookString}
|
|
13783
|
+
\`
|
|
13784
|
+
`));
|
|
13785
|
+
}
|
|
13786
|
+
return bookString;
|
|
11664
13787
|
}
|
|
11665
13788
|
/**
|
|
11666
13789
|
* TODO: [🧠][🈴] Where is the best location for this file
|
|
@@ -11990,5 +14113,5 @@ class PrefixStorage {
|
|
|
11990
14113
|
}
|
|
11991
14114
|
}
|
|
11992
14115
|
|
|
11993
|
-
export { $llmToolsMetadataRegister, $llmToolsRegister, $scrapersMetadataRegister, $scrapersRegister, ADMIN_EMAIL, ADMIN_GITHUB_NAME, AbstractFormatError, AuthenticationError, BIG_DATASET_TRESHOLD, BOOK_LANGUAGE_VERSION, BlackholeStorage, BoilerplateError, BoilerplateFormfactorDefinition, CLAIM, CLI_APP_ID, CallbackInterfaceTools, ChatbotFormfactorDefinition, CollectionError, CompletionFormfactorDefinition, CsvFormatError, CsvFormatParser, DEFAULT_BOOKS_DIRNAME, DEFAULT_BOOK_OUTPUT_PARAMETER_NAME, DEFAULT_BOOK_TITLE, DEFAULT_CSV_SETTINGS, DEFAULT_DOWNLOAD_CACHE_DIRNAME, DEFAULT_EXECUTION_CACHE_DIRNAME, DEFAULT_GET_PIPELINE_COLLECTION_FUNCTION_NAME, DEFAULT_INTERMEDIATE_FILES_STRATEGY, DEFAULT_IS_AUTO_INSTALLED, DEFAULT_IS_VERBOSE, DEFAULT_MAX_EXECUTION_ATTEMPTS, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH, DEFAULT_MAX_KNOWLEDGE_SOURCES_SCRAPING_TOTAL, DEFAULT_MAX_PARALLEL_COUNT, DEFAULT_MAX_REQUESTS_PER_MINUTE, DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME, DEFAULT_PROMPT_TASK_TITLE, DEFAULT_REMOTE_SERVER_URL, DEFAULT_SCRAPE_CACHE_DIRNAME, DEFAULT_TASK_TITLE, EXPECTATION_UNITS, EnvironmentMismatchError, ExecutionReportStringOptionsDefaults, ExpectError, FAILED_VALUE_PLACEHOLDER, FORMFACTOR_DEFINITIONS, GENERIC_PIPELINE_INTERFACE, GeneratorFormfactorDefinition, GenericFormfactorDefinition, ImageGeneratorFormfactorDefinition, KnowledgeScrapeError, LimitReachedError, MANDATORY_CSV_SETTINGS, MAX_FILENAME_LENGTH, MODEL_ORDERS, MODEL_TRUST_LEVELS, MODEL_VARIANTS, MatcherFormfactorDefinition, MemoryStorage, MissingToolsError, MultipleLlmExecutionTools, NAME, NonTaskSectionTypes, NotFoundError, NotYetImplementedError, ORDER_OF_PIPELINE_JSON, PENDING_VALUE_PLACEHOLDER, PLAYGROUND_APP_ID, PROMPTBOOK_ENGINE_VERSION, PROMPTBOOK_ERRORS, ParseError, PipelineExecutionError, PipelineLogicError, PipelineUrlError, PrefixStorage, PromptbookFetchError, REMOTE_SERVER_URLS, RESERVED_PARAMETER_NAMES, SET_IS_VERBOSE, SectionTypes, SheetsFormfactorDefinition, TaskTypes, TextFormatParser, TranslatorFormfactorDefinition, UNCERTAIN_USAGE, UNCERTAIN_ZERO_VALUE, UnexpectedError, WrappedError, ZERO_USAGE, ZERO_VALUE, _AnthropicClaudeMetadataRegistration, _AzureOpenAiMetadataRegistration, _BoilerplateScraperMetadataRegistration, _DeepseekMetadataRegistration, _DocumentScraperMetadataRegistration, _GoogleMetadataRegistration, _LegacyDocumentScraperMetadataRegistration, _MarkdownScraperMetadataRegistration, _MarkitdownScraperMetadataRegistration, _OllamaMetadataRegistration, _OpenAiAssistantMetadataRegistration, _OpenAiCompatibleMetadataRegistration, _OpenAiMetadataRegistration, _PdfScraperMetadataRegistration, _WebsiteScraperMetadataRegistration, addUsage, book, cacheLlmTools, collectionToJson, compilePipeline, computeCosineSimilarity, countUsage, createCollectionFromJson, createCollectionFromPromise, createCollectionFromUrl, createLlmToolsFromConfiguration, createPipelineExecutor, createSubcollection, embeddingVectorToString, executionReportJsonToString, extractParameterNamesFromTask, filterModels, getPipelineInterface, identificationToPromptbookToken, isPassingExpectations, isPipelineImplementingInterface, isPipelineInterfacesEqual, isPipelinePrepared, isValidPipelineString, joinLlmExecutionTools, limitTotalUsage, makeKnowledgeSourceHandler, migratePipeline, parsePipeline, pipelineJsonToString, prepareKnowledgePieces, preparePersona, preparePipeline, prettifyPipelineString, promptbookFetch, promptbookTokenToIdentification, unpreparePipeline, usageToHuman, usageToWorktime, validatePipeline, validatePipelineString };
|
|
14116
|
+
export { $llmToolsMetadataRegister, $llmToolsRegister, $scrapersMetadataRegister, $scrapersRegister, ADMIN_EMAIL, ADMIN_GITHUB_NAME, AbstractFormatError, AuthenticationError, BIG_DATASET_TRESHOLD, BOOK_LANGUAGE_VERSION, BlackholeStorage, BoilerplateError, BoilerplateFormfactorDefinition, CLAIM, CLI_APP_ID, CallbackInterfaceTools, ChatbotFormfactorDefinition, CollectionError, CompletionFormfactorDefinition, CsvFormatError, CsvFormatParser, DEFAULT_BOOK, DEFAULT_BOOKS_DIRNAME, DEFAULT_BOOK_OUTPUT_PARAMETER_NAME, DEFAULT_BOOK_TITLE, DEFAULT_CSV_SETTINGS, DEFAULT_DOWNLOAD_CACHE_DIRNAME, DEFAULT_EXECUTION_CACHE_DIRNAME, DEFAULT_GET_PIPELINE_COLLECTION_FUNCTION_NAME, DEFAULT_INTERMEDIATE_FILES_STRATEGY, DEFAULT_IS_AUTO_INSTALLED, DEFAULT_IS_VERBOSE, DEFAULT_MAX_EXECUTION_ATTEMPTS, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH, DEFAULT_MAX_KNOWLEDGE_SOURCES_SCRAPING_TOTAL, DEFAULT_MAX_PARALLEL_COUNT, DEFAULT_MAX_REQUESTS_PER_MINUTE, DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME, DEFAULT_PROMPT_TASK_TITLE, DEFAULT_REMOTE_SERVER_URL, DEFAULT_SCRAPE_CACHE_DIRNAME, DEFAULT_TASK_SIMULATED_DURATION_MS, DEFAULT_TASK_TITLE, EXPECTATION_UNITS, EnvironmentMismatchError, ExecutionReportStringOptionsDefaults, ExpectError, FAILED_VALUE_PLACEHOLDER, FORMFACTOR_DEFINITIONS, GENERIC_PIPELINE_INTERFACE, GeneratorFormfactorDefinition, GenericFormfactorDefinition, ImageGeneratorFormfactorDefinition, KnowledgeScrapeError, LimitReachedError, MANDATORY_CSV_SETTINGS, MAX_FILENAME_LENGTH, MODEL_ORDERS, MODEL_TRUST_LEVELS, MODEL_VARIANTS, MatcherFormfactorDefinition, MemoryStorage, MissingToolsError, MultipleLlmExecutionTools, NAME, NonTaskSectionTypes, NotFoundError, NotYetImplementedCommitmentDefinition, NotYetImplementedError, ORDER_OF_PIPELINE_JSON, PENDING_VALUE_PLACEHOLDER, PLAYGROUND_APP_ID, PROMPTBOOK_ENGINE_VERSION, PROMPTBOOK_ERRORS, ParseError, PipelineExecutionError, PipelineLogicError, PipelineUrlError, PrefixStorage, PromptbookFetchError, REMOTE_SERVER_URLS, RESERVED_PARAMETER_NAMES, SET_IS_VERBOSE, SectionTypes, SheetsFormfactorDefinition, TaskTypes, TextFormatParser, TranslatorFormfactorDefinition, UNCERTAIN_USAGE, UNCERTAIN_ZERO_VALUE, UnexpectedError, WrappedError, ZERO_USAGE, ZERO_VALUE, _AnthropicClaudeMetadataRegistration, _AzureOpenAiMetadataRegistration, _BoilerplateScraperMetadataRegistration, _DeepseekMetadataRegistration, _DocumentScraperMetadataRegistration, _GoogleMetadataRegistration, _LegacyDocumentScraperMetadataRegistration, _MarkdownScraperMetadataRegistration, _MarkitdownScraperMetadataRegistration, _OllamaMetadataRegistration, _OpenAiAssistantMetadataRegistration, _OpenAiCompatibleMetadataRegistration, _OpenAiMetadataRegistration, _PdfScraperMetadataRegistration, _WebsiteScraperMetadataRegistration, addUsage, book, cacheLlmTools, collectionToJson, compilePipeline, computeCosineSimilarity, countUsage, createAgentModelRequirements, createBasicAgentModelRequirements, createCollectionFromJson, createCollectionFromPromise, createCollectionFromUrl, createEmptyAgentModelRequirements, createLlmToolsFromConfiguration, createPipelineExecutor, createSubcollection, embeddingVectorToString, executionReportJsonToString, extractParameterNamesFromTask, filterModels, getAllCommitmentDefinitions, getAllCommitmentTypes, getCommitmentDefinition, getPipelineInterface, identificationToPromptbookToken, isCommitmentSupported, isPassingExpectations, isPipelineImplementingInterface, isPipelineInterfacesEqual, isPipelinePrepared, isValidBook, isValidPipelineString, joinLlmExecutionTools, limitTotalUsage, makeKnowledgeSourceHandler, migratePipeline, parseAgentSource, parsePipeline, pipelineJsonToString, prepareKnowledgePieces, preparePersona, preparePipeline, prettifyPipelineString, promptbookFetch, promptbookTokenToIdentification, unpreparePipeline, usageToHuman, usageToWorktime, validateBook, validatePipeline, validatePipelineString };
|
|
11994
14117
|
//# sourceMappingURL=index.es.js.map
|