@promptbook/wizard 0.100.0-1 → 0.100.0-10

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.
@@ -138,9 +138,6 @@ export declare const SMALL_NUMBER = 0.001;
138
138
  /**
139
139
  * Timeout for the connections in milliseconds
140
140
  *
141
- * Note: Increased from 7 seconds to 30 seconds to accommodate OAuth flows
142
- * like Facebook login which may require user interaction and redirects
143
- *
144
141
  * @private within the repository - too low-level in comparison with other `MAX_...`
145
142
  */
146
143
  export declare const CONNECTION_TIMEOUT_MS: number;
@@ -150,13 +147,6 @@ export declare const CONNECTION_TIMEOUT_MS: number;
150
147
  * @private within the repository - too low-level in comparison with other `MAX_...`
151
148
  */
152
149
  export declare const CONNECTION_RETRIES_LIMIT = 5;
153
- /**
154
- * Timeout specifically for OAuth authentication flows in milliseconds
155
- * OAuth flows typically require more time due to user interaction and redirects
156
- *
157
- * @private within the repository - too low-level in comparison with other `MAX_...`
158
- */
159
- export declare const OAUTH_TIMEOUT_MS: number;
160
150
  /**
161
151
  * Short time interval to prevent race conditions in milliseconds
162
152
  *
@@ -15,7 +15,7 @@ export declare const BOOK_LANGUAGE_VERSION: string_semantic_version;
15
15
  export declare const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version;
16
16
  /**
17
17
  * Represents the version string of the Promptbook engine.
18
- * It follows semantic versioning (e.g., `0.100.0-0`).
18
+ * It follows semantic versioning (e.g., `0.100.0-9`).
19
19
  *
20
20
  * @generated
21
21
  */
@@ -6,6 +6,15 @@ import type { InputParameters } from '../types/typeAliases';
6
6
  import type { string_filename } from '../types/typeAliases';
7
7
  import type { string_parameter_value } from '../types/typeAliases';
8
8
  import type { string_pipeline_url } from '../types/typeAliases';
9
+ /**
10
+ * Options for wizard methods
11
+ */
12
+ interface WizardOptions {
13
+ /**
14
+ * Whether to enable verbose logging
15
+ */
16
+ isVerbose?: boolean;
17
+ }
9
18
  /**
10
19
  * Wizard for simple usage of the Promptbook
11
20
  * Look at `wizard` for more details
@@ -26,7 +35,7 @@ declare class Wizard {
26
35
  *
27
36
  * Note: This works similar to the `ptbk run` command
28
37
  */
29
- execute(book: string_pipeline_url | string_filename | PipelineString, inputParameters: InputParameters): Promise<{
38
+ execute(book: string_pipeline_url | string_filename | PipelineString, inputParameters: InputParameters, options?: WizardOptions): Promise<{
30
39
  /**
31
40
  * Simple result of the execution
32
41
  */
@@ -36,9 +45,9 @@ declare class Wizard {
36
45
  /**
37
46
  * Provides the tools automatically for the Node.js environment
38
47
  *
39
- * @param pipelineSource
48
+ * @param options
40
49
  */
41
- getExecutionTools(): Promise<Required<Pick<ExecutionTools, 'fs' | 'fetch'>>>;
50
+ getExecutionTools(options?: WizardOptions): Promise<Required<Pick<ExecutionTools, 'fs' | 'fetch'>>>;
42
51
  /**
43
52
  * Load book from the source
44
53
  *
@@ -49,8 +58,9 @@ declare class Wizard {
49
58
  * 3) As a string
50
59
  *
51
60
  * @param pipelineSource
61
+ * @param options
52
62
  */
53
- getCompiledBook(pipelineSource: string_filename | string_pipeline_url | PipelineString): Promise<PipelineJson>;
63
+ getCompiledBook(pipelineSource: string_filename | string_pipeline_url | PipelineString, options?: WizardOptions): Promise<PipelineJson>;
54
64
  }
55
65
  /**
56
66
  * Wizard for simple usage of the Promptbook
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptbook/wizard",
3
- "version": "0.100.0-1",
3
+ "version": "0.100.0-10",
4
4
  "description": "Promptbook: Run AI apps in plain human language across multiple models and platforms",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -95,7 +95,7 @@
95
95
  "module": "./esm/index.es.js",
96
96
  "typings": "./esm/typings/src/_packages/wizard.index.d.ts",
97
97
  "peerDependencies": {
98
- "@promptbook/core": "0.100.0-1"
98
+ "@promptbook/core": "0.100.0-10"
99
99
  },
100
100
  "dependencies": {
101
101
  "@ai-sdk/deepseek": "0.1.6",
package/umd/index.umd.js CHANGED
@@ -49,7 +49,7 @@
49
49
  * @generated
50
50
  * @see https://github.com/webgptorg/promptbook
51
51
  */
52
- const PROMPTBOOK_ENGINE_VERSION = '0.100.0-1';
52
+ const PROMPTBOOK_ENGINE_VERSION = '0.100.0-10';
53
53
  /**
54
54
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
55
55
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -203,12 +203,9 @@
203
203
  /**
204
204
  * Timeout for the connections in milliseconds
205
205
  *
206
- * Note: Increased from 7 seconds to 30 seconds to accommodate OAuth flows
207
- * like Facebook login which may require user interaction and redirects
208
- *
209
206
  * @private within the repository - too low-level in comparison with other `MAX_...`
210
207
  */
211
- const CONNECTION_TIMEOUT_MS = 30 * 1000;
208
+ const CONNECTION_TIMEOUT_MS = 7 * 1000;
212
209
  // <- TODO: [⏳] Standardize timeouts, Make DEFAULT_TIMEOUT_MS as global constant
213
210
  /**
214
211
  * How many times to retry the connections
@@ -1400,39 +1397,13 @@
1400
1397
  transports: ['polling', 'websocket' /*, <- TODO: [🌬] Allow to pass `transports`, add 'webtransport' */],
1401
1398
  });
1402
1399
  // console.log('Connecting to', this.options.remoteServerUrl.href, { socket });
1403
- let isResolved = false;
1404
1400
  socket.on('connect', () => {
1405
- if (!isResolved) {
1406
- isResolved = true;
1407
- resolve(socket);
1408
- }
1409
- });
1410
- socket.on('connect_error', (error) => {
1411
- if (!isResolved) {
1412
- isResolved = true;
1413
- reject(new Error(`Failed to connect to ${remoteServerUrl}: ${error.message || error}`));
1414
- }
1415
- });
1416
- socket.on('disconnect', (reason) => {
1417
- if (!isResolved) {
1418
- isResolved = true;
1419
- reject(new Error(`Connection to ${remoteServerUrl} was disconnected: ${reason}`));
1420
- }
1401
+ resolve(socket);
1421
1402
  });
1422
- // Better timeout handling with more descriptive error message
1423
- const timeoutId = setTimeout(() => {
1424
- if (!isResolved) {
1425
- isResolved = true;
1426
- socket.disconnect();
1427
- reject(new Error(`Connection timeout after ${CONNECTION_TIMEOUT_MS / 1000} seconds while connecting to ${remoteServerUrl}. ` +
1428
- `This may indicate network issues or the server may be experiencing high load. ` +
1429
- `For authentication flows like social login, ensure sufficient time is allowed for user interaction.`));
1430
- }
1403
+ // TODO: [💩] Better timeout handling
1404
+ setTimeout(() => {
1405
+ reject(new Error(`Timeout while connecting to ${remoteServerUrl}`));
1431
1406
  }, CONNECTION_TIMEOUT_MS);
1432
- // Clean up timeout if connection succeeds
1433
- socket.on('connect', () => {
1434
- clearTimeout(timeoutId);
1435
- });
1436
1407
  });
1437
1408
  }
1438
1409
 
@@ -1478,33 +1449,8 @@
1478
1449
  * Check the configuration of all execution tools
1479
1450
  */
1480
1451
  async checkConfiguration() {
1481
- try {
1482
- const socket = await createRemoteClient(this.options);
1483
- socket.disconnect();
1484
- }
1485
- catch (error) {
1486
- if (error instanceof Error) {
1487
- // Provide user-friendly error messages for common connection issues
1488
- if (error.message.includes('timeout') || error.message.includes('Timeout')) {
1489
- throw new Error(`Connection to Promptbook server timed out. This may happen during authentication flows like Facebook login. ` +
1490
- `Please ensure: 1) Server is running at ${this.options.remoteServerUrl}, ` +
1491
- `2) Network connection is stable, 3) Authentication process is completed within the timeout period. ` +
1492
- `Original error: ${error.message}`);
1493
- }
1494
- if (error.message.includes('connect') || error.message.includes('ECONNREFUSED')) {
1495
- throw new Error(`Cannot connect to Promptbook server at ${this.options.remoteServerUrl}. ` +
1496
- `Please check if the server is running and accessible. ` +
1497
- `Original error: ${error.message}`);
1498
- }
1499
- if (error.message.includes('authentication') || error.message.includes('auth')) {
1500
- throw new Error(`Authentication failed when connecting to Promptbook server. ` +
1501
- `This may happen if social login (like Facebook) was not completed properly. ` +
1502
- `Please retry the authentication process. ` +
1503
- `Original error: ${error.message}`);
1504
- }
1505
- }
1506
- throw error; // Re-throw if not a recognized error pattern
1507
- }
1452
+ const socket = await createRemoteClient(this.options);
1453
+ socket.disconnect();
1508
1454
  // TODO: [main] !!3 Check version of the remote server and compatibility
1509
1455
  // TODO: [🎍] Send checkConfiguration
1510
1456
  }
@@ -6028,7 +5974,23 @@
6028
5974
  .join('/') +
6029
5975
  '.' +
6030
5976
  extension;
6031
- await promises.mkdir(path.dirname(cacheFilename), { recursive: true });
5977
+ // Note: Try to create cache directory, but don't fail if filesystem has issues
5978
+ try {
5979
+ await promises.mkdir(path.dirname(cacheFilename), { recursive: true });
5980
+ }
5981
+ catch (error) {
5982
+ // Note: If we can't create cache directory, continue without it
5983
+ // This handles read-only filesystems, permission issues, and missing parent directories
5984
+ if (error instanceof Error && (error.message.includes('EROFS') ||
5985
+ error.message.includes('read-only') ||
5986
+ error.message.includes('EACCES') ||
5987
+ error.message.includes('EPERM') ||
5988
+ error.message.includes('ENOENT'))) ;
5989
+ else {
5990
+ // Re-throw other unexpected errors
5991
+ throw error;
5992
+ }
5993
+ }
6032
5994
  let isDestroyed = true;
6033
5995
  const fileHandler = {
6034
5996
  filename: cacheFilename,
@@ -7792,12 +7754,58 @@
7792
7754
  // <- TODO: [🥬] Encapsulate sha256 to some private utility function
7793
7755
  const rootDirname = path.join(process.cwd(), DEFAULT_DOWNLOAD_CACHE_DIRNAME);
7794
7756
  const filepath = path.join(...nameToSubfolderPath(hash /* <- TODO: [🎎] Maybe add some SHA256 prefix */), `${basename.substring(0, MAX_FILENAME_LENGTH)}.${mimeTypeToExtension(mimeType)}`);
7795
- await tools.fs.mkdir(path.dirname(path.join(rootDirname, filepath)), { recursive: true });
7757
+ // Note: Try to create cache directory, but don't fail if filesystem has issues
7758
+ try {
7759
+ await tools.fs.mkdir(path.dirname(path.join(rootDirname, filepath)), { recursive: true });
7760
+ }
7761
+ catch (error) {
7762
+ // Note: If we can't create cache directory, we'll handle it when trying to write the file
7763
+ // This handles read-only filesystems, permission issues, and missing parent directories
7764
+ if (error instanceof Error && (error.message.includes('EROFS') ||
7765
+ error.message.includes('read-only') ||
7766
+ error.message.includes('EACCES') ||
7767
+ error.message.includes('EPERM') ||
7768
+ error.message.includes('ENOENT'))) ;
7769
+ else {
7770
+ // Re-throw other unexpected errors
7771
+ throw error;
7772
+ }
7773
+ }
7796
7774
  const fileContent = Buffer.from(await response.arrayBuffer());
7797
7775
  if (fileContent.length > DEFAULT_MAX_FILE_SIZE /* <- TODO: Allow to pass different value to remote server */) {
7798
7776
  throw new LimitReachedError(`File is too large (${Math.round(fileContent.length / 1024 / 1024)}MB). Maximum allowed size is ${Math.round(DEFAULT_MAX_FILE_SIZE / 1024 / 1024)}MB.`);
7799
7777
  }
7800
- await tools.fs.writeFile(path.join(rootDirname, filepath), fileContent);
7778
+ // Note: Try to cache the downloaded file, but don't fail if the filesystem is read-only
7779
+ try {
7780
+ await tools.fs.writeFile(path.join(rootDirname, filepath), fileContent);
7781
+ }
7782
+ catch (error) {
7783
+ // Note: If we can't write to cache, we'll process the file directly from memory
7784
+ // This handles read-only filesystems like Vercel
7785
+ if (error instanceof Error && (error.message.includes('EROFS') ||
7786
+ error.message.includes('read-only') ||
7787
+ error.message.includes('EACCES') ||
7788
+ error.message.includes('EPERM') ||
7789
+ error.message.includes('ENOENT'))) {
7790
+ // Return a handler that works directly with the downloaded content
7791
+ return {
7792
+ source: name,
7793
+ filename: null,
7794
+ url,
7795
+ mimeType,
7796
+ async asJson() {
7797
+ return JSON.parse(fileContent.toString('utf-8'));
7798
+ },
7799
+ async asText() {
7800
+ return fileContent.toString('utf-8');
7801
+ },
7802
+ };
7803
+ }
7804
+ else {
7805
+ // Re-throw other unexpected errors
7806
+ throw error;
7807
+ }
7808
+ }
7801
7809
  // TODO: [💵] Check the file security
7802
7810
  // TODO: [🧹][🧠] Delete the file after the scraping is done
7803
7811
  return makeKnowledgeSourceHandler({ name, knowledgeSourceContent: filepath }, tools, {
@@ -10875,7 +10883,23 @@
10875
10883
  // <- TODO: [🍀] Make MarkitdownError
10876
10884
  }
10877
10885
  // console.log('!!', { result, cacheFilehandler });
10878
- await this.tools.fs.writeFile(cacheFilehandler.filename, result.text_content);
10886
+ // Note: Try to cache the converted content, but don't fail if the filesystem is read-only
10887
+ try {
10888
+ await this.tools.fs.writeFile(cacheFilehandler.filename, result.text_content);
10889
+ }
10890
+ catch (error) {
10891
+ // Note: If we can't write to cache, we'll continue without caching
10892
+ // This handles read-only filesystems like Vercel
10893
+ if (error instanceof Error && (error.message.includes('EROFS') ||
10894
+ error.message.includes('read-only') ||
10895
+ error.message.includes('EACCES') ||
10896
+ error.message.includes('EPERM') ||
10897
+ error.message.includes('ENOENT'))) ;
10898
+ else {
10899
+ // Re-throw other unexpected errors
10900
+ throw error;
10901
+ }
10902
+ }
10879
10903
  }
10880
10904
  return cacheFilehandler;
10881
10905
  }
@@ -11163,7 +11187,23 @@
11163
11187
  extension: 'html',
11164
11188
  isVerbose,
11165
11189
  });
11166
- await this.tools.fs.writeFile(cacheFilehandler.filename, html, 'utf-8');
11190
+ // Note: Try to cache the scraped content, but don't fail if the filesystem is read-only
11191
+ try {
11192
+ await this.tools.fs.writeFile(cacheFilehandler.filename, html, 'utf-8');
11193
+ }
11194
+ catch (error) {
11195
+ // Note: If we can't write to cache, we'll continue without caching
11196
+ // This handles read-only filesystems like Vercel
11197
+ if (error instanceof Error && (error.message.includes('EROFS') ||
11198
+ error.message.includes('read-only') ||
11199
+ error.message.includes('EACCES') ||
11200
+ error.message.includes('EPERM') ||
11201
+ error.message.includes('ENOENT'))) ;
11202
+ else {
11203
+ // Re-throw other unexpected errors
11204
+ throw error;
11205
+ }
11206
+ }
11167
11207
  const markdown = this.showdownConverter.makeMarkdown(html, jsdom$1.window.document);
11168
11208
  return { ...cacheFilehandler, markdown };
11169
11209
  }
@@ -11904,8 +11944,27 @@
11904
11944
  throw new UnexpectedError(`The "${key}" you want to store in JSON file is not serializable as JSON`);
11905
11945
  }
11906
11946
  const fileContent = stringifyPipelineJson(value);
11907
- await promises.mkdir(path.dirname(filename), { recursive: true }); // <- [0]
11908
- await promises.writeFile(filename, fileContent, 'utf-8');
11947
+ // Note: Try to create cache directory and write file, but don't fail if filesystem is read-only or has permission issues
11948
+ try {
11949
+ await promises.mkdir(path.dirname(filename), { recursive: true }); // <- [0]
11950
+ await promises.writeFile(filename, fileContent, 'utf-8');
11951
+ }
11952
+ catch (error) {
11953
+ // Note: If we can't write to cache, silently ignore the error
11954
+ // This handles read-only filesystems, permission issues, and missing parent directories
11955
+ if (error instanceof Error && (error.message.includes('EROFS') ||
11956
+ error.message.includes('read-only') ||
11957
+ error.message.includes('EACCES') ||
11958
+ error.message.includes('EPERM') ||
11959
+ error.message.includes('ENOENT'))) {
11960
+ // Silently ignore filesystem errors - caching is optional
11961
+ return;
11962
+ }
11963
+ else {
11964
+ // Re-throw other unexpected errors
11965
+ throw error;
11966
+ }
11967
+ }
11909
11968
  }
11910
11969
  /**
11911
11970
  * Removes the key/value pair with the given key from the storage, if a key/value pair with the given key exists.
@@ -16775,7 +16834,23 @@
16775
16834
  ...options,
16776
16835
  });
16777
16836
  const compiledFilePath = filePath.replace('.book.md', '.book').replace('.book', '.bookc');
16778
- await saveArchive(compiledFilePath, [pipelineJson], fs);
16837
+ // Note: Try to save the compiled book to disk for caching, but don't fail if the filesystem is read-only
16838
+ try {
16839
+ await saveArchive(compiledFilePath, [pipelineJson], fs);
16840
+ }
16841
+ catch (error) {
16842
+ // Note: Ignore filesystem errors (like EROFS on read-only systems like Vercel)
16843
+ // The compiled book can still be used even if it can't be cached
16844
+ if (error instanceof Error && (error.message.includes('EROFS') ||
16845
+ error.message.includes('read-only') ||
16846
+ error.message.includes('EACCES') ||
16847
+ error.message.includes('EPERM') ||
16848
+ error.message.includes('ENOENT'))) ;
16849
+ else {
16850
+ // Re-throw other unexpected errors
16851
+ throw error;
16852
+ }
16853
+ }
16779
16854
  return pipelineJson;
16780
16855
  }
16781
16856
  }
@@ -16897,14 +16972,14 @@
16897
16972
  *
16898
16973
  * Note: This works similar to the `ptbk run` command
16899
16974
  */
16900
- async execute(book, inputParameters) {
16975
+ async execute(book, inputParameters, options = {}) {
16901
16976
  if (!$isRunningInNode()) {
16902
16977
  throw new EnvironmentMismatchError('Wizard works only in Node.js environment');
16903
16978
  }
16904
16979
  // ▶ Get the tools
16905
- const tools = await this.getExecutionTools();
16980
+ const tools = await this.getExecutionTools(options);
16906
16981
  // ▶ Get the Pipeline
16907
- const pipeline = await this.getCompiledBook(book);
16982
+ const pipeline = await this.getCompiledBook(book, options);
16908
16983
  // ▶ Create executor - the function that will execute the Pipeline
16909
16984
  const pipelineExecutor = createPipelineExecutor({ pipeline, tools });
16910
16985
  // 🚀▶ Execute the Pipeline
@@ -16927,15 +17002,16 @@
16927
17002
  /**
16928
17003
  * Provides the tools automatically for the Node.js environment
16929
17004
  *
16930
- * @param pipelineSource
17005
+ * @param options
16931
17006
  */
16932
- async getExecutionTools() {
17007
+ async getExecutionTools(options = {}) {
17008
+ var _a;
16933
17009
  if (this.executionTools !== null) {
16934
17010
  return this.executionTools;
16935
17011
  }
16936
17012
  // TODO: DRY [◽]
16937
17013
  const prepareAndScrapeOptions = {
16938
- isVerbose: false,
17014
+ isVerbose: (_a = options.isVerbose) !== null && _a !== void 0 ? _a : false,
16939
17015
  isCacheReloaded: false, // <- TODO: Allow to pass
16940
17016
  }; /* <- TODO: ` satisfies PrepareAndScrapeOptions` */
16941
17017
  const fs = $provideFilesystemForNode();
@@ -16965,9 +17041,10 @@
16965
17041
  * 3) As a string
16966
17042
  *
16967
17043
  * @param pipelineSource
17044
+ * @param options
16968
17045
  */
16969
- async getCompiledBook(pipelineSource) {
16970
- const tools = await this.getExecutionTools();
17046
+ async getCompiledBook(pipelineSource, options = {}) {
17047
+ const tools = await this.getExecutionTools(options);
16971
17048
  return /* not await */ $getCompiledBook(tools, pipelineSource);
16972
17049
  }
16973
17050
  }