@promptbook/cli 0.103.0-47 → 0.103.0-49

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.
Files changed (133) hide show
  1. package/apps/agents-server/README.md +1 -1
  2. package/apps/agents-server/TODO.txt +6 -5
  3. package/apps/agents-server/config.ts +130 -0
  4. package/apps/agents-server/next.config.ts +1 -1
  5. package/apps/agents-server/public/fonts/OpenMoji-black-glyf.woff2 +0 -0
  6. package/apps/agents-server/public/fonts/download-font.js +22 -0
  7. package/apps/agents-server/src/app/[agentName]/[...rest]/page.tsx +6 -0
  8. package/apps/agents-server/src/app/[agentName]/page.tsx +1 -0
  9. package/apps/agents-server/src/app/actions.ts +37 -2
  10. package/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +68 -0
  11. package/apps/agents-server/src/app/agents/[agentName]/AgentQrCode.tsx +55 -0
  12. package/apps/agents-server/src/app/agents/[agentName]/AgentUrlCopy.tsx +4 -5
  13. package/apps/agents-server/src/app/agents/[agentName]/CopyField.tsx +44 -0
  14. package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +8 -8
  15. package/apps/agents-server/src/app/agents/[agentName]/api/chat/route.ts +100 -18
  16. package/apps/agents-server/src/app/agents/[agentName]/api/feedback/route.ts +54 -0
  17. package/apps/agents-server/src/app/agents/[agentName]/api/modelRequirements/route.ts +6 -6
  18. package/apps/agents-server/src/app/agents/[agentName]/api/modelRequirements/systemMessage/route.ts +3 -3
  19. package/apps/agents-server/src/app/agents/[agentName]/api/profile/route.ts +6 -7
  20. package/apps/agents-server/src/app/agents/[agentName]/book/BookEditorWrapper.tsx +6 -7
  21. package/apps/agents-server/src/app/agents/[agentName]/book/page.tsx +9 -2
  22. package/apps/agents-server/src/app/agents/[agentName]/book+chat/AgentBookAndChat.tsx +23 -0
  23. package/apps/agents-server/src/app/agents/[agentName]/book+chat/{AgentBookAndChatComponent.tsx → AgentBookAndChatComponent.tsx.todo} +6 -8
  24. package/apps/agents-server/src/app/agents/[agentName]/book+chat/page.tsx +28 -17
  25. package/apps/agents-server/src/app/agents/[agentName]/book+chat/page.tsx.todo +21 -0
  26. package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatWrapper.tsx +34 -4
  27. package/apps/agents-server/src/app/agents/[agentName]/chat/page.tsx +4 -1
  28. package/apps/agents-server/src/app/agents/[agentName]/generateAgentMetadata.ts +42 -0
  29. package/apps/agents-server/src/app/agents/[agentName]/page.tsx +111 -108
  30. package/apps/agents-server/src/app/agents/page.tsx +1 -1
  31. package/apps/agents-server/src/app/api/auth/login/route.ts +65 -0
  32. package/apps/agents-server/src/app/api/auth/logout/route.ts +7 -0
  33. package/apps/agents-server/src/app/api/metadata/route.ts +116 -0
  34. package/apps/agents-server/src/app/api/upload/route.ts +7 -7
  35. package/apps/agents-server/src/app/api/users/[username]/route.ts +75 -0
  36. package/apps/agents-server/src/app/api/users/route.ts +71 -0
  37. package/apps/agents-server/src/app/globals.css +35 -1
  38. package/apps/agents-server/src/app/layout.tsx +43 -23
  39. package/apps/agents-server/src/app/metadata/MetadataClient.tsx +271 -0
  40. package/apps/agents-server/src/app/metadata/page.tsx +13 -0
  41. package/apps/agents-server/src/app/not-found.tsx +5 -0
  42. package/apps/agents-server/src/app/page.tsx +84 -46
  43. package/apps/agents-server/src/components/Auth/AuthControls.tsx +123 -0
  44. package/apps/agents-server/src/components/ErrorPage/ErrorPage.tsx +33 -0
  45. package/apps/agents-server/src/components/ForbiddenPage/ForbiddenPage.tsx +15 -0
  46. package/apps/agents-server/src/components/Header/Header.tsx +146 -0
  47. package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +27 -0
  48. package/apps/agents-server/src/components/LoginDialog/LoginDialog.tsx +40 -0
  49. package/apps/agents-server/src/components/LoginForm/LoginForm.tsx +109 -0
  50. package/apps/agents-server/src/components/NotFoundPage/NotFoundPage.tsx +17 -0
  51. package/apps/agents-server/src/components/UsersList/UsersList.tsx +190 -0
  52. package/apps/agents-server/src/components/VercelDeploymentCard/VercelDeploymentCard.tsx +60 -0
  53. package/apps/agents-server/src/database/$getTableName.ts +18 -0
  54. package/apps/agents-server/src/database/$provideSupabase.ts +29 -0
  55. package/apps/agents-server/src/{supabase/getSupabaseForBrowser.ts → database/$provideSupabaseForBrowser.ts} +9 -5
  56. package/apps/agents-server/src/{supabase/getSupabaseForServer.ts → database/$provideSupabaseForServer.ts} +7 -7
  57. package/apps/agents-server/src/{supabase/getSupabaseForWorker.ts → database/$provideSupabaseForWorker.ts} +5 -4
  58. package/apps/agents-server/src/database/getMetadata.ts +31 -0
  59. package/apps/agents-server/src/database/metadataDefaults.ts +32 -0
  60. package/apps/agents-server/src/database/schema.sql +179 -0
  61. package/apps/agents-server/src/database/schema.ts +251 -0
  62. package/apps/agents-server/src/middleware.ts +162 -0
  63. package/apps/agents-server/src/tools/$provideAgentCollectionForServer.ts +14 -10
  64. package/apps/agents-server/src/tools/$provideCdnForServer.ts +1 -1
  65. package/apps/agents-server/src/tools/$provideExecutionToolsForServer.ts +11 -13
  66. package/apps/agents-server/src/tools/$provideOpenAiAssistantExecutionToolsForServer.ts +7 -7
  67. package/apps/agents-server/src/tools/$provideServer.ts +39 -0
  68. package/apps/agents-server/src/utils/auth.ts +33 -0
  69. package/apps/agents-server/src/utils/cdn/utils/getUserFileCdnKey.ts +2 -1
  70. package/apps/agents-server/src/utils/cdn/utils/nameToSubfolderPath.ts +1 -1
  71. package/apps/agents-server/src/utils/getCurrentUser.ts +32 -0
  72. package/apps/agents-server/src/utils/isIpAllowed.ts +101 -0
  73. package/apps/agents-server/src/utils/isUserAdmin.ts +31 -0
  74. package/apps/agents-server/src/utils/session.ts +50 -0
  75. package/apps/agents-server/tailwind.config.ts +2 -0
  76. package/esm/index.es.js +310 -49
  77. package/esm/index.es.js.map +1 -1
  78. package/esm/typings/servers.d.ts +1 -0
  79. package/esm/typings/src/_packages/core.index.d.ts +6 -0
  80. package/esm/typings/src/_packages/types.index.d.ts +4 -0
  81. package/esm/typings/src/_packages/utils.index.d.ts +2 -0
  82. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +17 -3
  83. package/esm/typings/src/book-2.0/agent-source/AgentSourceParseResult.d.ts +2 -1
  84. package/esm/typings/src/book-2.0/agent-source/computeAgentHash.d.ts +8 -0
  85. package/esm/typings/src/book-2.0/agent-source/computeAgentHash.test.d.ts +1 -0
  86. package/esm/typings/src/book-2.0/agent-source/createDefaultAgentName.d.ts +8 -0
  87. package/esm/typings/src/book-2.0/agent-source/normalizeAgentName.d.ts +9 -0
  88. package/esm/typings/src/book-2.0/agent-source/normalizeAgentName.test.d.ts +1 -0
  89. package/esm/typings/src/book-2.0/agent-source/parseAgentSourceWithCommitments.d.ts +1 -1
  90. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +14 -8
  91. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabaseOptions.d.ts +10 -0
  92. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +57 -32
  93. package/esm/typings/src/commitments/MESSAGE/InitialMessageCommitmentDefinition.d.ts +28 -0
  94. package/esm/typings/src/commitments/index.d.ts +2 -1
  95. package/esm/typings/src/config.d.ts +1 -0
  96. package/esm/typings/src/errors/DatabaseError.d.ts +2 -2
  97. package/esm/typings/src/errors/WrappedError.d.ts +2 -2
  98. package/esm/typings/src/execution/ExecutionTask.d.ts +2 -2
  99. package/esm/typings/src/execution/LlmExecutionTools.d.ts +6 -1
  100. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForWizardOrCli.d.ts +2 -2
  101. package/esm/typings/src/llm-providers/_common/utils/assertUniqueModels.d.ts +12 -0
  102. package/esm/typings/src/llm-providers/agent/Agent.d.ts +17 -4
  103. package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +10 -1
  104. package/esm/typings/src/llm-providers/agent/RemoteAgent.d.ts +6 -2
  105. package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +30 -4
  106. package/esm/typings/src/llm-providers/openai/openai-models.test.d.ts +4 -0
  107. package/esm/typings/src/remote-server/startAgentServer.d.ts +2 -2
  108. package/esm/typings/src/remote-server/startRemoteServer.d.ts +1 -2
  109. package/esm/typings/src/transpilers/openai-sdk/register.d.ts +1 -1
  110. package/esm/typings/src/types/typeAliases.d.ts +6 -0
  111. package/esm/typings/src/utils/color/Color.d.ts +7 -0
  112. package/esm/typings/src/utils/color/Color.test.d.ts +1 -0
  113. package/esm/typings/src/utils/environment/$getGlobalScope.d.ts +2 -2
  114. package/esm/typings/src/utils/misc/computeHash.d.ts +11 -0
  115. package/esm/typings/src/utils/misc/computeHash.test.d.ts +1 -0
  116. package/esm/typings/src/utils/normalization/normalize-to-kebab-case.d.ts +2 -0
  117. package/esm/typings/src/utils/normalization/normalizeTo_PascalCase.d.ts +3 -0
  118. package/esm/typings/src/utils/normalization/normalizeTo_camelCase.d.ts +2 -0
  119. package/esm/typings/src/utils/normalization/titleToName.d.ts +2 -0
  120. package/esm/typings/src/utils/organization/$sideEffect.d.ts +2 -2
  121. package/esm/typings/src/utils/organization/$side_effect.d.ts +2 -2
  122. package/esm/typings/src/utils/organization/TODO_USE.d.ts +2 -2
  123. package/esm/typings/src/utils/organization/keepUnused.d.ts +2 -2
  124. package/esm/typings/src/utils/organization/preserve.d.ts +3 -3
  125. package/esm/typings/src/utils/organization/really_any.d.ts +7 -0
  126. package/esm/typings/src/utils/serialization/asSerializable.d.ts +2 -2
  127. package/esm/typings/src/version.d.ts +1 -1
  128. package/package.json +1 -1
  129. package/umd/index.umd.js +311 -50
  130. package/umd/index.umd.js.map +1 -1
  131. package/apps/agents-server/config.ts.todo +0 -312
  132. package/apps/agents-server/src/supabase/TODO.txt +0 -1
  133. package/apps/agents-server/src/supabase/getSupabase.ts +0 -25
package/esm/index.es.js CHANGED
@@ -47,7 +47,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
47
47
  * @generated
48
48
  * @see https://github.com/webgptorg/promptbook
49
49
  */
50
- const PROMPTBOOK_ENGINE_VERSION = '0.103.0-47';
50
+ const PROMPTBOOK_ENGINE_VERSION = '0.103.0-49';
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
@@ -86,6 +86,7 @@ const REMOTE_SERVER_URLS = [
86
86
  */
87
87
  ];
88
88
  /**
89
+ * TODO: [🐱‍🚀] Auto-federated server from url in here
89
90
  * Note: [💞] Ignore a discrepancy between file name and entity name
90
91
  */
91
92
 
@@ -432,6 +433,9 @@ class Color {
432
433
  if (hex.length === 3) {
433
434
  return Color.fromHex3(hex);
434
435
  }
436
+ if (hex.length === 4) {
437
+ return Color.fromHex4(hex);
438
+ }
435
439
  if (hex.length === 6) {
436
440
  return Color.fromHex6(hex);
437
441
  }
@@ -452,6 +456,19 @@ class Color {
452
456
  const b = parseInt(hex.substr(2, 1), 16) * 16;
453
457
  return take(new Color(r, g, b));
454
458
  }
459
+ /**
460
+ * Creates a new Color instance from color in hex format with 4 digits (with alpha channel)
461
+ *
462
+ * @param color in hex for example `09df`
463
+ * @returns Color object
464
+ */
465
+ static fromHex4(hex) {
466
+ const r = parseInt(hex.substr(0, 1), 16) * 16;
467
+ const g = parseInt(hex.substr(1, 1), 16) * 16;
468
+ const b = parseInt(hex.substr(2, 1), 16) * 16;
469
+ const a = parseInt(hex.substr(3, 1), 16) * 16;
470
+ return take(new Color(r, g, b, a));
471
+ }
455
472
  /**
456
473
  * Creates a new Color instance from color in hex format with 6 color digits (without alpha channel)
457
474
  *
@@ -642,7 +659,8 @@ class Color {
642
659
  * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
643
660
  */
644
661
  static isHexColorString(value) {
645
- return typeof value === 'string' && /^#(?:[0-9a-fA-F]{3}){1,2}$/.test(value);
662
+ return (typeof value === 'string' &&
663
+ /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
646
664
  }
647
665
  /**
648
666
  * Creates new Color object
@@ -983,6 +1001,7 @@ const PROMPTBOOK_COLOR = Color.fromHex('#79EAFD');
983
1001
  ({
984
1002
  TITLE: Color.fromHex('#244EA8'),
985
1003
  LINE: Color.fromHex('#eeeeee'),
1004
+ SEPARATOR: Color.fromHex('#cccccc'),
986
1005
  COMMITMENT: Color.fromHex('#DA0F78'),
987
1006
  PARAMETER: Color.fromHex('#8e44ad'),
988
1007
  });
@@ -2385,7 +2404,7 @@ function deepClone(objectValue) {
2385
2404
  TODO: [🧠] Is there a better implementation?
2386
2405
  > const propertyNames = Object.getOwnPropertyNames(objectValue);
2387
2406
  > for (const propertyName of propertyNames) {
2388
- > const value = (objectValue as really_any)[propertyName];
2407
+ > const value = (objectValue as chococake)[propertyName];
2389
2408
  > if (value && typeof value === 'object') {
2390
2409
  > deepClone(value);
2391
2410
  > }
@@ -2938,6 +2957,8 @@ function removeDiacritics(input) {
2938
2957
  /**
2939
2958
  * Converts a given text to kebab-case format.
2940
2959
  *
2960
+ * Note: [🔂] This function is idempotent.
2961
+ *
2941
2962
  * @param text The text to be converted.
2942
2963
  * @returns The kebab-case formatted string.
2943
2964
  * @example 'hello-world'
@@ -3007,6 +3028,8 @@ function removeEmojis(text) {
3007
3028
  /**
3008
3029
  * Converts a title string into a normalized name.
3009
3030
  *
3031
+ * Note: [🔂] This function is idempotent.
3032
+ *
3010
3033
  * @param value The title string to be converted to a name.
3011
3034
  * @returns A normalized name derived from the input title.
3012
3035
  * @example 'Hello World!' -> 'hello-world'
@@ -3200,7 +3223,7 @@ class DatabaseError extends Error {
3200
3223
  }
3201
3224
  }
3202
3225
  /**
3203
- * TODO: !!!! Explain that NotFoundError (!!! and other specific errors) has priority over DatabaseError in some contexts
3226
+ * TODO: [🐱‍🚀] Explain that NotFoundError ([🐱‍🚀] and other specific errors) has priority over DatabaseError in some contexts
3204
3227
  */
3205
3228
 
3206
3229
  /**
@@ -10017,6 +10040,8 @@ const expectCommandParser = {
10017
10040
  /**
10018
10041
  * Normalizes a given text to camelCase format.
10019
10042
  *
10043
+ * Note: [🔂] This function is idempotent.
10044
+ *
10020
10045
  * @param text The text to be normalized.
10021
10046
  * @param _isFirstLetterCapital Whether the first letter should be capitalized.
10022
10047
  * @returns The camelCase formatted string.
@@ -12966,6 +12991,18 @@ function renderPromptbookMermaid(pipelineJson, options) {
12966
12991
  * TODO: [🕌] When more than 2 functionalities, split into separate functions
12967
12992
  */
12968
12993
 
12994
+ /**
12995
+ * Computes SHA-256 hash of the given object
12996
+ *
12997
+ * @public exported from `@promptbook/utils`
12998
+ */
12999
+ function computeHash(value) {
13000
+ return SHA256(hexEncoder.parse(spaceTrim(valueToString(value)))).toString( /* hex */);
13001
+ }
13002
+ /**
13003
+ * TODO: [🥬][🥬] Use this ACRY
13004
+ */
13005
+
12969
13006
  /**
12970
13007
  * Makes first letter of a string lowercase
12971
13008
  *
@@ -13025,6 +13062,9 @@ function nameToUriParts(name) {
13025
13062
  }
13026
13063
 
13027
13064
  /**
13065
+ * Normalizes a given text to PascalCase format.
13066
+ *
13067
+ * Note: [🔂] This function is idempotent.
13028
13068
  *
13029
13069
  * @param text @public exported from `@promptbook/utils`
13030
13070
  * @returns
@@ -15074,7 +15114,7 @@ function $initializeRunCommand(program) {
15074
15114
  */
15075
15115
 
15076
15116
  /**
15077
- * !!!!!
15117
+ * [🐱‍🚀]
15078
15118
  * Remote server is a proxy server that uses its execution tools internally and exposes the executor interface externally.
15079
15119
  *
15080
15120
  * You can simply use `RemoteExecutionTools` on client-side javascript and connect to your remote server.
@@ -15082,11 +15122,11 @@ function $initializeRunCommand(program) {
15082
15122
  *
15083
15123
  * @see https://github.com/webgptorg/promptbook#remote-server
15084
15124
  * @public exported from `@promptbook/remote-server`
15085
- * <- TODO: !!!! Maybe change to `@promptbook/agent-server`
15125
+ * <- TODO: [🐱‍🚀] Change to `@promptbook/agent-server`
15086
15126
  */
15087
15127
  async function startAgentServer(options) {
15088
15128
  const { port = 4440 } = options;
15089
- // TODO: !!!! [🌕]
15129
+ // TODO: [🐱‍🚀] [🌕]
15090
15130
  const agentsServerRoot = join(__dirname, '../apps/agents-server');
15091
15131
  console.trace(`!!! Starting agents server on port ${port}...`);
15092
15132
  console.log(`!!! cwd`, process.cwd());
@@ -15122,7 +15162,7 @@ function $initializeStartAgentsServerCommand(program) {
15122
15162
  startServerCommand.alias('start');
15123
15163
  startServerCommand.action(handleActionErrors(async (path, cliOptions) => {
15124
15164
  const { port: portRaw, reload: isCacheReloaded, verbose: isVerbose } = cliOptions;
15125
- // TODO: !!!! [🌕] DRY
15165
+ // TODO: [🐱‍🚀] [🌕] DRY
15126
15166
  const port = parseInt(portRaw, 10);
15127
15167
  if (isNaN(port) || port <= 0 || port > 65535) {
15128
15168
  console.error(colors.red(`Invalid port number: ${portRaw}`));
@@ -15164,11 +15204,11 @@ function $initializeStartAgentsServerCommand(program) {
15164
15204
  TODO_USE(tools);
15165
15205
  TODO_USE(collection);
15166
15206
  */
15167
- // TODO: !!!! Use
15168
- // TODO: !!!! Pass collection and tools to the server starter
15169
- // TODO: !!!! The Next app should be build during the package build step not here
15207
+ // TODO: [🐱‍🚀] Use
15208
+ // TODO: [🐱‍🚀] Pass collection and tools to the server starter
15209
+ // TODO: [🐱‍🚀] The Next app should be build during the package build step not here
15170
15210
  /*
15171
- // TODO: !!!! Run this conditionally only in production mode in dev mode use `next dev`
15211
+ // TODO: [🐱‍🚀] Run this conditionally only in production mode in dev mode use `next dev`
15172
15212
  await $execCommand({
15173
15213
  cwd: './apps/agents-server',
15174
15214
  command: `next build`,
@@ -16394,8 +16434,7 @@ function startRemoteServer(options) {
16394
16434
  };
16395
16435
  }
16396
16436
  /**
16397
- * TODO !!!! Add agent
16398
- * TODO: !!!! Allow to chat with agents directly via remote server
16437
+
16399
16438
  * TODO: [🕋] Use here `aboutPromptbookInformation`
16400
16439
  * TODO: [🌡] Add CORS and security - probably via `helmet`
16401
16440
  * TODO: Split this file into multiple functions - handler for each request
@@ -17516,17 +17555,17 @@ const OPENAI_MODELS = exportJson({
17516
17555
  },
17517
17556
  /**/
17518
17557
  /*/
17519
- {
17520
- modelTitle: 'tts-1-hd-1106',
17521
- modelName: 'tts-1-hd-1106',
17522
- },
17523
- /**/
17558
+ {
17559
+ modelTitle: 'tts-1-hd-1106',
17560
+ modelName: 'tts-1-hd-1106',
17561
+ },
17562
+ /**/
17524
17563
  /*/
17525
- {
17526
- modelTitle: 'tts-1-hd',
17527
- modelName: 'tts-1-hd',
17528
- },
17529
- /**/
17564
+ {
17565
+ modelTitle: 'tts-1-hd',
17566
+ modelName: 'tts-1-hd',
17567
+ },
17568
+ /**/
17530
17569
  /**/
17531
17570
  {
17532
17571
  modelVariant: 'CHAT',
@@ -20382,11 +20421,12 @@ class OpenAiExecutionTools extends OpenAiCompatibleExecutionTools {
20382
20421
  *
20383
20422
  * This is useful for calling OpenAI API with a single assistant, for more wide usage use `OpenAiExecutionTools`.
20384
20423
  *
20385
- * !!! Note: [🦖] There are several different things in Promptbook:
20424
+ * Note: [🦖] There are several different things in Promptbook:
20386
20425
  * - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
20387
20426
  * - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
20388
20427
  * - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
20389
20428
  * - `OpenAiAssistantExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities, recommended for usage in `Agent` or `AgentLlmExecutionTools`
20429
+ * - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server
20390
20430
  *
20391
20431
  * @public exported from `@promptbook/openai`
20392
20432
  */
@@ -20421,6 +20461,12 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
20421
20461
  * Calls OpenAI API to use a chat model.
20422
20462
  */
20423
20463
  async callChatModel(prompt) {
20464
+ return this.callChatModelStream(prompt, () => { });
20465
+ }
20466
+ /**
20467
+ * Calls OpenAI API to use a chat model with streaming.
20468
+ */
20469
+ async callChatModelStream(prompt, onProgress) {
20424
20470
  var _a, _b, _c;
20425
20471
  if (this.options.isVerbose) {
20426
20472
  console.info('💬 OpenAI callChatModel call', { prompt });
@@ -20488,21 +20534,24 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
20488
20534
  console.info('connect', stream.currentEvent);
20489
20535
  }
20490
20536
  });
20491
- /*
20492
- stream.on('messageDelta', (messageDelta) => {
20493
- if (
20494
- this.options.isVerbose &&
20495
- messageDelta &&
20496
- messageDelta.content &&
20497
- messageDelta.content[0] &&
20498
- messageDelta.content[0].type === 'text'
20499
- ) {
20500
- console.info('messageDelta', messageDelta.content[0].text?.value);
20537
+ stream.on('textDelta', (textDelta, snapshot) => {
20538
+ if (this.options.isVerbose && textDelta.value) {
20539
+ console.info('textDelta', textDelta.value);
20501
20540
  }
20502
-
20503
- // <- TODO: [🐚] Make streaming and running tasks working
20541
+ const chunk = {
20542
+ content: textDelta.value || '',
20543
+ modelName: 'assistant',
20544
+ timing: {
20545
+ start,
20546
+ complete: $getCurrentDate(),
20547
+ },
20548
+ usage: UNCERTAIN_USAGE,
20549
+ rawPromptContent,
20550
+ rawRequest,
20551
+ rawResponse: snapshot,
20552
+ };
20553
+ onProgress(chunk);
20504
20554
  });
20505
- */
20506
20555
  stream.on('messageCreated', (message) => {
20507
20556
  if (this.options.isVerbose) {
20508
20557
  console.info('messageCreated', message);
@@ -20538,7 +20587,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
20538
20587
  }
20539
20588
  return exportJson({
20540
20589
  name: 'promptResult',
20541
- message: `Result of \`OpenAiAssistantExecutionTools.callChatModel\``,
20590
+ message: `Result of \`OpenAiAssistantExecutionTools.callChatModelStream\``,
20542
20591
  order: [],
20543
20592
  value: {
20544
20593
  content: resultContent,
@@ -20557,15 +20606,19 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
20557
20606
  },
20558
20607
  });
20559
20608
  }
20560
- async playground() {
20609
+ /*
20610
+ public async playground() {
20561
20611
  const client = await this.getClient();
20612
+
20562
20613
  // List all assistants
20563
20614
  const assistants = await client.beta.assistants.list();
20564
20615
  console.log('!!! Assistants:', assistants);
20616
+
20565
20617
  // Get details of a specific assistant
20566
20618
  const assistantId = 'asst_MO8fhZf4dGloCfXSHeLcIik0';
20567
20619
  const assistant = await client.beta.assistants.retrieve(assistantId);
20568
20620
  console.log('!!! Assistant Details:', assistant);
20621
+
20569
20622
  // Update an assistant
20570
20623
  const updatedAssistant = await client.beta.assistants.update(assistantId, {
20571
20624
  name: assistant.name + '(M)',
@@ -20575,8 +20628,19 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
20575
20628
  },
20576
20629
  });
20577
20630
  console.log('!!! Updated Assistant:', updatedAssistant);
20631
+
20578
20632
  await forEver();
20579
20633
  }
20634
+ */
20635
+ /**
20636
+ * Get an existing assistant tool wrapper
20637
+ */
20638
+ getAssistant(assistantId) {
20639
+ return new OpenAiAssistantExecutionTools({
20640
+ ...this.options,
20641
+ assistantId,
20642
+ });
20643
+ }
20580
20644
  async createNewAssistant(options) {
20581
20645
  if (!this.isCreatingNewAssistantsAllowed) {
20582
20646
  throw new NotAllowed(`Creating new assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
@@ -20662,9 +20726,98 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
20662
20726
  }
20663
20727
  const assistant = await client.beta.assistants.create(assistantConfig);
20664
20728
  console.log(`✅ Assistant created: ${assistant.id}`);
20665
- // TODO: !!!! Try listing existing assistants
20666
- // TODO: !!!! Try marking existing assistants by DISCRIMINANT
20667
- // TODO: !!!! Allow to update and reconnect to existing assistants
20729
+ // TODO: [🐱‍🚀] Try listing existing assistants
20730
+ // TODO: [🐱‍🚀] Try marking existing assistants by DISCRIMINANT
20731
+ // TODO: [🐱‍🚀] Allow to update and reconnect to existing assistants
20732
+ return new OpenAiAssistantExecutionTools({
20733
+ ...this.options,
20734
+ isCreatingNewAssistantsAllowed: false,
20735
+ assistantId: assistant.id,
20736
+ });
20737
+ }
20738
+ async updateAssistant(options) {
20739
+ if (!this.isCreatingNewAssistantsAllowed) {
20740
+ throw new NotAllowed(`Updating assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
20741
+ }
20742
+ const { assistantId, name, instructions, knowledgeSources } = options;
20743
+ const client = await this.getClient();
20744
+ let vectorStoreId;
20745
+ // If knowledge sources are provided, create a vector store with them
20746
+ // TODO: [🧠] Reuse vector store creation logic from createNewAssistant
20747
+ if (knowledgeSources && knowledgeSources.length > 0) {
20748
+ if (this.options.isVerbose) {
20749
+ console.info(`📚 Creating vector store for update with ${knowledgeSources.length} knowledge sources...`);
20750
+ }
20751
+ // Create a vector store
20752
+ const vectorStore = await client.beta.vectorStores.create({
20753
+ name: `${name} Knowledge Base`,
20754
+ });
20755
+ vectorStoreId = vectorStore.id;
20756
+ if (this.options.isVerbose) {
20757
+ console.info(`✅ Vector store created: ${vectorStoreId}`);
20758
+ }
20759
+ // Upload files from knowledge sources to the vector store
20760
+ const fileStreams = [];
20761
+ for (const source of knowledgeSources) {
20762
+ try {
20763
+ // Check if it's a URL
20764
+ if (source.startsWith('http://') || source.startsWith('https://')) {
20765
+ // Download the file
20766
+ const response = await fetch(source);
20767
+ if (!response.ok) {
20768
+ console.error(`Failed to download ${source}: ${response.statusText}`);
20769
+ continue;
20770
+ }
20771
+ const buffer = await response.arrayBuffer();
20772
+ const filename = source.split('/').pop() || 'downloaded-file';
20773
+ const blob = new Blob([buffer]);
20774
+ const file = new File([blob], filename);
20775
+ fileStreams.push(file);
20776
+ }
20777
+ else {
20778
+ // Assume it's a local file path
20779
+ // Note: This will work in Node.js environment
20780
+ // For browser environments, this would need different handling
20781
+ const fs = await import('fs');
20782
+ const fileStream = fs.createReadStream(source);
20783
+ fileStreams.push(fileStream);
20784
+ }
20785
+ }
20786
+ catch (error) {
20787
+ console.error(`Error processing knowledge source ${source}:`, error);
20788
+ }
20789
+ }
20790
+ // Batch upload files to the vector store
20791
+ if (fileStreams.length > 0) {
20792
+ try {
20793
+ await client.beta.vectorStores.fileBatches.uploadAndPoll(vectorStoreId, {
20794
+ files: fileStreams,
20795
+ });
20796
+ if (this.options.isVerbose) {
20797
+ console.info(`✅ Uploaded ${fileStreams.length} files to vector store`);
20798
+ }
20799
+ }
20800
+ catch (error) {
20801
+ console.error('Error uploading files to vector store:', error);
20802
+ }
20803
+ }
20804
+ }
20805
+ const assistantUpdate = {
20806
+ name,
20807
+ instructions,
20808
+ tools: [/* TODO: [🧠] Maybe add { type: 'code_interpreter' }, */ { type: 'file_search' }],
20809
+ };
20810
+ if (vectorStoreId) {
20811
+ assistantUpdate.tool_resources = {
20812
+ file_search: {
20813
+ vector_store_ids: [vectorStoreId],
20814
+ },
20815
+ };
20816
+ }
20817
+ const assistant = await client.beta.assistants.update(assistantId, assistantUpdate);
20818
+ if (this.options.isVerbose) {
20819
+ console.log(`✅ Assistant updated: ${assistant.id}`);
20820
+ }
20668
20821
  return new OpenAiAssistantExecutionTools({
20669
20822
  ...this.options,
20670
20823
  isCreatingNewAssistantsAllowed: false,
@@ -22897,6 +23050,60 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
22897
23050
  * Note: [💞] Ignore a discrepancy between file name and entity name
22898
23051
  */
22899
23052
 
23053
+ /**
23054
+ * INITIAL MESSAGE commitment definition
23055
+ *
23056
+ * The INITIAL MESSAGE commitment defines the first message that the user sees when opening the chat.
23057
+ * It is used to greet the user and set the tone of the conversation.
23058
+ *
23059
+ * Example usage in agent source:
23060
+ *
23061
+ * ```book
23062
+ * INITIAL MESSAGE Hello! I am ready to help you with your tasks.
23063
+ * ```
23064
+ *
23065
+ * @private [🪔] Maybe export the commitments through some package
23066
+ */
23067
+ class InitialMessageCommitmentDefinition extends BaseCommitmentDefinition {
23068
+ constructor() {
23069
+ super('INITIAL MESSAGE');
23070
+ }
23071
+ /**
23072
+ * Short one-line description of INITIAL MESSAGE.
23073
+ */
23074
+ get description() {
23075
+ return 'Defines the **initial message** shown to the user when the chat starts.';
23076
+ }
23077
+ /**
23078
+ * Markdown documentation for INITIAL MESSAGE commitment.
23079
+ */
23080
+ get documentation() {
23081
+ return spaceTrim$1(`
23082
+ # ${this.type}
23083
+
23084
+ Defines the first message that the user sees when opening the chat. This message is purely for display purposes in the UI and does not inherently become part of the LLM's system prompt context (unless also included via other means).
23085
+
23086
+ ## Key aspects
23087
+
23088
+ - Used to greet the user.
23089
+ - Sets the tone of the conversation.
23090
+ - Displayed immediately when the chat interface loads.
23091
+
23092
+ ## Examples
23093
+
23094
+ \`\`\`book
23095
+ Support Agent
23096
+
23097
+ PERSONA You are a helpful support agent.
23098
+ INITIAL MESSAGE Hi there! How can I assist you today?
23099
+ \`\`\`
23100
+ `);
23101
+ }
23102
+ applyToAgentModelRequirements(requirements, content) {
23103
+ return requirements;
23104
+ }
23105
+ }
23106
+
22900
23107
  /**
22901
23108
  * MESSAGE commitment definition
22902
23109
  *
@@ -23601,6 +23808,7 @@ class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
23601
23808
  // Keep everything after the PERSONA section
23602
23809
  cleanedMessage = lines.slice(personaEndIndex).join('\n').trim();
23603
23810
  }
23811
+ // TODO: [🕛] There should be `agentFullname` not `agentName`
23604
23812
  // Create new system message with persona at the beginning
23605
23813
  // Format: "You are {agentName}\n{personaContent}"
23606
23814
  // The # PERSONA comment will be removed later by removeCommentsFromSystemMessage
@@ -24057,6 +24265,7 @@ const COMMITMENT_REGISTRY = [
24057
24265
  new NoteCommitmentDefinition('NONCE'),
24058
24266
  new GoalCommitmentDefinition('GOAL'),
24059
24267
  new GoalCommitmentDefinition('GOALS'),
24268
+ new InitialMessageCommitmentDefinition(),
24060
24269
  new MessageCommitmentDefinition('MESSAGE'),
24061
24270
  new MessageCommitmentDefinition('MESSAGES'),
24062
24271
  new ScenarioCommitmentDefinition('SCENARIO'),
@@ -24429,6 +24638,36 @@ function generatePlaceholderAgentProfileImageUrl(agentName) {
24429
24638
  * TODO: [🤹] Figure out best placeholder image generator https://i.pravatar.cc/1000?u=568
24430
24639
  */
24431
24640
 
24641
+ /**
24642
+ * Computes SHA-256 hash of the agent source
24643
+ *
24644
+ * @public exported from `@promptbook/core`
24645
+ */
24646
+ function computeAgentHash(agentSource) {
24647
+ return computeHash(agentSource);
24648
+ }
24649
+
24650
+ /**
24651
+ * Normalizes agent name from arbitrary string to valid agent name
24652
+ *
24653
+ * Note: [🔂] This function is idempotent.
24654
+ *
24655
+ * @public exported from `@promptbook/core`
24656
+ */
24657
+ function normalizeAgentName(rawAgentName) {
24658
+ return titleToName(spaceTrim(rawAgentName));
24659
+ }
24660
+
24661
+ /**
24662
+ * Creates temporary default agent name based on agent source hash
24663
+ *
24664
+ * @public exported from `@promptbook/core`
24665
+ */
24666
+ function createDefaultAgentName(agentSource) {
24667
+ const agentHash = computeAgentHash(agentSource);
24668
+ return normalizeAgentName(`Agent ${agentHash.substring(0, 6)}`);
24669
+ }
24670
+
24432
24671
  /**
24433
24672
  * Parses basic information from agent source
24434
24673
  *
@@ -24454,13 +24693,31 @@ function parseAgentSource(agentSource) {
24454
24693
  }
24455
24694
  personaDescription += commitment.content;
24456
24695
  }
24696
+ let initialMessage = null;
24697
+ for (const commitment of parseResult.commitments) {
24698
+ if (commitment.type !== 'INITIAL MESSAGE') {
24699
+ continue;
24700
+ }
24701
+ // Note: Initial message override logic - later overrides earlier
24702
+ // Or should it append? Usually initial message is just one block.
24703
+ // Let's stick to "later overrides earlier" for simplicity, or just take the last one.
24704
+ initialMessage = commitment.content;
24705
+ }
24457
24706
  const meta = {};
24707
+ const links = [];
24458
24708
  for (const commitment of parseResult.commitments) {
24709
+ if (commitment.type === 'META LINK') {
24710
+ links.push(spaceTrim(commitment.content));
24711
+ continue;
24712
+ }
24459
24713
  if (commitment.type !== 'META') {
24460
24714
  continue;
24461
24715
  }
24462
24716
  // Parse META commitments - format is "META TYPE content"
24463
24717
  const metaTypeRaw = commitment.content.split(' ')[0] || 'NONE';
24718
+ if (metaTypeRaw === 'LINK') {
24719
+ links.push(spaceTrim(commitment.content.substring(metaTypeRaw.length)));
24720
+ }
24464
24721
  const metaType = normalizeTo_camelCase(metaTypeRaw);
24465
24722
  meta[metaType] = spaceTrim(commitment.content.substring(metaTypeRaw.length));
24466
24723
  }
@@ -24471,10 +24728,14 @@ function parseAgentSource(agentSource) {
24471
24728
  // Parse parameters using unified approach - both @Parameter and {parameter} notations
24472
24729
  // are treated as the same syntax feature with unified representation
24473
24730
  const parameters = parseParameters(agentSource);
24731
+ const agentHash = computeAgentHash(agentSource);
24474
24732
  return {
24475
- agentName: parseResult.agentName,
24733
+ agentName: normalizeAgentName(parseResult.agentName || createDefaultAgentName(agentSource)),
24734
+ agentHash,
24476
24735
  personaDescription,
24736
+ initialMessage,
24477
24737
  meta,
24738
+ links,
24478
24739
  parameters,
24479
24740
  };
24480
24741
  }
@@ -24692,7 +24953,7 @@ const OpenAiSdkTranspiler = {
24692
24953
  });
24693
24954
 
24694
24955
  const answer = response.choices[0].message.content;
24695
- console.log('\\n🧠 ${agentName}:', answer, '\\n');
24956
+ console.log('\\n🧠 ${agentName /* <- TODO: [🕛] There should be `agentFullname` not `agentName` */}:', answer, '\\n');
24696
24957
 
24697
24958
  chatHistory.push({ role: 'assistant', content: answer });
24698
24959
  promptUser();
@@ -24711,7 +24972,7 @@ const OpenAiSdkTranspiler = {
24711
24972
 
24712
24973
  (async () => {
24713
24974
  await setupKnowledge();
24714
- console.log("🤖 Chat with ${agentName} (type 'exit' to quit)\\n");
24975
+ console.log("🤖 Chat with ${agentName /* <- TODO: [🕛] There should be `agentFullname` not `agentName` */} (type 'exit' to quit)\\n");
24715
24976
  promptUser();
24716
24977
  })();
24717
24978
  `);
@@ -24758,7 +25019,7 @@ const OpenAiSdkTranspiler = {
24758
25019
  });
24759
25020
 
24760
25021
  const answer = response.choices[0].message.content;
24761
- console.log('\\n🧠 ${agentName}:', answer, '\\n');
25022
+ console.log('\\n🧠 ${agentName /* <- TODO: [🕛] There should be `agentFullname` not `agentName` */}:', answer, '\\n');
24762
25023
 
24763
25024
  chatHistory.push({ role: 'assistant', content: answer });
24764
25025
  promptUser();
@@ -24775,7 +25036,7 @@ const OpenAiSdkTranspiler = {
24775
25036
  });
24776
25037
  }
24777
25038
 
24778
- console.log("🤖 Chat with ${agentName} (type 'exit' to quit)\\n");
25039
+ console.log("🤖 Chat with ${agentName /* <- TODO: [🕛] There should be `agentFullname` not `agentName` */} (type 'exit' to quit)\\n");
24779
25040
  promptUser();
24780
25041
 
24781
25042
  `);
@@ -24791,7 +25052,7 @@ const OpenAiSdkTranspiler = {
24791
25052
  * @public exported from `@promptbook/wizard`
24792
25053
  * @public exported from `@promptbook/cli`
24793
25054
  *
24794
- * TODO: !!!! Which package should export this?
25055
+ * TODO: [🧠] Which package should export this?
24795
25056
  */
24796
25057
  const _OpenAiSdkTranspilerRegistration = $bookTranspilersRegister.register(OpenAiSdkTranspiler);
24797
25058
  /**