@promptbook/node 0.100.1 โ†’ 0.100.3-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,6 +29,10 @@ Write AI applications using plain human language across multiple models and plat
29
29
 
30
30
 
31
31
 
32
+ <blockquote style="color: #ff8811">
33
+ <b>โš  Warning:</b> This is a pre-release version of the library. It is not yet ready for production use. Please look at <a href="https://www.npmjs.com/package/@promptbook/core?activeTab=versions">latest stable release</a>.
34
+ </blockquote>
35
+
32
36
  ## ๐Ÿ“ฆ Package `@promptbook/node`
33
37
 
34
38
  - Promptbooks are [divided into several](#-packages) packages, all are published from [single monorepo](https://github.com/webgptorg/promptbook).
package/esm/index.es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import colors from 'colors';
2
2
  import { stat, access, constants, readFile, writeFile, readdir, mkdir, unlink } from 'fs/promises';
3
- import { basename, join, dirname, relative } from 'path';
3
+ import { basename, join, dirname, isAbsolute, relative } from 'path';
4
4
  import spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
5
5
  import JSZip from 'jszip';
6
6
  import parserHtml from 'prettier/parser-html';
@@ -31,7 +31,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
31
31
  * @generated
32
32
  * @see https://github.com/webgptorg/promptbook
33
33
  */
34
- const PROMPTBOOK_ENGINE_VERSION = '0.100.1';
34
+ const PROMPTBOOK_ENGINE_VERSION = '0.100.3-0';
35
35
  /**
36
36
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
37
37
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
@@ -1185,7 +1185,7 @@ function isValidEmail(email) {
1185
1185
  }
1186
1186
 
1187
1187
  /**
1188
- * Tests if given string is valid URL.
1188
+ * Tests if given string is valid file path.
1189
1189
  *
1190
1190
  * Note: This does not check if the file exists only if the path is valid
1191
1191
  * @public exported from `@promptbook/utils`
@@ -1197,18 +1197,25 @@ function isValidFilePath(filename) {
1197
1197
  if (filename.split('\n').length > 1) {
1198
1198
  return false;
1199
1199
  }
1200
- if (filename.split(' ').length >
1201
- 5 /* <- TODO: [๐Ÿง ][๐Ÿˆท] Make some better non-arbitrary way how to distinct filenames from informational texts */) {
1200
+ // Normalize slashes early so heuristics can detect path-like inputs
1201
+ const filenameSlashes = filename.replace(/\\/g, '/');
1202
+ // Reject strings that look like sentences (informational text)
1203
+ // Heuristic: contains multiple spaces and ends with a period, or contains typical sentence punctuation
1204
+ // But skip this heuristic if the string looks like a path (contains '/' or starts with a drive letter)
1205
+ if (filename.trim().length > 60 && // long enough to be a sentence
1206
+ /[.!?]/.test(filename) && // contains sentence punctuation
1207
+ filename.split(' ').length > 8 && // has many words
1208
+ !/\/|^[A-Z]:/i.test(filenameSlashes) // do NOT treat as sentence if looks like a path
1209
+ ) {
1202
1210
  return false;
1203
1211
  }
1204
- const filenameSlashes = filename.split('\\').join('/');
1205
1212
  // Absolute Unix path: /hello.txt
1206
1213
  if (/^(\/)/i.test(filenameSlashes)) {
1207
1214
  // console.log(filename, 'Absolute Unix path: /hello.txt');
1208
1215
  return true;
1209
1216
  }
1210
- // Absolute Windows path: /hello.txt
1211
- if (/^([A-Z]{1,2}:\/?)\//i.test(filenameSlashes)) {
1217
+ // Absolute Windows path: C:/ or C:\ (allow spaces and multiple dots in filename)
1218
+ if (/^[A-Z]:\/.+$/i.test(filenameSlashes)) {
1212
1219
  // console.log(filename, 'Absolute Windows path: /hello.txt');
1213
1220
  return true;
1214
1221
  }
@@ -5800,9 +5807,15 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
5800
5807
  }
5801
5808
  if (isValidUrl(knowledgeSourceContent)) {
5802
5809
  const url = knowledgeSourceContent;
5810
+ if (isVerbose) {
5811
+ console.info(`๐Ÿ“„ [1] "${name}" is available at "${url}"`);
5812
+ }
5803
5813
  const response = await fetch(url); // <- TODO: [๐Ÿง ] Scraping and fetch proxy
5804
5814
  const mimeType = ((_a = response.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.split(';')[0]) || 'text/html';
5805
5815
  if (tools.fs === undefined || !url.endsWith('.pdf' /* <- TODO: [๐Ÿ’ต] */)) {
5816
+ if (isVerbose) {
5817
+ console.info(`๐Ÿ“„ [2] "${name}" tools.fs is not available or URL is not a PDF.`);
5818
+ }
5806
5819
  return {
5807
5820
  source: name,
5808
5821
  filename: null,
@@ -5838,13 +5851,17 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
5838
5851
  await tools.fs.mkdir(dirname(join(rootDirname, filepath)), { recursive: true });
5839
5852
  }
5840
5853
  catch (error) {
5854
+ if (isVerbose) {
5855
+ console.info(`๐Ÿ“„ [3] "${name}" error creating cache directory`);
5856
+ }
5841
5857
  // Note: If we can't create cache directory, we'll handle it when trying to write the file
5842
5858
  // This handles read-only filesystems, permission issues, and missing parent directories
5843
- if (error instanceof Error && (error.message.includes('EROFS') ||
5844
- error.message.includes('read-only') ||
5845
- error.message.includes('EACCES') ||
5846
- error.message.includes('EPERM') ||
5847
- error.message.includes('ENOENT'))) ;
5859
+ if (error instanceof Error &&
5860
+ (error.message.includes('EROFS') ||
5861
+ error.message.includes('read-only') ||
5862
+ error.message.includes('EACCES') ||
5863
+ error.message.includes('EPERM') ||
5864
+ error.message.includes('ENOENT'))) ;
5848
5865
  else {
5849
5866
  // Re-throw other unexpected errors
5850
5867
  throw error;
@@ -5859,13 +5876,17 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
5859
5876
  await tools.fs.writeFile(join(rootDirname, filepath), fileContent);
5860
5877
  }
5861
5878
  catch (error) {
5879
+ if (isVerbose) {
5880
+ console.info(`๐Ÿ“„ [4] "${name}" error writing cache file`);
5881
+ }
5862
5882
  // Note: If we can't write to cache, we'll process the file directly from memory
5863
5883
  // This handles read-only filesystems like Vercel
5864
- if (error instanceof Error && (error.message.includes('EROFS') ||
5865
- error.message.includes('read-only') ||
5866
- error.message.includes('EACCES') ||
5867
- error.message.includes('EPERM') ||
5868
- error.message.includes('ENOENT'))) {
5884
+ if (error instanceof Error &&
5885
+ (error.message.includes('EROFS') ||
5886
+ error.message.includes('read-only') ||
5887
+ error.message.includes('EACCES') ||
5888
+ error.message.includes('EPERM') ||
5889
+ error.message.includes('ENOENT'))) {
5869
5890
  // Return a handler that works directly with the downloaded content
5870
5891
  return {
5871
5892
  source: name,
@@ -5887,6 +5908,9 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
5887
5908
  }
5888
5909
  // TODO: [๐Ÿ’ต] Check the file security
5889
5910
  // TODO: [๐Ÿงน][๐Ÿง ] Delete the file after the scraping is done
5911
+ if (isVerbose) {
5912
+ console.info(`๐Ÿ“„ [5] "${name}" cached at "${join(rootDirname, filepath)}"`);
5913
+ }
5890
5914
  return makeKnowledgeSourceHandler({ name, knowledgeSourceContent: filepath }, tools, {
5891
5915
  ...options,
5892
5916
  rootDirname,
@@ -5901,7 +5925,12 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
5901
5925
  throw new EnvironmentMismatchError('Can not import file knowledge in non-file pipeline');
5902
5926
  // <- TODO: [๐Ÿง ] What is the best error type here`
5903
5927
  }
5904
- const filename = join(rootDirname, knowledgeSourceContent).split('\\').join('/');
5928
+ const filename = isAbsolute(knowledgeSourceContent)
5929
+ ? knowledgeSourceContent
5930
+ : join(rootDirname, knowledgeSourceContent).split('\\').join('/');
5931
+ if (isVerbose) {
5932
+ console.info(`๐Ÿ“„ [6] "${name}" is a valid file "${filename}"`);
5933
+ }
5905
5934
  const fileExtension = getFileExtension(filename);
5906
5935
  const mimeType = extensionToMimeType(fileExtension || '');
5907
5936
  if (!(await isFileExisting(filename, tools.fs))) {
@@ -5943,6 +5972,12 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
5943
5972
  };
5944
5973
  }
5945
5974
  else {
5975
+ if (isVerbose) {
5976
+ console.info(`๐Ÿ“„ [7] "${name}" is just a explicit string text with a knowledge source`);
5977
+ console.info('---');
5978
+ console.info(knowledgeSourceContent);
5979
+ console.info('---');
5980
+ }
5946
5981
  return {
5947
5982
  source: name,
5948
5983
  filename: null,