@promptbook/node 0.100.0 โ†’ 0.100.2

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.
@@ -1,7 +1,7 @@
1
1
  import type { string_agent_name } from '../../types/typeAliases';
2
2
  import type { string_url_image } from '../../types/typeAliases';
3
3
  import type { string_book } from './string_book';
4
- export interface AgentBasicInformation {
4
+ export type AgentBasicInformation = {
5
5
  /**
6
6
  * Name of the agent
7
7
  * This is the first line of the agent source
@@ -17,7 +17,7 @@ export interface AgentBasicInformation {
17
17
  * This is the line starting with "META IMAGE"
18
18
  */
19
19
  profileImageUrl: string_url_image;
20
- }
20
+ };
21
21
  /**
22
22
  * Parses basic information from agent source
23
23
  *
@@ -6,7 +6,7 @@ import type { AgentModelRequirements } from '../_misc/AgentModelRequirements';
6
6
  * - Creating regex patterns for parsing
7
7
  * - Applying its effects to agent model requirements
8
8
  */
9
- export interface CommitmentDefinition {
9
+ export type CommitmentDefinition = {
10
10
  /**
11
11
  * The type/name of this commitment (e.g., 'PERSONA', 'KNOWLEDGE', etc.)
12
12
  */
@@ -45,4 +45,4 @@ export interface CommitmentDefinition {
45
45
  * @returns Updated agent model requirements
46
46
  */
47
47
  applyToAgentModelRequirements(requirements: AgentModelRequirements, content: string): AgentModelRequirements;
48
- }
48
+ };
@@ -4,7 +4,7 @@ import type { TODO_any } from '../../../utils/organization/TODO_any';
4
4
  *
5
5
  * This is like "compiled" version of agent source
6
6
  */
7
- export interface AgentModelRequirements {
7
+ export type AgentModelRequirements = {
8
8
  /**
9
9
  * The system message that defines the agent's behavior and personality
10
10
  */
@@ -34,4 +34,4 @@ export interface AgentModelRequirements {
34
34
  * Each commitment can store its own data here
35
35
  */
36
36
  readonly metadata?: Record<string, TODO_any>;
37
- }
37
+ };
@@ -2,7 +2,7 @@ import type { ParsedCommitment } from './ParsedCommitment';
2
2
  /**
3
3
  * Result of parsing agent source for commitments
4
4
  */
5
- export interface AgentSourceParseResult {
5
+ export type AgentSourceParseResult = {
6
6
  /**
7
7
  * The agent name (first line)
8
8
  */
@@ -15,4 +15,4 @@ export interface AgentSourceParseResult {
15
15
  * Lines that are not commitments (for system message)
16
16
  */
17
17
  nonCommitmentLines: string[];
18
- }
18
+ };
@@ -2,7 +2,7 @@ import type { BookCommitment } from '../_base/BookCommitment';
2
2
  /**
3
3
  * Parsed commitment line from agent source
4
4
  */
5
- export interface ParsedCommitment {
5
+ export type ParsedCommitment = {
6
6
  /**
7
7
  * The commitment type (e.g., 'PERSONA', 'KNOWLEDGE')
8
8
  */
@@ -19,4 +19,4 @@ export interface ParsedCommitment {
19
19
  * Line number in the agent source (1-based)
20
20
  */
21
21
  lineNumber: number;
22
- }
22
+ };
@@ -24,3 +24,6 @@ export type AvatarProfileProps = {
24
24
  * @public exported from `@promptbook/components`
25
25
  */
26
26
  export declare function AvatarProfile(props: AvatarProfileProps): import("react/jsx-runtime").JSX.Element;
27
+ /**
28
+ * TODO: [๐Ÿ•›] Unite `AvatarProfileProps`, `ChatParticipant`, `LlmExecutionTools` + `LlmToolsMetadata`
29
+ */
@@ -1,3 +1,4 @@
1
+ import type { CSSProperties } from 'react';
1
2
  import type { string_book } from '../../book-2.0/agent-source/string_book';
2
3
  /**
3
4
  * Props of `BookEditor`
@@ -9,6 +10,10 @@ export type BookEditorProps = {
9
10
  * Additional CSS classes to apply to the editor container.
10
11
  */
11
12
  readonly className?: string;
13
+ /**
14
+ * Optional CSS style which will be added to root <div/> element
15
+ */
16
+ readonly style?: CSSProperties;
12
17
  /**
13
18
  * CSS className for a font (e.g. from next/font) to style the editor text.
14
19
  * If omitted, defaults to system serif fonts.
@@ -1,7 +1,4 @@
1
- import type { string_color } from '../../../types/typeAliases';
2
- import type { string_name } from '../../../types/typeAliases';
3
- import type { string_person_fullname } from '../../../types/typeAliases';
4
- import type { string_url_image } from '../../../types/typeAliases';
1
+ import type { string_color, string_name, string_person_fullname, string_url_image } from '../../../types/typeAliases';
5
2
  import { Color } from '../../../utils/color/Color';
6
3
  /**
7
4
  * A participant in the chat
@@ -30,3 +27,6 @@ export type ChatParticipant = {
30
27
  */
31
28
  color: string_color | Color;
32
29
  };
30
+ /**
31
+ * TODO: [๐Ÿ•›] Unite `AvatarProfileProps`, `ChatParticipant`, `LlmExecutionTools` + `LlmToolsMetadata`
32
+ */
@@ -1,13 +1,9 @@
1
1
  import type { Promisable } from 'type-fest';
2
2
  import type { ChatParticipant } from '../book-components/Chat/types/ChatParticipant';
3
3
  import type { Prompt } from '../types/Prompt';
4
- import type { string_markdown } from '../types/typeAliases';
5
- import type { string_markdown_text } from '../types/typeAliases';
6
- import type { string_title } from '../types/typeAliases';
4
+ import type { string_markdown, string_markdown_text, string_title } from '../types/typeAliases';
7
5
  import type { AvailableModel } from './AvailableModel';
8
- import type { ChatPromptResult } from './PromptResult';
9
- import type { CompletionPromptResult } from './PromptResult';
10
- import type { EmbeddingPromptResult } from './PromptResult';
6
+ import type { ChatPromptResult, CompletionPromptResult, EmbeddingPromptResult } from './PromptResult';
11
7
  /**
12
8
  * Container for all the tools needed to execute prompts to large language models like GPT-4
13
9
  * On its interface it exposes common methods for prompt execution.
@@ -60,6 +56,7 @@ export type LlmExecutionTools = {
60
56
  callEmbeddingModel?(prompt: Prompt): Promise<EmbeddingPromptResult>;
61
57
  };
62
58
  /**
59
+ * TODO: [๐Ÿ•›] Extend this from sth class
63
60
  * TODO: [๐Ÿš] Implement destroyable pattern to free resources
64
61
  * TODO: [๐Ÿณ] Add `callTranslationModel`
65
62
  * TODO: [๐Ÿง ] Emulation of one type of model with another one - emuate chat with completion; emulate translation with chat
@@ -5,7 +5,7 @@ import type { string_postprocessing_function_name } from '../../types/typeAliase
5
5
  /**
6
6
  * Options for validating a prompt result
7
7
  */
8
- export interface ValidatePromptResultOptions {
8
+ export type ValidatePromptResultOptions = {
9
9
  /**
10
10
  * The result string to validate
11
11
  */
@@ -23,11 +23,11 @@ export interface ValidatePromptResultOptions {
23
23
  * Note: This is for validation purposes only - postprocessing should be done before calling this function
24
24
  */
25
25
  postprocessingFunctionNames?: ReadonlyArray<string_postprocessing_function_name>;
26
- }
26
+ };
27
27
  /**
28
28
  * Result of prompt result validation
29
29
  */
30
- export interface ValidatePromptResultResult {
30
+ export type ValidatePromptResultResult = {
31
31
  /**
32
32
  * Whether the result is valid (passes all expectations and format checks)
33
33
  */
@@ -40,7 +40,7 @@ export interface ValidatePromptResultResult {
40
40
  * Error that occurred during validation, if any
41
41
  */
42
42
  error?: ExpectError;
43
- }
43
+ };
44
44
  /**
45
45
  * Validates a prompt result against expectations and format requirements.
46
46
  * This function provides a common abstraction for result validation that can be used
@@ -76,6 +76,6 @@ export declare function getLlmProviderProfile(providerKey: keyof typeof LLM_PROV
76
76
  export declare function createCustomLlmProfile(baseProfile: ChatParticipant, overrides: Partial<ChatParticipant>): ChatParticipant;
77
77
  /**
78
78
  * TODO: Refactor this - each profile must be alongside the provider definition
79
- * TODO: Unite `AvatarProfileProps` and `ChatParticipant`
79
+ * TODO: [๐Ÿ•›] Unite `AvatarProfileProps`, `ChatParticipant`, `LlmExecutionTools` + `LlmToolsMetadata`
80
80
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
81
81
  */
@@ -1,7 +1,5 @@
1
- import { MODEL_ORDERS } from '../../../constants';
2
- import { MODEL_TRUST_LEVELS } from '../../../constants';
3
- import type { string_name } from '../../../types/typeAliases';
4
- import type { string_title } from '../../../types/typeAliases';
1
+ import { MODEL_ORDERS, MODEL_TRUST_LEVELS } from '../../../constants';
2
+ import type { string_name, string_title } from '../../../types/typeAliases';
5
3
  import type { Registered } from '../../../utils/$Register';
6
4
  import type { string_SCREAMING_CASE } from '../../../utils/normalization/normalizeTo_SCREAMING_CASE';
7
5
  import type { LlmToolsConfiguration } from './LlmToolsConfiguration';
@@ -52,6 +50,7 @@ export type LlmToolsMetadata = Registered & {
52
50
  createConfigurationFromEnv(env: Record<string_name, string>): LlmToolsConfiguration[number] | null;
53
51
  };
54
52
  /**
53
+ * TODO: [๐Ÿ•›] Extend this
55
54
  * TODO: Add configuration schema and maybe some documentation link
56
55
  * TODO: Maybe constrain LlmToolsConfiguration[number] by generic to ensure that `createConfigurationFromEnv` and `getBoilerplateConfiguration` always create same `packageName` and `className`
57
56
  * TODO: [ยฎ] DRY Register logic
@@ -1,5 +1,4 @@
1
- import type { string_color } from '../../types/typeAliases';
2
- import type { string_url_image } from '../../types/typeAliases';
1
+ import type { string_color, string_url_image } from '../../types/typeAliases';
3
2
  import type { WithTake } from '../take/interfaces/ITakeChain';
4
3
  import { CSS_COLORS } from './css-colors';
5
4
  /**
@@ -6,7 +6,7 @@ import type { Takeable } from './Takeable';
6
6
  * @deprecated [๐Ÿคก] Use some better functional library instead of `TakeChain`
7
7
  */
8
8
  export type WithTake<TValue extends Takeable> = TValue & ITakeChain<TValue>;
9
- export interface ITakeChain<TValue extends Takeable> {
9
+ export type ITakeChain<TValue extends Takeable> = {
10
10
  readonly value: TValue;
11
11
  then<TResultValue extends Takeable>(callback: (value: TValue) => TResultValue): WithTake<TResultValue>;
12
- }
12
+ };
@@ -1,7 +1,7 @@
1
1
  import type { string_filename } from '../../../types/typeAliases';
2
2
  import type { really_unknown } from '../../organization/really_unknown';
3
3
  /**
4
- * Tests if given string is valid URL.
4
+ * Tests if given string is valid file path.
5
5
  *
6
6
  * Note: This does not check if the file exists only if the path is valid
7
7
  * @public exported from `@promptbook/utils`
@@ -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-65`).
18
+ * It follows semantic versioning (e.g., `0.100.1`).
19
19
  *
20
20
  * @generated
21
21
  */
@@ -9,12 +9,12 @@ import type { string_pipeline_url } from '../types/typeAliases';
9
9
  /**
10
10
  * Options for wizard methods
11
11
  */
12
- interface WizardOptions {
12
+ type WizardOptions = {
13
13
  /**
14
14
  * Whether to enable verbose logging
15
15
  */
16
16
  isVerbose?: boolean;
17
- }
17
+ };
18
18
  /**
19
19
  * Wizard for simple usage of the Promptbook
20
20
  * Look at `wizard` for more details
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptbook/node",
3
- "version": "0.100.0",
3
+ "version": "0.100.2",
4
4
  "description": "Promptbook: Run AI apps in plain human language across multiple models and platforms",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -93,7 +93,7 @@
93
93
  "module": "./esm/index.es.js",
94
94
  "typings": "./esm/typings/src/_packages/node.index.d.ts",
95
95
  "peerDependencies": {
96
- "@promptbook/core": "0.100.0"
96
+ "@promptbook/core": "0.100.2"
97
97
  },
98
98
  "dependencies": {
99
99
  "colors": "1.4.0",
package/umd/index.umd.js CHANGED
@@ -47,7 +47,7 @@
47
47
  * @generated
48
48
  * @see https://github.com/webgptorg/promptbook
49
49
  */
50
- const PROMPTBOOK_ENGINE_VERSION = '0.100.0';
50
+ const PROMPTBOOK_ENGINE_VERSION = '0.100.2';
51
51
  /**
52
52
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
53
53
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
@@ -1201,7 +1201,7 @@
1201
1201
  }
1202
1202
 
1203
1203
  /**
1204
- * Tests if given string is valid URL.
1204
+ * Tests if given string is valid file path.
1205
1205
  *
1206
1206
  * Note: This does not check if the file exists only if the path is valid
1207
1207
  * @public exported from `@promptbook/utils`
@@ -1213,18 +1213,25 @@
1213
1213
  if (filename.split('\n').length > 1) {
1214
1214
  return false;
1215
1215
  }
1216
- if (filename.split(' ').length >
1217
- 5 /* <- TODO: [๐Ÿง ][๐Ÿˆท] Make some better non-arbitrary way how to distinct filenames from informational texts */) {
1216
+ // Normalize slashes early so heuristics can detect path-like inputs
1217
+ const filenameSlashes = filename.replace(/\\/g, '/');
1218
+ // Reject strings that look like sentences (informational text)
1219
+ // Heuristic: contains multiple spaces and ends with a period, or contains typical sentence punctuation
1220
+ // But skip this heuristic if the string looks like a path (contains '/' or starts with a drive letter)
1221
+ if (filename.trim().length > 60 && // long enough to be a sentence
1222
+ /[.!?]/.test(filename) && // contains sentence punctuation
1223
+ filename.split(' ').length > 8 && // has many words
1224
+ !/\/|^[A-Z]:/i.test(filenameSlashes) // do NOT treat as sentence if looks like a path
1225
+ ) {
1218
1226
  return false;
1219
1227
  }
1220
- const filenameSlashes = filename.split('\\').join('/');
1221
1228
  // Absolute Unix path: /hello.txt
1222
1229
  if (/^(\/)/i.test(filenameSlashes)) {
1223
1230
  // console.log(filename, 'Absolute Unix path: /hello.txt');
1224
1231
  return true;
1225
1232
  }
1226
- // Absolute Windows path: /hello.txt
1227
- if (/^([A-Z]{1,2}:\/?)\//i.test(filenameSlashes)) {
1233
+ // Absolute Windows path: C:/ or C:\ (allow spaces and multiple dots in filename)
1234
+ if (/^[A-Z]:\/.+$/i.test(filenameSlashes)) {
1228
1235
  // console.log(filename, 'Absolute Windows path: /hello.txt');
1229
1236
  return true;
1230
1237
  }
@@ -3074,7 +3081,7 @@
3074
3081
  };
3075
3082
  /**
3076
3083
  * TODO: Refactor this - each profile must be alongside the provider definition
3077
- * TODO: Unite `AvatarProfileProps` and `ChatParticipant`
3084
+ * TODO: [๐Ÿ•›] Unite `AvatarProfileProps`, `ChatParticipant`, `LlmExecutionTools` + `LlmToolsMetadata`
3078
3085
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
3079
3086
  */
3080
3087
 
@@ -5816,9 +5823,15 @@
5816
5823
  }
5817
5824
  if (isValidUrl(knowledgeSourceContent)) {
5818
5825
  const url = knowledgeSourceContent;
5826
+ if (isVerbose) {
5827
+ console.info(`๐Ÿ“„ [1] "${name}" is available at "${url}"`);
5828
+ }
5819
5829
  const response = await fetch(url); // <- TODO: [๐Ÿง ] Scraping and fetch proxy
5820
5830
  const mimeType = ((_a = response.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.split(';')[0]) || 'text/html';
5821
5831
  if (tools.fs === undefined || !url.endsWith('.pdf' /* <- TODO: [๐Ÿ’ต] */)) {
5832
+ if (isVerbose) {
5833
+ console.info(`๐Ÿ“„ [2] "${name}" tools.fs is not available or URL is not a PDF.`);
5834
+ }
5822
5835
  return {
5823
5836
  source: name,
5824
5837
  filename: null,
@@ -5854,13 +5867,17 @@
5854
5867
  await tools.fs.mkdir(path.dirname(path.join(rootDirname, filepath)), { recursive: true });
5855
5868
  }
5856
5869
  catch (error) {
5870
+ if (isVerbose) {
5871
+ console.info(`๐Ÿ“„ [3] "${name}" error creating cache directory`);
5872
+ }
5857
5873
  // Note: If we can't create cache directory, we'll handle it when trying to write the file
5858
5874
  // This handles read-only filesystems, permission issues, and missing parent directories
5859
- if (error instanceof Error && (error.message.includes('EROFS') ||
5860
- error.message.includes('read-only') ||
5861
- error.message.includes('EACCES') ||
5862
- error.message.includes('EPERM') ||
5863
- error.message.includes('ENOENT'))) ;
5875
+ if (error instanceof Error &&
5876
+ (error.message.includes('EROFS') ||
5877
+ error.message.includes('read-only') ||
5878
+ error.message.includes('EACCES') ||
5879
+ error.message.includes('EPERM') ||
5880
+ error.message.includes('ENOENT'))) ;
5864
5881
  else {
5865
5882
  // Re-throw other unexpected errors
5866
5883
  throw error;
@@ -5875,13 +5892,17 @@
5875
5892
  await tools.fs.writeFile(path.join(rootDirname, filepath), fileContent);
5876
5893
  }
5877
5894
  catch (error) {
5895
+ if (isVerbose) {
5896
+ console.info(`๐Ÿ“„ [4] "${name}" error writing cache file`);
5897
+ }
5878
5898
  // Note: If we can't write to cache, we'll process the file directly from memory
5879
5899
  // This handles read-only filesystems like Vercel
5880
- if (error instanceof Error && (error.message.includes('EROFS') ||
5881
- error.message.includes('read-only') ||
5882
- error.message.includes('EACCES') ||
5883
- error.message.includes('EPERM') ||
5884
- error.message.includes('ENOENT'))) {
5900
+ if (error instanceof Error &&
5901
+ (error.message.includes('EROFS') ||
5902
+ error.message.includes('read-only') ||
5903
+ error.message.includes('EACCES') ||
5904
+ error.message.includes('EPERM') ||
5905
+ error.message.includes('ENOENT'))) {
5885
5906
  // Return a handler that works directly with the downloaded content
5886
5907
  return {
5887
5908
  source: name,
@@ -5903,6 +5924,9 @@
5903
5924
  }
5904
5925
  // TODO: [๐Ÿ’ต] Check the file security
5905
5926
  // TODO: [๐Ÿงน][๐Ÿง ] Delete the file after the scraping is done
5927
+ if (isVerbose) {
5928
+ console.info(`๐Ÿ“„ [5] "${name}" cached at "${path.join(rootDirname, filepath)}"`);
5929
+ }
5906
5930
  return makeKnowledgeSourceHandler({ name, knowledgeSourceContent: filepath }, tools, {
5907
5931
  ...options,
5908
5932
  rootDirname,
@@ -5917,7 +5941,12 @@
5917
5941
  throw new EnvironmentMismatchError('Can not import file knowledge in non-file pipeline');
5918
5942
  // <- TODO: [๐Ÿง ] What is the best error type here`
5919
5943
  }
5920
- const filename = path.join(rootDirname, knowledgeSourceContent).split('\\').join('/');
5944
+ const filename = path.isAbsolute(knowledgeSourceContent)
5945
+ ? knowledgeSourceContent
5946
+ : path.join(rootDirname, knowledgeSourceContent).split('\\').join('/');
5947
+ if (isVerbose) {
5948
+ console.info(`๐Ÿ“„ [6] "${name}" is a valid file "${filename}"`);
5949
+ }
5921
5950
  const fileExtension = getFileExtension(filename);
5922
5951
  const mimeType = extensionToMimeType(fileExtension || '');
5923
5952
  if (!(await isFileExisting(filename, tools.fs))) {
@@ -5959,6 +5988,12 @@
5959
5988
  };
5960
5989
  }
5961
5990
  else {
5991
+ if (isVerbose) {
5992
+ console.info(`๐Ÿ“„ [7] "${name}" is just a explicit string text with a knowledge source`);
5993
+ console.info('---');
5994
+ console.info(knowledgeSourceContent);
5995
+ console.info('---');
5996
+ }
5962
5997
  return {
5963
5998
  source: name,
5964
5999
  filename: null,