@promptbook/core 0.112.0-64 → 0.112.0-66

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 (55) hide show
  1. package/esm/index.es.js +1567 -297
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/src/_packages/components.index.d.ts +0 -2
  4. package/esm/src/_packages/core.index.d.ts +2 -2
  5. package/esm/src/_packages/types.index.d.ts +0 -2
  6. package/esm/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
  7. package/esm/src/avatars/visuals/minecraft2AvatarVisual.d.ts +7 -0
  8. package/esm/src/avatars/visuals/minecraftAvatarVisualShared.d.ts +48 -0
  9. package/esm/src/book-2.0/book-language-documentation/BookLanguageDocumentationExample.d.ts +27 -0
  10. package/esm/src/book-2.0/book-language-documentation/bookLanguageCommonPitfalls.d.ts +25 -0
  11. package/esm/src/book-2.0/book-language-documentation/bookLanguageDocumentationExamples.d.ts +10 -0
  12. package/esm/src/book-2.0/book-language-documentation/createStandaloneBookLanguageMarkdown.d.ts +14 -0
  13. package/esm/src/book-2.0/book-language-documentation/renderGroupedCommitmentDocumentationMarkdown.d.ts +43 -0
  14. package/esm/src/book-components/Chat/types/ChatMessage.d.ts +0 -34
  15. package/esm/src/cli/cli-commands/coder/ensureCoderGitignoreFile.d.ts +1 -1
  16. package/esm/src/commitments/KNOWLEDGE/KNOWLEDGE.d.ts +0 -11
  17. package/esm/src/commitments/_common/toolRuntimeContext.d.ts +0 -6
  18. package/esm/src/config.d.ts +3 -3
  19. package/esm/src/formfactors/index.d.ts +2 -2
  20. package/esm/src/formfactors/matcher/MatcherFormfactorDefinition.d.ts +1 -1
  21. package/esm/src/formfactors/translator/TranslatorFormfactorDefinition.d.ts +1 -1
  22. package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +0 -4
  23. package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionToolsOptions.d.ts +0 -9
  24. package/esm/src/utils/files/getPromptbookTempPath.d.ts +24 -0
  25. package/esm/src/version.d.ts +1 -1
  26. package/package.json +1 -2
  27. package/umd/index.umd.js +1570 -300
  28. package/umd/index.umd.js.map +1 -1
  29. package/umd/src/_packages/components.index.d.ts +0 -2
  30. package/umd/src/_packages/core.index.d.ts +2 -2
  31. package/umd/src/_packages/types.index.d.ts +0 -2
  32. package/umd/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
  33. package/umd/src/avatars/visuals/minecraft2AvatarVisual.d.ts +7 -0
  34. package/umd/src/avatars/visuals/minecraftAvatarVisualShared.d.ts +48 -0
  35. package/umd/src/book-2.0/book-language-documentation/BookLanguageDocumentationExample.d.ts +27 -0
  36. package/umd/src/book-2.0/book-language-documentation/bookLanguageCommonPitfalls.d.ts +25 -0
  37. package/umd/src/book-2.0/book-language-documentation/bookLanguageDocumentationExamples.d.ts +10 -0
  38. package/umd/src/book-2.0/book-language-documentation/createStandaloneBookLanguageMarkdown.d.ts +14 -0
  39. package/umd/src/book-2.0/book-language-documentation/renderGroupedCommitmentDocumentationMarkdown.d.ts +43 -0
  40. package/umd/src/book-2.0/book-language-documentation/renderGroupedCommitmentDocumentationMarkdown.test.d.ts +1 -0
  41. package/umd/src/book-components/Chat/types/ChatMessage.d.ts +0 -34
  42. package/umd/src/cli/cli-commands/coder/ensureCoderGitignoreFile.d.ts +1 -1
  43. package/umd/src/commitments/KNOWLEDGE/KNOWLEDGE.d.ts +0 -11
  44. package/umd/src/commitments/_common/toolRuntimeContext.d.ts +0 -6
  45. package/umd/src/config.d.ts +3 -3
  46. package/umd/src/formfactors/index.d.ts +2 -2
  47. package/umd/src/formfactors/matcher/MatcherFormfactorDefinition.d.ts +1 -1
  48. package/umd/src/formfactors/translator/TranslatorFormfactorDefinition.d.ts +1 -1
  49. package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +0 -4
  50. package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionToolsOptions.d.ts +0 -9
  51. package/umd/src/utils/files/getPromptbookTempPath.d.ts +24 -0
  52. package/umd/src/utils/files/getPromptbookTempPath.test.d.ts +1 -0
  53. package/umd/src/version.d.ts +1 -1
  54. /package/esm/src/{commitments/KNOWLEDGE/KNOWLEDGE.test.d.ts → book-2.0/book-language-documentation/renderGroupedCommitmentDocumentationMarkdown.test.d.ts} +0 -0
  55. /package/{umd/src/commitments/KNOWLEDGE/KNOWLEDGE.test.d.ts → esm/src/utils/files/getPromptbookTempPath.test.d.ts} +0 -0
package/esm/index.es.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { SHA256 } from 'crypto-js';
2
2
  import hexEncoder from 'crypto-js/enc-hex';
3
3
  import { spaceTrim as spaceTrim$1 } from 'spacetrim';
4
+ import { posix, basename, join, dirname, isAbsolute } from 'path';
4
5
  import { randomBytes } from 'crypto';
5
6
  import { Subject, BehaviorSubject } from 'rxjs';
6
7
  import { forTime } from 'waitasecond';
7
8
  import sha256 from 'crypto-js/sha256';
8
- import { basename, join, dirname, isAbsolute } from 'path';
9
9
  import { lookup, extension } from 'mime-types';
10
10
  import { parse, unparse } from 'papaparse';
11
11
  import moment from 'moment';
@@ -28,7 +28,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
28
28
  * @generated
29
29
  * @see https://github.com/webgptorg/promptbook
30
30
  */
31
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-64';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-66';
32
32
  /**
33
33
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
34
34
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -947,6 +947,29 @@ function saturate(amount) {
947
947
  }
948
948
  // TODO: Maybe implement by mix+hsl
949
949
 
950
+ /**
951
+ * Relative directory name without the `./` prefix for Git ignore rules and glob patterns.
952
+ *
953
+ * @private internal utility for Promptbook-owned temp files
954
+ */
955
+ const PROMPTBOOK_TEMP_DIRECTORY_NAME = '.promptbook';
956
+ /**
957
+ * Builds one project-relative path inside the shared Promptbook working directory.
958
+ *
959
+ * @private internal utility for Promptbook-owned temp files
960
+ */
961
+ function getPromptbookTempPath(...pathSegments) {
962
+ return `./${getPromptbookTempPosixPath(...pathSegments)}`;
963
+ }
964
+ /**
965
+ * Builds one POSIX path fragment inside the shared Promptbook working directory for globs and generated text files.
966
+ *
967
+ * @private internal utility for Promptbook-owned temp files
968
+ */
969
+ function getPromptbookTempPosixPath(...pathSegments) {
970
+ return posix.join(PROMPTBOOK_TEMP_DIRECTORY_NAME, ...pathSegments);
971
+ }
972
+
950
973
  /**
951
974
  * Returns the same value that is passed as argument.
952
975
  * No side effects.
@@ -1217,7 +1240,6 @@ const DEFAULT_BOOKS_DIRNAME = './books';
1217
1240
  */
1218
1241
  const DEFAULT_AGENTS_DIRNAME = './agents';
1219
1242
  // <- TODO: [🕝] Make also `AGENTS_DIRNAME_ALTERNATIVES`
1220
- // TODO: Just `.promptbook` in config, hardcode subfolders like `download-cache` or `execution-cache`
1221
1243
  /**
1222
1244
  * Where to store the temporary downloads
1223
1245
  *
@@ -1225,7 +1247,7 @@ const DEFAULT_AGENTS_DIRNAME = './agents';
1225
1247
  *
1226
1248
  * @public exported from `@promptbook/core`
1227
1249
  */
1228
- const DEFAULT_DOWNLOAD_CACHE_DIRNAME = './.promptbook/download-cache';
1250
+ const DEFAULT_DOWNLOAD_CACHE_DIRNAME = getPromptbookTempPath('download-cache');
1229
1251
  /**
1230
1252
  * Where to store the cache of executions for promptbook CLI
1231
1253
  *
@@ -1233,7 +1255,7 @@ const DEFAULT_DOWNLOAD_CACHE_DIRNAME = './.promptbook/download-cache';
1233
1255
  *
1234
1256
  * @public exported from `@promptbook/core`
1235
1257
  */
1236
- const DEFAULT_EXECUTION_CACHE_DIRNAME = './.promptbook/execution-cache';
1258
+ const DEFAULT_EXECUTION_CACHE_DIRNAME = getPromptbookTempPath('execution-cache');
1237
1259
  /**
1238
1260
  * Where to store the scrape cache
1239
1261
  *
@@ -1241,7 +1263,7 @@ const DEFAULT_EXECUTION_CACHE_DIRNAME = './.promptbook/execution-cache';
1241
1263
  *
1242
1264
  * @public exported from `@promptbook/core`
1243
1265
  */
1244
- const DEFAULT_SCRAPE_CACHE_DIRNAME = './.promptbook/scrape-cache';
1266
+ const DEFAULT_SCRAPE_CACHE_DIRNAME = getPromptbookTempPath('scrape-cache');
1245
1267
  /**
1246
1268
  * Id of application for the CLI when using remote server
1247
1269
  *
@@ -12088,18 +12110,6 @@ function parseDataUrlKnowledgeSource(source) {
12088
12110
  }
12089
12111
  // Note: [💞] Ignore a discrepancy between file name and entity name
12090
12112
 
12091
- /**
12092
- * Name of the tool used by agents to search configured `KNOWLEDGE` sources.
12093
- *
12094
- * @public exported from `@promptbook/core`
12095
- */
12096
- const KNOWLEDGE_SEARCH_TOOL_NAME = 'knowledge_search';
12097
- /**
12098
- * Title of the system-message section generated for `KNOWLEDGE` commitments.
12099
- *
12100
- * @private constant of `KnowledgeCommitmentDefinition`
12101
- */
12102
- const KNOWLEDGE_SEARCH_SYSTEM_SECTION_TITLE = 'Knowledge Search';
12103
12113
  /**
12104
12114
  * KNOWLEDGE commitment definition
12105
12115
  *
@@ -12221,17 +12231,9 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
12221
12231
  knowledgeInfoEntries.push(`Knowledge Source Inline: ${inlineSource.filename} (derived from inline content and processed for retrieval during chat)`);
12222
12232
  }
12223
12233
  if (knowledgeInfoEntries.length === 0) {
12224
- return addKnowledgeSearchToolAndSystemSection(nextRequirements);
12234
+ return nextRequirements;
12225
12235
  }
12226
- return addKnowledgeSearchToolAndSystemSection(nextRequirements);
12227
- }
12228
- /**
12229
- * Gets human-readable titles for tool functions provided by this commitment.
12230
- */
12231
- getToolTitles() {
12232
- return {
12233
- [KNOWLEDGE_SEARCH_TOOL_NAME]: 'Knowledge search',
12234
- };
12236
+ return this.appendToSystemMessage(nextRequirements, knowledgeInfoEntries.join('\n'), '\n\n');
12235
12237
  }
12236
12238
  }
12237
12239
  /**
@@ -12245,128 +12247,6 @@ function hasMeaningfulNonUrlText(content, urls) {
12245
12247
  const significantText = contentWithoutUrls.replace(/[\s.,!?;:'"`()[\]{}<>/-]+/g, '');
12246
12248
  return significantText.length > 0;
12247
12249
  }
12248
- /**
12249
- * Adds the shared `knowledge_search` tool definition and the consolidated system-message section.
12250
- *
12251
- * @param requirements - Requirements after one `KNOWLEDGE` commitment was applied.
12252
- * @returns Requirements with the knowledge search instructions and tool definition.
12253
- *
12254
- * @private internal utility of `KnowledgeCommitmentDefinition`
12255
- */
12256
- function addKnowledgeSearchToolAndSystemSection(requirements) {
12257
- const nextRequirements = addKnowledgeSearchTool(requirements);
12258
- const section = createKnowledgeSearchSystemSection(nextRequirements);
12259
- const sectionHeader = `## ${KNOWLEDGE_SEARCH_SYSTEM_SECTION_TITLE}`;
12260
- if (nextRequirements.systemMessage.includes(sectionHeader)) {
12261
- return {
12262
- ...nextRequirements,
12263
- systemMessage: nextRequirements.systemMessage.replace(new RegExp(`## ${KNOWLEDGE_SEARCH_SYSTEM_SECTION_TITLE.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[\\s\\S]*?(?=\\n\\n##|$)`), section),
12264
- };
12265
- }
12266
- return {
12267
- ...nextRequirements,
12268
- systemMessage: nextRequirements.systemMessage.trim()
12269
- ? `${nextRequirements.systemMessage}\n\n${section}`
12270
- : section,
12271
- };
12272
- }
12273
- /**
12274
- * Adds the `knowledge_search` model tool when it is not already present.
12275
- *
12276
- * @param requirements - Current model requirements.
12277
- * @returns Requirements with the tool definition available to the model.
12278
- *
12279
- * @private internal utility of `KnowledgeCommitmentDefinition`
12280
- */
12281
- function addKnowledgeSearchTool(requirements) {
12282
- const existingTools = requirements.tools || [];
12283
- if (existingTools.some((tool) => tool.name === KNOWLEDGE_SEARCH_TOOL_NAME)) {
12284
- return requirements;
12285
- }
12286
- return {
12287
- ...requirements,
12288
- tools: [
12289
- ...existingTools,
12290
- {
12291
- name: KNOWLEDGE_SEARCH_TOOL_NAME,
12292
- description: spaceTrim$1(`
12293
- Search the agent's configured knowledge sources and return relevant excerpts with citation ids.
12294
- Use this before answering questions that may depend on the agent's KNOWLEDGE commitments.
12295
- `),
12296
- parameters: {
12297
- type: 'object',
12298
- properties: {
12299
- query: {
12300
- type: 'string',
12301
- description: 'The natural-language search query for the knowledge base.',
12302
- },
12303
- limit: {
12304
- type: 'integer',
12305
- description: 'Maximum number of matching source excerpts to return.',
12306
- },
12307
- },
12308
- required: ['query'],
12309
- },
12310
- },
12311
- ],
12312
- };
12313
- }
12314
- /**
12315
- * Creates the model-facing system-message section for knowledge search.
12316
- *
12317
- * @param requirements - Current model requirements.
12318
- * @returns Markdown system-message section.
12319
- *
12320
- * @private internal utility of `KnowledgeCommitmentDefinition`
12321
- */
12322
- function createKnowledgeSearchSystemSection(requirements) {
12323
- const sourceEntries = createKnowledgeSourceSystemEntries(requirements);
12324
- const sourceList = sourceEntries.length > 0 ? sourceEntries.map((entry) => `- ${entry}`).join('\n') : '- None';
12325
- return spaceTrim$1(`
12326
- ## ${KNOWLEDGE_SEARCH_SYSTEM_SECTION_TITLE}
12327
-
12328
- - Use \`${KNOWLEDGE_SEARCH_TOOL_NAME}\` to search the configured knowledge sources before answering questions that depend on this agent's knowledge base.
12329
- - Base source-backed factual answers on the returned excerpts.
12330
- - When you use a returned excerpt, include its citation marker in the answer body, for example \`[0:0]\`.
12331
- - If the search returns no relevant information, say that the knowledge base did not contain the answer instead of inventing it.
12332
-
12333
- Configured knowledge sources:
12334
- ${sourceList}
12335
- `);
12336
- }
12337
- /**
12338
- * Builds a stable list of configured knowledge sources for system-message diagnostics.
12339
- *
12340
- * @param requirements - Current model requirements.
12341
- * @returns Human-readable source entries.
12342
- *
12343
- * @private internal utility of `KnowledgeCommitmentDefinition`
12344
- */
12345
- function createKnowledgeSourceSystemEntries(requirements) {
12346
- var _a;
12347
- const entries = [];
12348
- const seenEntries = new Set();
12349
- for (const source of requirements.knowledgeSources || []) {
12350
- const entry = `Source URL: ${source} (processed for retrieval during chat)`;
12351
- if (seenEntries.has(entry)) {
12352
- continue;
12353
- }
12354
- seenEntries.add(entry);
12355
- entries.push(entry);
12356
- }
12357
- const inlineSources = (((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.inlineKnowledgeSources) || [])
12358
- .map((source) => source.filename)
12359
- .filter(Boolean);
12360
- for (const filename of inlineSources) {
12361
- const entry = `Knowledge Source Inline: ${filename} (Inline source: processed for retrieval during chat)`;
12362
- if (seenEntries.has(entry)) {
12363
- continue;
12364
- }
12365
- seenEntries.add(entry);
12366
- entries.push(entry);
12367
- }
12368
- return entries;
12369
- }
12370
12250
 
12371
12251
  /**
12372
12252
  * LANGUAGE commitment definition
@@ -14999,6 +14879,177 @@ function drawFractalCore(context, size, palette, timeMs, corePhase) {
14999
14879
  context.restore();
15000
14880
  }
15001
14881
 
14882
+ /* eslint-disable no-magic-numbers */
14883
+ /**
14884
+ * Builds the seeded six-face texture pack used by the Minecraft-style head cuboid.
14885
+ *
14886
+ * @param random Seeded random generator.
14887
+ * @param palette Derived avatar palette.
14888
+ * @param hasHeadband Whether the generated avatar should include a colored headband.
14889
+ * @returns Head cuboid textures.
14890
+ *
14891
+ * @private helper of the Minecraft avatar visuals
14892
+ */
14893
+ function createMinecraftHeadTextures(random, palette, hasHeadband) {
14894
+ const faceTexture = createMinecraftFaceTexture(random, palette, hasHeadband);
14895
+ const hairColor = random() < 0.5 ? palette.primary : palette.secondary;
14896
+ const skinColor = palette.highlight;
14897
+ const headbandColor = hasHeadband ? palette.accent : hairColor;
14898
+ const sideTexture = createFilledTexture(skinColor);
14899
+ const backTexture = createFilledTexture(skinColor);
14900
+ const topTexture = createFilledTexture(hairColor);
14901
+ const bottomTexture = createFilledTexture(`${palette.shadow}cc`);
14902
+ fillTextureRect(sideTexture, 0, 0, 8, 3, hairColor);
14903
+ fillTextureRect(backTexture, 0, 0, 8, 5, hairColor);
14904
+ fillTextureRect(backTexture, 1, 5, 6, 1, hairColor);
14905
+ if (hasHeadband) {
14906
+ fillTextureRect(sideTexture, 0, 2, 8, 1, headbandColor);
14907
+ fillTextureRect(backTexture, 0, 2, 8, 1, headbandColor);
14908
+ fillTextureRect(topTexture, 0, 4, 8, 1, headbandColor);
14909
+ }
14910
+ sideTexture[4][4] = `${palette.shadow}99`;
14911
+ sideTexture[5][4] = `${palette.shadow}cc`;
14912
+ backTexture[6][2] = `${palette.shadow}99`;
14913
+ backTexture[6][5] = `${palette.shadow}99`;
14914
+ return {
14915
+ front: faceTexture,
14916
+ back: backTexture,
14917
+ left: sideTexture,
14918
+ right: mirrorMinecraftTexture(sideTexture),
14919
+ top: topTexture,
14920
+ bottom: bottomTexture,
14921
+ };
14922
+ }
14923
+ /**
14924
+ * Builds the seeded six-face texture pack used by the Minecraft-style torso cuboid.
14925
+ *
14926
+ * @param random Seeded random generator.
14927
+ * @param palette Derived avatar palette.
14928
+ * @returns Torso cuboid textures.
14929
+ *
14930
+ * @private helper of the Minecraft avatar visuals
14931
+ */
14932
+ function createMinecraftTorsoTextures(random, palette) {
14933
+ const frontTexture = createMinecraftShirtTexture(random, palette);
14934
+ const sideTexture = createFilledTexture(palette.primary);
14935
+ const backTexture = createFilledTexture(palette.primary);
14936
+ const topTexture = createFilledTexture(`${palette.highlight}dd`);
14937
+ const bottomTexture = createFilledTexture(`${palette.shadow}dd`);
14938
+ const stripeColor = random() < 0.5 ? palette.secondary : palette.highlight;
14939
+ fillTextureRect(sideTexture, 0, 0, 8, 2, palette.shadow);
14940
+ fillTextureRect(backTexture, 0, 0, 8, 2, palette.shadow);
14941
+ fillTextureRect(backTexture, 3, 2, 2, 6, stripeColor);
14942
+ fillTextureRect(sideTexture, 4, 2, 1, 6, stripeColor);
14943
+ fillTextureRect(topTexture, 0, 0, 8, 2, palette.shadow);
14944
+ fillTextureRect(topTexture, 2, 2, 4, 4, stripeColor);
14945
+ return {
14946
+ front: frontTexture,
14947
+ back: backTexture,
14948
+ left: sideTexture,
14949
+ right: mirrorMinecraftTexture(sideTexture),
14950
+ top: topTexture,
14951
+ bottom: bottomTexture,
14952
+ };
14953
+ }
14954
+ /**
14955
+ * Mirrors one Minecraft texture horizontally.
14956
+ *
14957
+ * @param texture Source texture.
14958
+ * @returns Mirrored texture copy.
14959
+ *
14960
+ * @private helper of the Minecraft avatar visuals
14961
+ */
14962
+ function mirrorMinecraftTexture(texture) {
14963
+ return texture.map((row) => [...row].reverse());
14964
+ }
14965
+ /**
14966
+ * Creates the front-face pixel texture for the cube head.
14967
+ *
14968
+ * @param random Seeded random generator.
14969
+ * @param palette Derived avatar palette.
14970
+ * @param hasHeadband Whether the avatar should render a headband row.
14971
+ * @returns 8x8 pixel texture.
14972
+ *
14973
+ * @private helper of the Minecraft avatar visuals
14974
+ */
14975
+ function createMinecraftFaceTexture(random, palette, hasHeadband) {
14976
+ const texture = createFilledTexture(palette.highlight);
14977
+ const hairlineColor = random() < 0.5 ? palette.primary : palette.secondary;
14978
+ const cheekColor = random() < 0.5 ? `${palette.accent}bb` : `${palette.secondary}bb`;
14979
+ fillTextureRect(texture, 0, 0, 8, 2, hairlineColor);
14980
+ texture[2][0] = hairlineColor;
14981
+ texture[2][7] = hairlineColor;
14982
+ texture[3][0] = hairlineColor;
14983
+ texture[3][7] = hairlineColor;
14984
+ if (hasHeadband) {
14985
+ fillTextureRect(texture, 0, 2, 8, 1, palette.accent);
14986
+ }
14987
+ texture[3][2] = palette.ink;
14988
+ texture[3][5] = palette.ink;
14989
+ texture[4][2] = '#ffffff';
14990
+ texture[4][5] = '#ffffff';
14991
+ texture[5][1] = cheekColor;
14992
+ texture[5][6] = cheekColor;
14993
+ texture[5][3] = palette.shadow;
14994
+ texture[5][4] = palette.shadow;
14995
+ texture[6][3] = palette.shadow;
14996
+ texture[6][4] = palette.shadow;
14997
+ return texture;
14998
+ }
14999
+ /**
15000
+ * Creates the front-face pixel texture for the torso.
15001
+ *
15002
+ * @param random Seeded random generator.
15003
+ * @param palette Derived avatar palette.
15004
+ * @returns 8x8 torso texture.
15005
+ *
15006
+ * @private helper of the Minecraft avatar visuals
15007
+ */
15008
+ function createMinecraftShirtTexture(random, palette) {
15009
+ const texture = createFilledTexture(palette.primary);
15010
+ const stripeColor = random() < 0.5 ? palette.secondary : palette.highlight;
15011
+ fillTextureRect(texture, 0, 0, 8, 2, palette.shadow);
15012
+ for (let rowIndex = 2; rowIndex < 8; rowIndex++) {
15013
+ texture[rowIndex][3] = stripeColor;
15014
+ texture[rowIndex][4] = stripeColor;
15015
+ }
15016
+ texture[4][1] = palette.accent;
15017
+ texture[4][6] = palette.accent;
15018
+ texture[5][2] = palette.highlight;
15019
+ texture[5][5] = palette.highlight;
15020
+ return texture;
15021
+ }
15022
+ /**
15023
+ * Creates one solid-color 8x8 Minecraft texture.
15024
+ *
15025
+ * @param color Fill color.
15026
+ * @returns Filled 8x8 texture.
15027
+ *
15028
+ * @private helper of the Minecraft avatar visuals
15029
+ */
15030
+ function createFilledTexture(color) {
15031
+ return Array.from({ length: 8 }, () => Array.from({ length: 8 }, () => color));
15032
+ }
15033
+ /**
15034
+ * Fills one rectangular area inside a mutable Minecraft texture.
15035
+ *
15036
+ * @param texture Mutable target texture.
15037
+ * @param x Left texture coordinate.
15038
+ * @param y Top texture coordinate.
15039
+ * @param width Rectangle width.
15040
+ * @param height Rectangle height.
15041
+ * @param color Fill color.
15042
+ *
15043
+ * @private helper of the Minecraft avatar visuals
15044
+ */
15045
+ function fillTextureRect(texture, x, y, width, height, color) {
15046
+ for (let rowIndex = y; rowIndex < y + height; rowIndex++) {
15047
+ for (let columnIndex = x; columnIndex < x + width; columnIndex++) {
15048
+ texture[rowIndex][columnIndex] = color;
15049
+ }
15050
+ }
15051
+ }
15052
+
15002
15053
  /* eslint-disable no-magic-numbers */
15003
15054
  /**
15004
15055
  * Minecraft-style 3D avatar visual.
@@ -15023,8 +15074,8 @@ const minecraftAvatarVisual = {
15023
15074
  const bodyX = size * 0.33;
15024
15075
  const bodyY = headY + headSize * 0.96;
15025
15076
  const hasHeadband = random() < 0.5;
15026
- const faceTexture = createMinecraftFaceTexture(createRandom('minecraft-face'), palette, hasHeadband);
15027
- const shirtTexture = createMinecraftShirtTexture(createRandom('minecraft-shirt'), palette);
15077
+ const headTextures = createMinecraftHeadTextures(createRandom('minecraft-face'), palette, hasHeadband);
15078
+ const torsoTextures = createMinecraftTorsoTextures(createRandom('minecraft-shirt'), palette);
15028
15079
  drawAvatarFrame(context, size, palette);
15029
15080
  const spotlight = context.createRadialGradient(size * 0.5, size * 0.18, size * 0.05, size * 0.5, size * 0.18, size * 0.5);
15030
15081
  spotlight.addColorStop(0, `${palette.highlight}66`);
@@ -15044,7 +15095,7 @@ const minecraftAvatarVisual = {
15044
15095
  width: bodyWidth,
15045
15096
  height: bodyHeight,
15046
15097
  depth: bodyDepth,
15047
- frontTexture: shirtTexture,
15098
+ frontTexture: torsoTextures.front,
15048
15099
  topColor: `${palette.highlight}cc`,
15049
15100
  sideColor: `${palette.secondary}dd`,
15050
15101
  outlineColor: `${palette.shadow}aa`,
@@ -15055,7 +15106,7 @@ const minecraftAvatarVisual = {
15055
15106
  width: headSize,
15056
15107
  height: headSize,
15057
15108
  depth,
15058
- frontTexture: faceTexture,
15109
+ frontTexture: headTextures.front,
15059
15110
  topColor: `${palette.highlight}ee`,
15060
15111
  sideColor: `${palette.secondary}ee`,
15061
15112
  outlineColor: `${palette.shadow}cc`,
@@ -15120,72 +15171,505 @@ function drawVoxelCuboid(context, cuboid) {
15120
15171
  context.closePath();
15121
15172
  context.stroke();
15122
15173
  }
15174
+
15175
+ /* eslint-disable no-magic-numbers */
15123
15176
  /**
15124
- * Creates the front-face pixel texture for the cube head.
15177
+ * Fixed scene camera distance used for the proper-3D projection.
15125
15178
  *
15126
- * @param random Seeded random generator.
15179
+ * @private helper of `minecraft2AvatarVisual`
15180
+ */
15181
+ const CAMERA_DISTANCE_RATIO = 1.4;
15182
+ /**
15183
+ * Shared light direction used to shade projected cuboid faces.
15184
+ *
15185
+ * @private helper of `minecraft2AvatarVisual`
15186
+ */
15187
+ const LIGHT_DIRECTION = normalizeVector3({
15188
+ x: 0.4,
15189
+ y: -0.65,
15190
+ z: 0.92,
15191
+ });
15192
+ /**
15193
+ * Minecraft 3D 2 avatar visual.
15194
+ *
15195
+ * @private built-in avatar visual
15196
+ */
15197
+ const minecraft2AvatarVisual = {
15198
+ id: 'minecraft2',
15199
+ title: 'Minecraft 3D 2',
15200
+ description: 'Proper 3D Minecraft-style portrait with textured cuboids and pointer-driven head turns.',
15201
+ isAnimated: true,
15202
+ supportsPointerTracking: true,
15203
+ render({ context, size, palette, createRandom, timeMs, interaction }) {
15204
+ const spotlightY = size * 0.22;
15205
+ const headRandom = createRandom('minecraft2-head');
15206
+ const hasHeadband = headRandom() < 0.5;
15207
+ const headTextures = createMinecraftHeadTextures(createRandom('minecraft2-head-textures'), palette, hasHeadband);
15208
+ const torsoTextures = createMinecraftTorsoTextures(createRandom('minecraft2-body-textures'), palette);
15209
+ const bob = Math.sin(timeMs / 880) * size * 0.014;
15210
+ const bodyYaw = -0.24 + Math.sin(timeMs / 2300) * 0.06 + interaction.bodyOffsetX * 0.16;
15211
+ const bodyPitch = -0.12 + Math.cos(timeMs / 2800) * 0.02 - interaction.bodyOffsetY * 0.06;
15212
+ const headYaw = -0.18 + Math.sin(timeMs / 1900 + 0.6) * 0.05 + interaction.gazeX * 0.62;
15213
+ const headPitch = -0.12 + Math.cos(timeMs / 2400 + 1.1) * 0.03 - interaction.gazeY * 0.38;
15214
+ const sceneCenterX = size * 0.5;
15215
+ const sceneCenterY = size * 0.57;
15216
+ const bodyWidth = size * 0.225;
15217
+ const bodyHeight = size * 0.245;
15218
+ const bodyDepth = size * 0.145;
15219
+ const headSize = size * 0.24;
15220
+ const headLift = size * 0.205;
15221
+ const headForwardShift = interaction.intensity * size * 0.018;
15222
+ const sceneCuboids = [
15223
+ {
15224
+ center: {
15225
+ x: interaction.bodyOffsetX * size * 0.026,
15226
+ y: size * 0.05 + interaction.bodyOffsetY * size * 0.018 + bob,
15227
+ z: 0,
15228
+ },
15229
+ width: bodyWidth,
15230
+ height: bodyHeight,
15231
+ depth: bodyDepth,
15232
+ rotationX: bodyPitch,
15233
+ rotationY: bodyYaw,
15234
+ textures: torsoTextures,
15235
+ outlineColor: `${palette.shadow}cc`,
15236
+ },
15237
+ {
15238
+ center: {
15239
+ x: interaction.bodyOffsetX * size * 0.018 + interaction.gazeX * size * 0.016,
15240
+ y: -headLift + bob * 1.15,
15241
+ z: headForwardShift,
15242
+ },
15243
+ width: headSize,
15244
+ height: headSize,
15245
+ depth: headSize,
15246
+ rotationX: headPitch,
15247
+ rotationY: headYaw,
15248
+ textures: headTextures,
15249
+ outlineColor: `${palette.shadow}dd`,
15250
+ },
15251
+ ];
15252
+ const visibleFaces = sceneCuboids
15253
+ .flatMap((cuboid) => resolveVisibleCuboidFaces(cuboid, size, sceneCenterX, sceneCenterY))
15254
+ .sort((firstFace, secondFace) => firstFace.averageDepth - secondFace.averageDepth);
15255
+ drawAvatarFrame(context, size, palette);
15256
+ drawMinecraftBackdrop(context, size, palette, sceneCenterX, spotlightY, interaction, timeMs);
15257
+ drawMinecraftShadow(context, size, palette, interaction, timeMs);
15258
+ for (const visibleFace of visibleFaces) {
15259
+ drawTexturedProjectedFace(context, visibleFace);
15260
+ }
15261
+ },
15262
+ };
15263
+ /**
15264
+ * Draws the shared background atmosphere behind the Minecraft 3D 2 portrait.
15265
+ *
15266
+ * @param context Canvas 2D context.
15267
+ * @param size Canvas size in CSS pixels.
15127
15268
  * @param palette Derived avatar palette.
15128
- * @param hasHeadband Whether the avatar should render a headband row.
15129
- * @returns 8x8 pixel texture.
15269
+ * @param sceneCenterX Horizontal scene center.
15270
+ * @param spotlightY Vertical spotlight anchor.
15271
+ * @param interaction Smoothed pointer-aware interaction state.
15272
+ * @param timeMs Current animation time in milliseconds.
15130
15273
  *
15131
- * @private helper of `minecraftAvatarVisual`
15274
+ * @private helper of `minecraft2AvatarVisual`
15132
15275
  */
15133
- function createMinecraftFaceTexture(random, palette, hasHeadband) {
15134
- const texture = Array.from({ length: 8 }, () => Array.from({ length: 8 }, () => palette.highlight));
15135
- const hairlineColor = random() < 0.5 ? palette.primary : palette.secondary;
15136
- const cheekColor = random() < 0.5 ? `${palette.accent}bb` : `${palette.secondary}bb`;
15137
- for (let rowIndex = 0; rowIndex < 2; rowIndex++) {
15138
- for (let columnIndex = 0; columnIndex < 8; columnIndex++) {
15139
- texture[rowIndex][columnIndex] = hairlineColor;
15276
+ function drawMinecraftBackdrop(context, size, palette, sceneCenterX, spotlightY, interaction, timeMs) {
15277
+ const spotlightGradient = context.createRadialGradient(sceneCenterX + interaction.gazeX * size * 0.08, spotlightY + interaction.gazeY * size * 0.05, size * 0.03, sceneCenterX, spotlightY, size * 0.52);
15278
+ spotlightGradient.addColorStop(0, `${palette.highlight}66`);
15279
+ spotlightGradient.addColorStop(0.42, `${palette.accent}1d`);
15280
+ spotlightGradient.addColorStop(1, `${palette.highlight}00`);
15281
+ context.fillStyle = spotlightGradient;
15282
+ context.fillRect(0, 0, size, size);
15283
+ const rimGradient = context.createLinearGradient(0, size * 0.14, 0, size * 0.92);
15284
+ rimGradient.addColorStop(0, `${palette.highlight}12`);
15285
+ rimGradient.addColorStop(0.55, `${palette.secondary}0a`);
15286
+ rimGradient.addColorStop(1, `${palette.shadow}00`);
15287
+ context.fillStyle = rimGradient;
15288
+ context.fillRect(0, 0, size, size);
15289
+ context.save();
15290
+ context.globalAlpha = 0.08 + interaction.intensity * 0.04;
15291
+ context.fillStyle = palette.highlight;
15292
+ context.beginPath();
15293
+ context.arc(size * 0.72 + Math.sin(timeMs / 1600) * size * 0.03, size * 0.2 + Math.cos(timeMs / 1400) * size * 0.018, size * 0.025, 0, Math.PI * 2);
15294
+ context.fill();
15295
+ context.restore();
15296
+ }
15297
+ /**
15298
+ * Draws the soft floor shadow used to anchor the cuboids in the frame.
15299
+ *
15300
+ * @param context Canvas 2D context.
15301
+ * @param size Canvas size in CSS pixels.
15302
+ * @param palette Derived avatar palette.
15303
+ * @param interaction Smoothed pointer-aware interaction state.
15304
+ * @param timeMs Current animation time in milliseconds.
15305
+ *
15306
+ * @private helper of `minecraft2AvatarVisual`
15307
+ */
15308
+ function drawMinecraftShadow(context, size, palette, interaction, timeMs) {
15309
+ context.save();
15310
+ context.fillStyle = `${palette.shadow}66`;
15311
+ context.filter = `blur(${size * 0.02}px)`;
15312
+ context.beginPath();
15313
+ context.ellipse(size * 0.5 + interaction.gazeX * size * 0.03, size * 0.85 + Math.sin(timeMs / 880) * size * 0.01, size * (0.16 + interaction.intensity * 0.015), size * 0.055, 0, 0, Math.PI * 2);
15314
+ context.fill();
15315
+ context.restore();
15316
+ }
15317
+ /**
15318
+ * Resolves all visible projected faces for one scene cuboid.
15319
+ *
15320
+ * @param cuboid Scene cuboid definition.
15321
+ * @param size Canvas size in CSS pixels.
15322
+ * @param sceneCenterX Horizontal scene center.
15323
+ * @param sceneCenterY Vertical scene center.
15324
+ * @returns Visible faces sorted later by depth.
15325
+ *
15326
+ * @private helper of `minecraft2AvatarVisual`
15327
+ */
15328
+ function resolveVisibleCuboidFaces(cuboid, size, sceneCenterX, sceneCenterY) {
15329
+ const halfWidth = cuboid.width / 2;
15330
+ const halfHeight = cuboid.height / 2;
15331
+ const halfDepth = cuboid.depth / 2;
15332
+ const faceDefinitions = [
15333
+ {
15334
+ texture: cuboid.textures.front,
15335
+ corners: [
15336
+ { x: -halfWidth, y: -halfHeight, z: halfDepth },
15337
+ { x: halfWidth, y: -halfHeight, z: halfDepth },
15338
+ { x: halfWidth, y: halfHeight, z: halfDepth },
15339
+ { x: -halfWidth, y: halfHeight, z: halfDepth },
15340
+ ],
15341
+ },
15342
+ {
15343
+ texture: cuboid.textures.back,
15344
+ corners: [
15345
+ { x: halfWidth, y: -halfHeight, z: -halfDepth },
15346
+ { x: -halfWidth, y: -halfHeight, z: -halfDepth },
15347
+ { x: -halfWidth, y: halfHeight, z: -halfDepth },
15348
+ { x: halfWidth, y: halfHeight, z: -halfDepth },
15349
+ ],
15350
+ },
15351
+ {
15352
+ texture: cuboid.textures.right,
15353
+ corners: [
15354
+ { x: halfWidth, y: -halfHeight, z: halfDepth },
15355
+ { x: halfWidth, y: -halfHeight, z: -halfDepth },
15356
+ { x: halfWidth, y: halfHeight, z: -halfDepth },
15357
+ { x: halfWidth, y: halfHeight, z: halfDepth },
15358
+ ],
15359
+ },
15360
+ {
15361
+ texture: cuboid.textures.left,
15362
+ corners: [
15363
+ { x: -halfWidth, y: -halfHeight, z: -halfDepth },
15364
+ { x: -halfWidth, y: -halfHeight, z: halfDepth },
15365
+ { x: -halfWidth, y: halfHeight, z: halfDepth },
15366
+ { x: -halfWidth, y: halfHeight, z: -halfDepth },
15367
+ ],
15368
+ },
15369
+ {
15370
+ texture: cuboid.textures.top,
15371
+ corners: [
15372
+ { x: -halfWidth, y: -halfHeight, z: -halfDepth },
15373
+ { x: halfWidth, y: -halfHeight, z: -halfDepth },
15374
+ { x: halfWidth, y: -halfHeight, z: halfDepth },
15375
+ { x: -halfWidth, y: -halfHeight, z: halfDepth },
15376
+ ],
15377
+ },
15378
+ {
15379
+ texture: cuboid.textures.bottom,
15380
+ corners: [
15381
+ { x: -halfWidth, y: halfHeight, z: halfDepth },
15382
+ { x: halfWidth, y: halfHeight, z: halfDepth },
15383
+ { x: halfWidth, y: halfHeight, z: -halfDepth },
15384
+ { x: -halfWidth, y: halfHeight, z: -halfDepth },
15385
+ ],
15386
+ },
15387
+ ];
15388
+ const visibleFaces = faceDefinitions
15389
+ .map((faceDefinition) => {
15390
+ const transformedCorners = faceDefinition.corners.map((corner) => transformScenePoint(corner, cuboid.center, cuboid.rotationX, cuboid.rotationY));
15391
+ const faceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
15392
+ if (faceNormal.z <= 0.02) {
15393
+ return null;
15140
15394
  }
15395
+ const projectedCorners = transformedCorners.map((corner) => projectScenePoint(corner, size, sceneCenterX, sceneCenterY));
15396
+ return {
15397
+ corners: projectedCorners,
15398
+ texture: faceDefinition.texture,
15399
+ averageDepth: transformedCorners.reduce((depthSum, corner) => depthSum + corner.z, 0) / transformedCorners.length,
15400
+ lightIntensity: clampNumber$1(dotProduct3D(faceNormal, LIGHT_DIRECTION), -1, 1),
15401
+ outlineColor: cuboid.outlineColor,
15402
+ };
15403
+ });
15404
+ return visibleFaces.filter((visibleFace) => visibleFace !== null);
15405
+ }
15406
+ /**
15407
+ * Draws one projected textured face by tessellating its texture cells into quads.
15408
+ *
15409
+ * @param context Canvas 2D context.
15410
+ * @param face Visible projected face.
15411
+ *
15412
+ * @private helper of `minecraft2AvatarVisual`
15413
+ */
15414
+ function drawTexturedProjectedFace(context, face) {
15415
+ var _a;
15416
+ const rows = face.texture.length;
15417
+ const columns = ((_a = face.texture[0]) === null || _a === void 0 ? void 0 : _a.length) || 0;
15418
+ if (rows === 0 || columns === 0) {
15419
+ return;
15141
15420
  }
15142
- texture[2][0] = hairlineColor;
15143
- texture[2][7] = hairlineColor;
15144
- texture[3][0] = hairlineColor;
15145
- texture[3][7] = hairlineColor;
15146
- if (hasHeadband) {
15147
- for (let columnIndex = 0; columnIndex < 8; columnIndex++) {
15148
- texture[2][columnIndex] = palette.accent;
15421
+ for (let rowIndex = 0; rowIndex < rows; rowIndex++) {
15422
+ for (let columnIndex = 0; columnIndex < columns; columnIndex++) {
15423
+ const startX = columnIndex / columns;
15424
+ const endX = (columnIndex + 1) / columns;
15425
+ const startY = rowIndex / rows;
15426
+ const endY = (rowIndex + 1) / rows;
15427
+ drawProjectedQuad(context, [
15428
+ interpolateProjectedQuad(face.corners, startX, startY),
15429
+ interpolateProjectedQuad(face.corners, endX, startY),
15430
+ interpolateProjectedQuad(face.corners, endX, endY),
15431
+ interpolateProjectedQuad(face.corners, startX, endY),
15432
+ ], face.texture[rowIndex][columnIndex]);
15149
15433
  }
15150
15434
  }
15151
- texture[3][2] = palette.ink;
15152
- texture[3][5] = palette.ink;
15153
- texture[4][2] = '#ffffff';
15154
- texture[4][5] = '#ffffff';
15155
- texture[5][1] = cheekColor;
15156
- texture[5][6] = cheekColor;
15157
- texture[5][3] = palette.shadow;
15158
- texture[5][4] = palette.shadow;
15159
- texture[6][3] = palette.shadow;
15160
- texture[6][4] = palette.shadow;
15161
- return texture;
15435
+ if (face.lightIntensity > 0) {
15436
+ drawProjectedQuad(context, face.corners, `rgba(255, 255, 255, ${0.15 * face.lightIntensity})`);
15437
+ }
15438
+ else if (face.lightIntensity < 0) {
15439
+ drawProjectedQuad(context, face.corners, `rgba(0, 0, 0, ${0.22 * Math.abs(face.lightIntensity)})`);
15440
+ }
15441
+ context.save();
15442
+ context.beginPath();
15443
+ context.moveTo(face.corners[0].x, face.corners[0].y);
15444
+ for (let cornerIndex = 1; cornerIndex < face.corners.length; cornerIndex++) {
15445
+ context.lineTo(face.corners[cornerIndex].x, face.corners[cornerIndex].y);
15446
+ }
15447
+ context.closePath();
15448
+ context.strokeStyle = face.outlineColor;
15449
+ context.lineWidth = Math.max(1.1, getProjectedQuadPerimeter(face.corners) * 0.0045);
15450
+ context.lineJoin = 'round';
15451
+ context.stroke();
15452
+ context.restore();
15162
15453
  }
15163
15454
  /**
15164
- * Creates the front-face pixel texture for the torso.
15455
+ * Draws one filled projected quad.
15165
15456
  *
15166
- * @param random Seeded random generator.
15167
- * @param palette Derived avatar palette.
15168
- * @returns 8x8 torso texture.
15457
+ * @param context Canvas 2D context.
15458
+ * @param corners Quad corners in clockwise order.
15459
+ * @param fillStyle CSS fill style.
15169
15460
  *
15170
- * @private helper of `minecraftAvatarVisual`
15461
+ * @private helper of `minecraft2AvatarVisual`
15171
15462
  */
15172
- function createMinecraftShirtTexture(random, palette) {
15173
- const texture = Array.from({ length: 8 }, () => Array.from({ length: 8 }, () => palette.primary));
15174
- const stripeColor = random() < 0.5 ? palette.secondary : palette.highlight;
15175
- for (let rowIndex = 0; rowIndex < 2; rowIndex++) {
15176
- for (let columnIndex = 0; columnIndex < 8; columnIndex++) {
15177
- texture[rowIndex][columnIndex] = palette.shadow;
15178
- }
15463
+ function drawProjectedQuad(context, corners, fillStyle) {
15464
+ context.beginPath();
15465
+ context.moveTo(corners[0].x, corners[0].y);
15466
+ context.lineTo(corners[1].x, corners[1].y);
15467
+ context.lineTo(corners[2].x, corners[2].y);
15468
+ context.lineTo(corners[3].x, corners[3].y);
15469
+ context.closePath();
15470
+ context.fillStyle = fillStyle;
15471
+ context.fill();
15472
+ }
15473
+ /**
15474
+ * Interpolates one point inside a projected quad across both quad axes.
15475
+ *
15476
+ * @param corners Quad corners in clockwise order.
15477
+ * @param horizontalRatio Horizontal ratio in the range `[0, 1]`.
15478
+ * @param verticalRatio Vertical ratio in the range `[0, 1]`.
15479
+ * @returns Interpolated projected point.
15480
+ *
15481
+ * @private helper of `minecraft2AvatarVisual`
15482
+ */
15483
+ function interpolateProjectedQuad(corners, horizontalRatio, verticalRatio) {
15484
+ const topPoint = interpolateProjectedPoint(corners[0], corners[1], horizontalRatio);
15485
+ const bottomPoint = interpolateProjectedPoint(corners[3], corners[2], horizontalRatio);
15486
+ return interpolateProjectedPoint(topPoint, bottomPoint, verticalRatio);
15487
+ }
15488
+ /**
15489
+ * Interpolates between two projected points.
15490
+ *
15491
+ * @param startPoint Start point.
15492
+ * @param endPoint End point.
15493
+ * @param ratio Interpolation ratio in the range `[0, 1]`.
15494
+ * @returns Interpolated projected point.
15495
+ *
15496
+ * @private helper of `minecraft2AvatarVisual`
15497
+ */
15498
+ function interpolateProjectedPoint(startPoint, endPoint, ratio) {
15499
+ return {
15500
+ x: startPoint.x + (endPoint.x - startPoint.x) * ratio,
15501
+ y: startPoint.y + (endPoint.y - startPoint.y) * ratio,
15502
+ z: startPoint.z + (endPoint.z - startPoint.z) * ratio,
15503
+ };
15504
+ }
15505
+ /**
15506
+ * Projects one rotated scene point into canvas coordinates.
15507
+ *
15508
+ * @param point Scene point.
15509
+ * @param size Canvas size in CSS pixels.
15510
+ * @param sceneCenterX Horizontal scene center.
15511
+ * @param sceneCenterY Vertical scene center.
15512
+ * @returns Projected point.
15513
+ *
15514
+ * @private helper of `minecraft2AvatarVisual`
15515
+ */
15516
+ function projectScenePoint(point, size, sceneCenterX, sceneCenterY) {
15517
+ const cameraDistance = size * CAMERA_DISTANCE_RATIO;
15518
+ const perspectiveScale = cameraDistance / Math.max(cameraDistance - point.z, cameraDistance * 0.35);
15519
+ return {
15520
+ x: sceneCenterX + point.x * perspectiveScale,
15521
+ y: sceneCenterY + point.y * perspectiveScale,
15522
+ z: point.z,
15523
+ };
15524
+ }
15525
+ /**
15526
+ * Applies the local cuboid rotations and translation to one scene point.
15527
+ *
15528
+ * @param localPoint Point in cuboid-local space.
15529
+ * @param center Cuboid center in scene space.
15530
+ * @param rotationX Cuboid pitch in radians.
15531
+ * @param rotationY Cuboid yaw in radians.
15532
+ * @returns Transformed scene-space point.
15533
+ *
15534
+ * @private helper of `minecraft2AvatarVisual`
15535
+ */
15536
+ function transformScenePoint(localPoint, center, rotationX, rotationY) {
15537
+ const yawedPoint = rotatePointAroundY(localPoint, rotationY);
15538
+ const pitchedPoint = rotatePointAroundX(yawedPoint, rotationX);
15539
+ return {
15540
+ x: center.x + pitchedPoint.x,
15541
+ y: center.y + pitchedPoint.y,
15542
+ z: center.z + pitchedPoint.z,
15543
+ };
15544
+ }
15545
+ /**
15546
+ * Rotates one point around the local Y axis.
15547
+ *
15548
+ * @param point Source point.
15549
+ * @param angle Rotation angle in radians.
15550
+ * @returns Rotated point.
15551
+ *
15552
+ * @private helper of `minecraft2AvatarVisual`
15553
+ */
15554
+ function rotatePointAroundY(point, angle) {
15555
+ const cosine = Math.cos(angle);
15556
+ const sine = Math.sin(angle);
15557
+ return {
15558
+ x: point.x * cosine + point.z * sine,
15559
+ y: point.y,
15560
+ z: -point.x * sine + point.z * cosine,
15561
+ };
15562
+ }
15563
+ /**
15564
+ * Rotates one point around the local X axis.
15565
+ *
15566
+ * @param point Source point.
15567
+ * @param angle Rotation angle in radians.
15568
+ * @returns Rotated point.
15569
+ *
15570
+ * @private helper of `minecraft2AvatarVisual`
15571
+ */
15572
+ function rotatePointAroundX(point, angle) {
15573
+ const cosine = Math.cos(angle);
15574
+ const sine = Math.sin(angle);
15575
+ return {
15576
+ x: point.x,
15577
+ y: point.y * cosine - point.z * sine,
15578
+ z: point.y * sine + point.z * cosine,
15579
+ };
15580
+ }
15581
+ /**
15582
+ * Subtracts one 3D point from another.
15583
+ *
15584
+ * @param leftPoint Left point.
15585
+ * @param rightPoint Right point.
15586
+ * @returns Difference vector.
15587
+ *
15588
+ * @private helper of `minecraft2AvatarVisual`
15589
+ */
15590
+ function subtractPoint3D(leftPoint, rightPoint) {
15591
+ return {
15592
+ x: leftPoint.x - rightPoint.x,
15593
+ y: leftPoint.y - rightPoint.y,
15594
+ z: leftPoint.z - rightPoint.z,
15595
+ };
15596
+ }
15597
+ /**
15598
+ * Computes the 3D cross product of two vectors.
15599
+ *
15600
+ * @param leftVector Left vector.
15601
+ * @param rightVector Right vector.
15602
+ * @returns Cross product.
15603
+ *
15604
+ * @private helper of `minecraft2AvatarVisual`
15605
+ */
15606
+ function crossProduct3D(leftVector, rightVector) {
15607
+ return {
15608
+ x: leftVector.y * rightVector.z - leftVector.z * rightVector.y,
15609
+ y: leftVector.z * rightVector.x - leftVector.x * rightVector.z,
15610
+ z: leftVector.x * rightVector.y - leftVector.y * rightVector.x,
15611
+ };
15612
+ }
15613
+ /**
15614
+ * Computes the 3D dot product of two vectors.
15615
+ *
15616
+ * @param leftVector Left vector.
15617
+ * @param rightVector Right vector.
15618
+ * @returns Dot product.
15619
+ *
15620
+ * @private helper of `minecraft2AvatarVisual`
15621
+ */
15622
+ function dotProduct3D(leftVector, rightVector) {
15623
+ return leftVector.x * rightVector.x + leftVector.y * rightVector.y + leftVector.z * rightVector.z;
15624
+ }
15625
+ /**
15626
+ * Normalizes one 3D vector while keeping zero vectors stable.
15627
+ *
15628
+ * @param vector Source vector.
15629
+ * @returns Normalized vector.
15630
+ *
15631
+ * @private helper of `minecraft2AvatarVisual`
15632
+ */
15633
+ function normalizeVector3(vector) {
15634
+ const length = Math.hypot(vector.x, vector.y, vector.z);
15635
+ if (length === 0) {
15636
+ return vector;
15179
15637
  }
15180
- for (let rowIndex = 2; rowIndex < 8; rowIndex++) {
15181
- texture[rowIndex][3] = stripeColor;
15182
- texture[rowIndex][4] = stripeColor;
15638
+ return {
15639
+ x: vector.x / length,
15640
+ y: vector.y / length,
15641
+ z: vector.z / length,
15642
+ };
15643
+ }
15644
+ /**
15645
+ * Clamps one number into the provided range.
15646
+ *
15647
+ * @param value Input value.
15648
+ * @param minimumValue Inclusive lower bound.
15649
+ * @param maximumValue Inclusive upper bound.
15650
+ * @returns Clamped value.
15651
+ *
15652
+ * @private helper of `minecraft2AvatarVisual`
15653
+ */
15654
+ function clampNumber$1(value, minimumValue, maximumValue) {
15655
+ return Math.min(maximumValue, Math.max(minimumValue, value));
15656
+ }
15657
+ /**
15658
+ * Measures the perimeter of one projected quad.
15659
+ *
15660
+ * @param corners Quad corners.
15661
+ * @returns Perimeter length.
15662
+ *
15663
+ * @private helper of `minecraft2AvatarVisual`
15664
+ */
15665
+ function getProjectedQuadPerimeter(corners) {
15666
+ let perimeter = 0;
15667
+ for (let cornerIndex = 0; cornerIndex < corners.length; cornerIndex++) {
15668
+ const currentCorner = corners[cornerIndex];
15669
+ const nextCorner = corners[(cornerIndex + 1) % corners.length];
15670
+ perimeter += Math.hypot(nextCorner.x - currentCorner.x, nextCorner.y - currentCorner.y);
15183
15671
  }
15184
- texture[4][1] = palette.accent;
15185
- texture[4][6] = palette.accent;
15186
- texture[5][2] = palette.highlight;
15187
- texture[5][5] = palette.highlight;
15188
- return texture;
15672
+ return perimeter;
15189
15673
  }
15190
15674
 
15191
15675
  /* eslint-disable no-magic-numbers */
@@ -16790,6 +17274,7 @@ const AVATAR_VISUALS = [
16790
17274
  octopus3AvatarVisual,
16791
17275
  asciiOctopusAvatarVisual,
16792
17276
  minecraftAvatarVisual,
17277
+ minecraft2AvatarVisual,
16793
17278
  fractalAvatarVisual,
16794
17279
  orbAvatarVisual,
16795
17280
  ];
@@ -18092,7 +18577,11 @@ class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
18092
18577
  // Create new system message with persona at the beginning
18093
18578
  // Format: "You are {agentName}\n{personaContent}"
18094
18579
  // The # PERSONA comment will be removed later by removeCommentsFromSystemMessage
18095
- const personaSection = `# PERSONA\nYou are ${agentName}\n${mergedPersonaContent}`; // <- TODO: Use spaceTrim
18580
+ const personaSection = spaceTrim$1((block) => `
18581
+ # PERSONA
18582
+ You are ${agentName}
18583
+ ${block(mergedPersonaContent)}
18584
+ `);
18096
18585
  const newSystemMessage = cleanedMessage ? `${personaSection}\n\n${cleanedMessage}` : personaSection;
18097
18586
  return {
18098
18587
  ...requirements,
@@ -18994,7 +19483,10 @@ function buildTeamSystemMessageBody(teamEntries) {
18994
19483
  */
18995
19484
  function buildTeamToolDescription(entry) {
18996
19485
  const detailLines = collectTeamEntryDetails(entry).map(({ label, content }) => `${label}: ${content}`);
18997
- return [`Consult teammate ${entry.teammate.label}`, ...detailLines].join('\n');
19486
+ return spaceTrim$1((block) => `
19487
+ Consult teammate ${entry.teammate.label}
19488
+ ${block(detailLines.join('\n'))}
19489
+ `);
18998
19490
  }
18999
19491
  /**
19000
19492
  * Collects structured teammate details that should stay visible to the model.
@@ -24328,7 +24820,10 @@ function createListedTimeoutsAssistantMessage(options) {
24328
24820
  if (hiddenCount > 0) {
24329
24821
  summaryRows.push(`...and ${hiddenCount} more.`);
24330
24822
  }
24331
- return [`Found ${options.total} ${options.total === 1 ? 'timeout' : 'timeouts'}:`, ...summaryRows].join('\n');
24823
+ return spaceTrim$1((block) => `
24824
+ Found ${options.total} ${options.total === 1 ? 'timeout' : 'timeouts'}:
24825
+ ${block(summaryRows.join('\n'))}
24826
+ `);
24332
24827
  }
24333
24828
  /**
24334
24829
  * Formats one timeout row for assistant-visible timeout listings.
@@ -27699,6 +28194,791 @@ const DEFAULT_BOOK = padBook(validateBook(spaceTrim$1(`
27699
28194
  // <- [🐱‍🚀] Buttons into genesis book
27700
28195
  // <- TODO: [🐱‍🚀] generateBookBoilerplate and deprecate `DEFAULT_BOOK`
27701
28196
 
28197
+ /**
28198
+ * Warning message used for unfinished commitments.
28199
+ */
28200
+ const UNFINISHED_COMMITMENT_MESSAGE = 'This commitment is unfinished and not ready to use. Be careful when using it.';
28201
+ /**
28202
+ * Low-level warning message used for low-level commitments.
28203
+ */
28204
+ const LOW_LEVEL_COMMITMENT_MESSAGE = 'This commitment is low-level and not used by most of the users. Be careful when using it.';
28205
+ /**
28206
+ * Short badge text used for deprecated commitments.
28207
+ */
28208
+ const DEPRECATED_COMMITMENT_BADGE_LABEL = 'Deprecated';
28209
+ /**
28210
+ * Short badge text used for unfinished and low-level commitments.
28211
+ */
28212
+ const LOW_LEVEL_COMMITMENT_BADGE_LABEL = 'Low-level';
28213
+ /**
28214
+ * Longer label used for deprecated commitments.
28215
+ */
28216
+ const DEPRECATED_COMMITMENT_DETAIL_LABEL = 'Deprecated commitment';
28217
+ /**
28218
+ * Longer label used for unfinished and low-level commitments.
28219
+ */
28220
+ const LOW_LEVEL_COMMITMENT_DETAIL_LABEL = 'Low-level commitment';
28221
+ /**
28222
+ * Prefix used when formatting replacement guidance.
28223
+ */
28224
+ const PREFERRED_REPLACEMENT_LABEL = 'Preferred replacement';
28225
+ /**
28226
+ * Formats preferred replacement guidance for deprecated commitments.
28227
+ *
28228
+ * @param replacedBy - Preferred replacement commitment keywords.
28229
+ * @returns Optional replacement guidance sentence with leading space.
28230
+ *
28231
+ * @private internal utility of commitment catalog notices
28232
+ */
28233
+ function formatCommitmentReplacementText(replacedBy) {
28234
+ if (!replacedBy || replacedBy.length === 0) {
28235
+ return '';
28236
+ }
28237
+ return ` ${PREFERRED_REPLACEMENT_LABEL}: ${replacedBy.map((type) => `\`${type}\``).join(', ')}.`;
28238
+ }
28239
+ /**
28240
+ * Resolves the notice metadata for deprecated, unfinished, or low-level commitments.
28241
+ *
28242
+ * @param definition - Commitment definition to inspect.
28243
+ * @returns Notice metadata when the commitment should be surfaced with caution.
28244
+ *
28245
+ * @private internal utility of commitment catalog notices
28246
+ */
28247
+ function getCommitmentNoticeMetadata(definition) {
28248
+ if (definition.isUnfinished) {
28249
+ return {
28250
+ kind: 'unfinished',
28251
+ badgeLabel: LOW_LEVEL_COMMITMENT_BADGE_LABEL,
28252
+ detailLabel: LOW_LEVEL_COMMITMENT_DETAIL_LABEL,
28253
+ message: UNFINISHED_COMMITMENT_MESSAGE,
28254
+ };
28255
+ }
28256
+ if (definition.isLowLevel) {
28257
+ return {
28258
+ kind: 'lowLevel',
28259
+ badgeLabel: LOW_LEVEL_COMMITMENT_BADGE_LABEL,
28260
+ detailLabel: LOW_LEVEL_COMMITMENT_DETAIL_LABEL,
28261
+ message: LOW_LEVEL_COMMITMENT_MESSAGE,
28262
+ };
28263
+ }
28264
+ if (definition.deprecation) {
28265
+ return {
28266
+ kind: 'deprecated',
28267
+ badgeLabel: DEPRECATED_COMMITMENT_BADGE_LABEL,
28268
+ detailLabel: DEPRECATED_COMMITMENT_DETAIL_LABEL,
28269
+ message: definition.deprecation.message,
28270
+ };
28271
+ }
28272
+ return null;
28273
+ }
28274
+
28275
+ /**
28276
+ * Common anti-patterns with practical fixes.
28277
+ *
28278
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28279
+ */
28280
+ const bookLanguageCommonPitfalls = [
28281
+ {
28282
+ title: 'Too broad agent scope',
28283
+ dont: 'One agent tries to be a lawyer, developer, marketer, and researcher at once.',
28284
+ doInstead: 'Split into focused agents and orchestrate with TEAM or IMPORT.',
28285
+ },
28286
+ {
28287
+ title: 'Unverifiable claims',
28288
+ dont: 'The agent answers internet-dependent questions without tools or without citing sources.',
28289
+ doInstead: 'Add `USE SEARCH ENGINE` / `USE BROWSER` and a citation-oriented `RULE`.',
28290
+ },
28291
+ {
28292
+ title: 'Missing guardrails',
28293
+ dont: 'Only persona is defined, with no behavioral constraints.',
28294
+ doInstead: 'Add concrete `RULE` commitments for safety, scope, and tone.',
28295
+ },
28296
+ {
28297
+ title: 'Overloaded inheritance',
28298
+ dont: 'Using deep `FROM` chains without documenting why each parent is needed.',
28299
+ doInstead: 'Keep inheritance shallow and use focused IMPORT/TEAM composition for reuse.',
28300
+ },
28301
+ {
28302
+ title: 'Unsafe memory usage',
28303
+ dont: 'Storing every detail in memory without boundaries.',
28304
+ doInstead: 'Pair `MEMORY` with explicit rules about what is allowed to persist.',
28305
+ },
28306
+ ];
28307
+
28308
+ /**
28309
+ * End-to-end examples used by the standalone Book language documentation.
28310
+ *
28311
+ * These are intentionally compact but complete, so they can be copy-pasted and
28312
+ * used as practical starting points.
28313
+ *
28314
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28315
+ */
28316
+ const bookLanguageDocumentationExamples = [
28317
+ {
28318
+ id: 'minimal-hello-world-agent',
28319
+ title: 'Minimal hello-world agent',
28320
+ goal: 'Create the smallest useful agent with identity and greeting.',
28321
+ source: spaceTrim$1(`
28322
+ Hello World Agent
28323
+
28324
+ GOAL Be a concise and friendly assistant.
28325
+ INITIAL MESSAGE Hello! I am ready to help.
28326
+ CLOSED
28327
+ `),
28328
+ walkthrough: [
28329
+ 'The first line (`Hello World Agent`) is the agent name.',
28330
+ '`GOAL` defines the effective role and profile text.',
28331
+ '`INITIAL MESSAGE` sets a deterministic first message for a new chat.',
28332
+ '`CLOSED` prevents conversational self-modification.',
28333
+ ],
28334
+ },
28335
+ {
28336
+ id: 'tool-using-browser-search-agent',
28337
+ title: 'Tool-using agent (Browser + Search engine)',
28338
+ goal: 'Enable internet research with clear sourcing behavior.',
28339
+ source: spaceTrim$1(`
28340
+ Web Research Assistant
28341
+
28342
+ GOAL Research topics using fresh and verifiable information.
28343
+ USE SEARCH ENGINE Prefer official sources and recent publications.
28344
+ USE BROWSER
28345
+ RULE Verify important claims across multiple sources when possible.
28346
+ RULE Include source links in your final answer.
28347
+ INITIAL MESSAGE Ask me what topic you want to research and how deep the report should be.
28348
+ `),
28349
+ walkthrough: [
28350
+ '`USE SEARCH ENGINE` provides web search tooling and optional search instructions.',
28351
+ '`USE BROWSER` enables URL fetching and interactive browsing tools.',
28352
+ '`RULE` commitments make reliability behavior explicit and repeatable.',
28353
+ 'This pattern is ideal for current-events and fact-checking agents.',
28354
+ ],
28355
+ },
28356
+ {
28357
+ id: 'rule-and-knowledge-agent',
28358
+ title: 'Agent with RULE and KNOWLEDGE',
28359
+ goal: 'Ground responses in explicit constraints and curated sources.',
28360
+ source: spaceTrim$1(`
28361
+ Support Policy Assistant
28362
+
28363
+ GOAL Answer questions about support policy.
28364
+ KNOWLEDGE Refunds are available within 30 days with proof of purchase.
28365
+ KNOWLEDGE https://example.com/support-policy
28366
+ RULE If a policy item is missing in available knowledge, say it explicitly.
28367
+ RULE Never invent legal or policy statements.
28368
+ INITIAL MESSAGE I can explain refund and support rules from provided knowledge.
28369
+ `),
28370
+ walkthrough: [
28371
+ '`KNOWLEDGE` may be inline text or an external URL/document.',
28372
+ '`RULE` commitments define non-negotiable behavior constraints.',
28373
+ 'Combining both creates predictable, grounded policy responses.',
28374
+ 'Use this pattern for compliance, support, and internal procedures.',
28375
+ ],
28376
+ },
28377
+ {
28378
+ id: 'memory-agent-with-long-term-memory',
28379
+ title: 'MEMORY agent with long-term memory',
28380
+ goal: 'Persist user preferences across conversations.',
28381
+ source: spaceTrim$1(`
28382
+ Customer Success Memory Agent
28383
+
28384
+ GOAL Support SaaS customers while remembering relevant setup and preference context.
28385
+ MEMORY Remember product setup, user goals, and communication preferences.
28386
+ RULE Store only user-approved preferences and project context.
28387
+ RULE Never store secrets or sensitive data unless explicitly requested and allowed.
28388
+ INITIAL MESSAGE I can remember your setup and preferences for future sessions.
28389
+ `),
28390
+ walkthrough: [
28391
+ '`MEMORY` adds runtime memory tools and memory-specific system guidance.',
28392
+ '`RULE` commitments narrow what should be remembered to reduce privacy risks.',
28393
+ 'In Agents Server, memory is runtime-backed and user-scoped.',
28394
+ 'Use this for assistants that must preserve context over time.',
28395
+ ],
28396
+ },
28397
+ {
28398
+ id: 'use-project-and-wallet-integration-agent',
28399
+ title: 'USE PROJECT and WALLET external integration',
28400
+ goal: 'Work with GitHub repositories and wallet-backed credentials.',
28401
+ source: spaceTrim$1(`
28402
+ Repository Maintainer
28403
+
28404
+ GOAL Maintain a GitHub repository and prepare safe pull requests.
28405
+ USE PROJECT https://github.com/acme/website
28406
+ WALLET Store credentials for repository operations.
28407
+ RULE Before editing files, explain the planned change and impacted paths.
28408
+ RULE Never reveal raw credentials in chat output.
28409
+ INITIAL MESSAGE I can inspect the repository and help you prepare PR-ready changes.
28410
+ `),
28411
+ walkthrough: [
28412
+ '`USE PROJECT` enables repository tools for listing, reading, editing files, and creating PRs.',
28413
+ 'Credentials are resolved from wallet records at runtime in Agents Server.',
28414
+ '`WALLET` is kept here as a compatibility marker, but current Book 2.0 parsing treats it as deprecated/ignored.',
28415
+ 'In current runtime behavior, wallet-backed integrations are driven by commitments such as `USE PROJECT` and `USE EMAIL`.',
28416
+ ],
28417
+ },
28418
+ {
28419
+ id: 'use-calendar-integration-agent',
28420
+ title: 'USE CALENDAR integration',
28421
+ goal: 'Coordinate meetings and schedules through a connected Google Calendar.',
28422
+ source: spaceTrim$1(`
28423
+ Calendar Assistant
28424
+
28425
+ GOAL Schedule meetings and keep the calendar conflict-free.
28426
+ USE CALENDAR https://calendar.google.com/calendar/u/0/r
28427
+ SCOPES https://www.googleapis.com/auth/calendar
28428
+ RULE Confirm destructive actions before deleting an event.
28429
+ INITIAL MESSAGE Tell me the meeting details and I will schedule it in your calendar.
28430
+ `),
28431
+ walkthrough: [
28432
+ '`USE CALENDAR` enables calendar tools for listing, reading, creating, updating, and deleting events.',
28433
+ 'The first calendar URL identifies which calendar integration should be used.',
28434
+ '`SCOPES` can explicitly request required Google Calendar OAuth permissions.',
28435
+ 'Credentials are resolved from wallet-backed Google Calendar OAuth records at runtime in Agents Server.',
28436
+ ],
28437
+ },
28438
+ {
28439
+ id: 'agents-team-example',
28440
+ title: 'Agents TEAM (with in-book teammates)',
28441
+ goal: 'Delegate sub-tasks to specialized teammates.',
28442
+ source: spaceTrim$1(`
28443
+ Team Manager
28444
+
28445
+ GOAL Coordinate specialists and deliver one consolidated answer.
28446
+ TEAM Ask {Legal Reviewer} for legal constraints and {Implementation Reviewer} for technical feasibility.
28447
+ RULE Always summarize teammate outputs into one action plan.
28448
+
28449
+ ---
28450
+
28451
+ Legal Reviewer
28452
+
28453
+ FROM VOID
28454
+ GOAL Review legal and compliance risk.
28455
+ RULE Flag legal/compliance risk and uncertainty clearly.
28456
+ CLOSED
28457
+
28458
+ ---
28459
+
28460
+ Implementation Reviewer
28461
+
28462
+ FROM VOID
28463
+ GOAL Review implementation effort and delivery risk.
28464
+ RULE Estimate complexity and identify blockers.
28465
+ CLOSED
28466
+ `),
28467
+ walkthrough: [
28468
+ 'The main agent delegates via `TEAM` commitment.',
28469
+ 'References in `{...}` are resolved against embedded agents inside the same book (split by `---`).',
28470
+ 'Each teammate can be isolated with `FROM VOID` for deterministic specialization.',
28471
+ 'This pattern works well for multi-role review and decision support.',
28472
+ ],
28473
+ },
28474
+ ];
28475
+
28476
+ /**
28477
+ * Canonical commitment keyword for the open/closed family.
28478
+ *
28479
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28480
+ */
28481
+ const OPEN_COMMITMENT_TYPE = 'OPEN';
28482
+ /**
28483
+ * Canonical commitment keyword for the open/closed family.
28484
+ */
28485
+ const CLOSED_COMMITMENT_TYPE = 'CLOSED';
28486
+ /**
28487
+ * Removes the top-level heading from one commitment documentation block.
28488
+ *
28489
+ * @param markdown - Original markdown source.
28490
+ * @returns Markdown without the first `#` heading.
28491
+ *
28492
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28493
+ */
28494
+ function removeLeadingTopLevelHeading(markdown) {
28495
+ return markdown.replace(/^\s*#\s+[^\n]+\n*/u, '').trim();
28496
+ }
28497
+ /**
28498
+ * Renders one subsection for the combined open/closed documentation family.
28499
+ *
28500
+ * @param title - Heading label for the subsection.
28501
+ * @param documentation - Raw commitment documentation markdown.
28502
+ * @returns Markdown subsection with a `####` heading.
28503
+ *
28504
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28505
+ */
28506
+ function renderDocumentationSection(title, documentation) {
28507
+ return `#### ${title}\n\n${removeLeadingTopLevelHeading(documentation)}`;
28508
+ }
28509
+ /**
28510
+ * Renders the documentation body for one grouped commitment entry.
28511
+ *
28512
+ * `OPEN` and `CLOSED` are intentionally rendered together so the documentation
28513
+ * surfaces present them as one conceptual switch instead of two isolated pages.
28514
+ *
28515
+ * @param group - Grouped commitment metadata.
28516
+ * @returns Markdown body for the docs page/catalog entry.
28517
+ *
28518
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28519
+ */
28520
+ function renderGroupedCommitmentDocumentationMarkdown(group) {
28521
+ const commitmentTypes = new Set([group.primary.type, ...group.aliases]);
28522
+ if (commitmentTypes.has(OPEN_COMMITMENT_TYPE) && commitmentTypes.has(CLOSED_COMMITMENT_TYPE)) {
28523
+ const openCommitmentDefinition = getCommitmentDefinition(OPEN_COMMITMENT_TYPE);
28524
+ const closedCommitmentDefinition = getCommitmentDefinition(CLOSED_COMMITMENT_TYPE);
28525
+ if (openCommitmentDefinition && closedCommitmentDefinition) {
28526
+ return spaceTrim$1((block) => `
28527
+ ${block(renderDocumentationSection(OPEN_COMMITMENT_TYPE, openCommitmentDefinition.documentation))}
28528
+
28529
+ ${block(renderDocumentationSection(CLOSED_COMMITMENT_TYPE, closedCommitmentDefinition.documentation))}
28530
+ `);
28531
+ }
28532
+ }
28533
+ return removeLeadingTopLevelHeading(group.primary.documentation);
28534
+ }
28535
+
28536
+ /**
28537
+ * Commitment types that primarily model composition of multiple agents.
28538
+ *
28539
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28540
+ */
28541
+ const COMPOSITION_COMMITMENT_TYPES = new Set(['FROM', 'IMPORT', 'IMPORTS', 'TEAM']);
28542
+ /**
28543
+ * Commitment types that expose tools/runtime capabilities.
28544
+ *
28545
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28546
+ */
28547
+ const TOOLING_COMMITMENT_TYPES = new Set([
28548
+ 'USE BROWSER',
28549
+ 'USE DEEPSEARCH',
28550
+ 'USE SEARCH ENGINE',
28551
+ 'USE SEARCH',
28552
+ 'USE SPAWN',
28553
+ 'USE EMAIL',
28554
+ 'USE POPUP',
28555
+ 'USE TIME',
28556
+ 'USE USER LOCATION',
28557
+ 'USE PROJECT',
28558
+ 'USE CALENDAR',
28559
+ 'USE IMAGE GENERATOR',
28560
+ 'USE MCP',
28561
+ 'USE PRIVACY',
28562
+ 'MEMORY',
28563
+ 'MEMORIES',
28564
+ ]);
28565
+ /**
28566
+ * Commitment types that primarily define agent profile metadata.
28567
+ *
28568
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28569
+ */
28570
+ const PROFILE_COMMITMENT_TYPES = new Set([
28571
+ 'GOAL',
28572
+ 'GOALS',
28573
+ 'PERSONA',
28574
+ 'PERSONAE',
28575
+ 'META',
28576
+ 'META AVATAR',
28577
+ 'META IMAGE',
28578
+ 'META LINK',
28579
+ 'META DOMAIN',
28580
+ 'META DESCRIPTION',
28581
+ 'META DISCLAIMER',
28582
+ 'META INPUT PLACEHOLDER',
28583
+ 'META COLOR',
28584
+ 'META FONT',
28585
+ 'META VOICE',
28586
+ 'INITIAL MESSAGE',
28587
+ 'MODEL',
28588
+ 'MODELS',
28589
+ ]);
28590
+ /**
28591
+ * Commitment types that primarily define behavioral constraints or prompt shaping.
28592
+ *
28593
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28594
+ */
28595
+ const BEHAVIOR_COMMITMENT_TYPES = new Set([
28596
+ 'RULE',
28597
+ 'RULES',
28598
+ 'KNOWLEDGE',
28599
+ 'GOAL',
28600
+ 'GOALS',
28601
+ 'STYLE',
28602
+ 'STYLES',
28603
+ 'LANGUAGE',
28604
+ 'LANGUAGES',
28605
+ 'FORMAT',
28606
+ 'FORMATS',
28607
+ 'TEMPLATE',
28608
+ 'TEMPLATES',
28609
+ 'WRITING SAMPLE',
28610
+ 'WRITING RULES',
28611
+ 'SAMPLE',
28612
+ 'EXAMPLE',
28613
+ 'SCENARIO',
28614
+ 'SCENARIOS',
28615
+ 'MESSAGE',
28616
+ 'MESSAGES',
28617
+ 'MESSAGE SUFFIX',
28618
+ 'USER MESSAGE',
28619
+ 'AGENT MESSAGE',
28620
+ 'INTERNAL MESSAGE',
28621
+ 'OPEN',
28622
+ 'CLOSED',
28623
+ ]);
28624
+ /**
28625
+ * Creates one standalone markdown guide for Book language (Book 2.0 / agent language).
28626
+ *
28627
+ * The output intentionally combines:
28628
+ * - static conceptual building blocks maintained in this repository
28629
+ * - dynamically generated commitment catalog from runtime commitment definitions
28630
+ * so docs stay up-to-date by design.
28631
+ *
28632
+ * @returns Full standalone markdown document.
28633
+ *
28634
+ * @public exported from `@promptbook/core`
28635
+ */
28636
+ function createStandaloneBookLanguageMarkdown() {
28637
+ const groupedCommitments = getGroupedCommitmentDefinitions();
28638
+ const generatedAtIso = new Date().toISOString();
28639
+ const placeholderCommitmentCount = groupedCommitments.filter(({ primary }) => primary instanceof NotYetImplementedCommitmentDefinition).length;
28640
+ const implementedCommitmentCount = groupedCommitments.length - placeholderCommitmentCount;
28641
+ const allCommitmentKeywords = groupedCommitments.flatMap(({ primary, aliases }) => [primary.type, ...aliases]);
28642
+ const toolingCommitments = groupedCommitments.filter(({ primary }) => TOOLING_COMMITMENT_TYPES.has(primary.type));
28643
+ const profileCommitments = groupedCommitments.filter(({ primary }) => PROFILE_COMMITMENT_TYPES.has(primary.type));
28644
+ const compositionCommitments = groupedCommitments.filter(({ primary }) => COMPOSITION_COMMITMENT_TYPES.has(primary.type));
28645
+ const behaviorCommitments = groupedCommitments.filter(({ primary }) => BEHAVIOR_COMMITMENT_TYPES.has(primary.type));
28646
+ return spaceTrim$1(
28647
+ // [✨]
28648
+ (block) => `
28649
+ # Book Language blueprint
28650
+
28651
+ > Canonical standalone guide for Promptbook Book Agent language.
28652
+ > Generated from repository https://github.com/webgptorg/promptbook
28653
+
28654
+ - Book language version: \`${BOOK_LANGUAGE_VERSION}\`
28655
+ - Generated at: \`${generatedAtIso}\`
28656
+ - Commitment groups: \`${groupedCommitments.length}\`
28657
+ - Implemented commitments: \`${implementedCommitmentCount}\`
28658
+ - Placeholder commitments: \`${placeholderCommitmentCount}\`
28659
+
28660
+ ## <a id="table-of-contents"></a>Table of Contents
28661
+
28662
+ - [What Book language is](#what-book-language-is)
28663
+ - [Execution and compilation model](#execution-and-compilation-model)
28664
+ - [Mental model of an agent](#mental-model-of-an-agent)
28665
+ - [How to structure good agents](#how-to-structure-good-agents)
28666
+ - [Primitives and constructs reference](#primitives-and-constructs-reference)
28667
+ - [Commitment catalog (all commitments)](#commitment-catalog-all-commitments)
28668
+ - [End-to-end examples](#end-to-end-examples)
28669
+ - [Do nots and common pitfalls](#do-nots-and-common-pitfalls)
28670
+ - [Build an agent from scratch (offline tutorial)](#build-an-agent-from-scratch-offline-tutorial)
28671
+
28672
+ ## <a id="what-book-language-is"></a>What Book language is
28673
+
28674
+ Book language is a domain-specific language for defining **AI agents** as plain-text source.
28675
+ It solves these problems:
28676
+
28677
+ - **One editable source of truth** for agent behavior, tools, memory, and profile metadata.
28678
+ - **Composable agent architecture** through commitments like \`FROM\`, \`IMPORT\`, and \`TEAM\`.
28679
+ - **Deterministic runtime preparation** where source is parsed and compiled into model requirements.
28680
+ - **Portable agent definitions** that can be copied, versioned, and reviewed as text.
28681
+
28682
+ In this repository, "Book language" means **Book 2.0 agent language**.
28683
+
28684
+ ## <a id="execution-and-compilation-model"></a>Execution and compilation model
28685
+
28686
+ Promptbook and Agents Server use two core passes:
28687
+
28688
+ 1. **Fast parse pass** (\`parseAgentSource\`):
28689
+ It synchronously extracts agent profile/basic info (name, last goal/profile text, meta, capabilities, samples, references).
28690
+ 2. **Compilation pass** (\`createAgentModelRequirements\`):
28691
+ It applies commitments in sequence and builds executable model requirements (system message, tools, memory/tool metadata, imports, etc.).
28692
+
28693
+ In Agents Server, the runtime flow typically includes:
28694
+
28695
+ 1. Resolve scoped references (including in-book references like \`{Some Agent}\`).
28696
+ 2. Resolve inheritance/import chains into effective source.
28697
+ 3. Compile effective source into model requirements.
28698
+ 4. Execute chat turns with resolved tools and runtime adapters.
28699
+
28700
+ ## <a id="mental-model-of-an-agent"></a>Mental model of an agent
28701
+
28702
+ Think of one agent source as four layers:
28703
+
28704
+ 1. **Identity/Profile layer**:
28705
+ Agent name (first non-commitment line), the last \`GOAL\` (preferred) or deprecated \`PERSONA\`, and \`META*\` commitments.
28706
+ 2. **Behavior layer**:
28707
+ \`RULE\`, \`KNOWLEDGE\`, \`WRITING SAMPLE\`, \`WRITING RULES\`, deprecated \`STYLE\`, \`FORMAT\`, \`TEMPLATE\`, \`LANGUAGE\`, \`GOAL\`, and related commitments.
28708
+ 3. **Capability layer**:
28709
+ \`USE*\`, \`MEMORY\`, and other tooling commitments exposing runtime abilities.
28710
+ 4. **Composition layer**:
28711
+ \`FROM\` inheritance, \`IMPORT\` reuse, and \`TEAM\` delegation.
28712
+
28713
+ Agent composition commitments in current runtime:
28714
+
28715
+ - Profile-centric commitments detected: ${profileCommitments
28716
+ .map(({ primary }) => `\`${primary.type}\``)
28717
+ .join(', ')}
28718
+ - Behavior-centric commitments detected: ${behaviorCommitments
28719
+ .map(({ primary }) => `\`${primary.type}\``)
28720
+ .join(', ')}
28721
+ - Tool/runtime commitments detected: ${toolingCommitments
28722
+ .map(({ primary }) => `\`${primary.type}\``)
28723
+ .join(', ')}
28724
+ - Composition commitments detected: ${compositionCommitments
28725
+ .map(({ primary }) => `\`${primary.type}\``)
28726
+ .join(', ')}
28727
+
28728
+ ### META commitments and agent profile
28729
+
28730
+ \`META*\` commitments control profile data shown in UI (for example avatar visual, image, description, disclaimers, domain, input placeholder).
28731
+ They generally shape presentation/metadata rather than tool behavior.
28732
+
28733
+ ### FROM inheritance
28734
+
28735
+ \`FROM\` points to a parent agent source. During inheritance resolution:
28736
+
28737
+ - Parent corpus is merged into effective source.
28738
+ - \`FROM {Void}\` / \`FROM VOID\` means explicit "no parent".
28739
+ - Missing references are surfaced as notes in resolved source.
28740
+
28741
+ ### TEAM and IMPORT
28742
+
28743
+ - \`TEAM\` registers teammate agents as callable tools.
28744
+ - \`IMPORT\` injects imported agent/file content into current agent context.
28745
+ - In Agents Server, compact references like \`{Legal Reviewer}\` can resolve to embedded in-book agents.
28746
+
28747
+ ### USE commitments
28748
+
28749
+ \`USE*\` commitments enable capabilities (search, browser, project integration, email, image generation, etc.).
28750
+ They expose runtime tools and system-message guidance used during execution.
28751
+
28752
+ ## <a id="how-to-structure-good-agents"></a>How to structure good agents
28753
+
28754
+ Recommended patterns and tradeoffs:
28755
+
28756
+ 1. **Single clear role first**:
28757
+ Start with one narrow \`GOAL\`; use \`PERSONA\` only for backward-compatible legacy books.
28758
+ Tradeoff: less initial flexibility, much higher reliability.
28759
+ 2. **Guardrails early**:
28760
+ Add concrete \`RULE\` commitments before adding many tools.
28761
+ Tradeoff: more upfront design, fewer runtime surprises.
28762
+ 3. **Grounding over improvisation**:
28763
+ Prefer \`KNOWLEDGE\` + explicit citation rule for high-stakes answers.
28764
+ Tradeoff: extra maintenance for sources, better factual control.
28765
+ 4. **Composition over monoliths**:
28766
+ Use \`TEAM\`/\`IMPORT\` for specialized responsibilities.
28767
+ Tradeoff: orchestration overhead, stronger modularity and reuse.
28768
+ 5. **Controlled memory**:
28769
+ If using \`MEMORY\`, define what must and must not be remembered.
28770
+ Tradeoff: stricter policy design, better privacy and signal quality.
28771
+
28772
+ ## <a id="primitives-and-constructs-reference"></a>Primitives and constructs reference
28773
+
28774
+ ### Core syntax primitives
28775
+
28776
+ 1. **Agent title**:
28777
+ First non-empty line that is not a commitment keyword.
28778
+ 2. **Commitment block**:
28779
+ Starts with a commitment keyword and continues until the next commitment block or separator.
28780
+ 3. **Horizontal separator**:
28781
+ Lines like \`---\` split sections; in Agents Server they can delimit embedded in-book agents.
28782
+ 4. **Code fences**:
28783
+ Preserved inside commitment content; useful for examples/instructions.
28784
+ 5. **Parameters**:
28785
+ Both \`@parameter\` and \`{parameter}\` notations are supported and parsed.
28786
+
28787
+ ### Reference tokens and pseudo-agents
28788
+
28789
+ - Compact references like \`{Agent Name}\` are resolved by Agents Server reference resolver.
28790
+ - Pseudo-agent forms (for example \`{User}\`, \`{Void}\`) are supported in relevant commitments.
28791
+ - \`{User}\` is intended for \`TEAM\`; \`{Void}\` is useful for explicit no-parent inheritance.
28792
+
28793
+ ### Commitment keywords currently recognized
28794
+
28795
+ ${block(getSafeCodeBlock(allCommitmentKeywords.join(', '), 'text'))}
28796
+
28797
+ ## <a id="commitment-catalog-all-commitments"></a>Commitment catalog (all commitments)
28798
+
28799
+ This section is generated from commitment definitions in \`src/commitments\`.
28800
+ For each commitment group you get:
28801
+
28802
+ - semantics summary (description/icon/status)
28803
+ - parsing schema (\`createTypeRegex\` and \`createRegex\`)
28804
+ - canonical documentation block
28805
+
28806
+ ${block(groupedCommitments.map(renderCommitmentCatalogSection).join('\n\n'))}
28807
+
28808
+ ## <a id="end-to-end-examples"></a>End-to-end examples
28809
+
28810
+ ${block(bookLanguageDocumentationExamples.map(renderExampleSection).join('\n\n'))}
28811
+
28812
+ ## <a id="do-nots-and-common-pitfalls"></a>Do nots and common pitfalls
28813
+
28814
+ ${block(bookLanguageCommonPitfalls
28815
+ .map((pitfall, index) => spaceTrim$1(`
28816
+ ${index + 1}. **${pitfall.title}**
28817
+ - Don't: ${pitfall.dont}
28818
+ - Do instead: ${pitfall.doInstead}
28819
+ `))
28820
+ .join('\n'))}
28821
+
28822
+ ## <a id="build-an-agent-from-scratch-offline-tutorial"></a>Build an agent from scratch (offline tutorial)
28823
+
28824
+ This tutorial is sufficient without internet access.
28825
+
28826
+ 1. **Define role and goal**
28827
+ Create a short name line and one clear \`GOAL\`.
28828
+ 2. **Add behavioral constraints**
28829
+ Add 3-6 specific \`RULE\` commitments covering scope, tone, and safety boundaries.
28830
+ 3. **Add grounding**
28831
+ Add \`KNOWLEDGE\` commitments (inline text or local/importable sources).
28832
+ 4. **Add capabilities**
28833
+ Add only necessary \`USE*\` and/or \`MEMORY\` commitments.
28834
+ 5. **Set profile metadata**
28835
+ Add \`META DESCRIPTION\`, \`META AVATAR\` or \`META IMAGE\`, \`META INPUT PLACEHOLDER\`, and disclaimers if needed.
28836
+ 6. **Add first interaction**
28837
+ Add \`INITIAL MESSAGE\` and optionally sample \`USER MESSAGE\` / \`AGENT MESSAGE\` pairs.
28838
+ 7. **Close for deterministic behavior (optional)**
28839
+ Add \`CLOSED\` when you want stable non-self-modifying behavior.
28840
+
28841
+ Copy-paste template:
28842
+
28843
+ ${block(getSafeCodeBlock(spaceTrim$1(`
28844
+ Project Assistant
28845
+
28846
+ GOAL Help the user turn project ideas into concrete deliverables with focused planning support.
28847
+
28848
+ RULE Ask clarifying questions when requirements are ambiguous.
28849
+ RULE Provide concise, structured outputs with actionable steps.
28850
+ RULE If information is missing, state assumptions explicitly.
28851
+ RULE Do not invent facts.
28852
+
28853
+ KNOWLEDGE Team works in two-week sprints and tracks tasks in Kanban.
28854
+ KNOWLEDGE Preferred output format: summary, plan, risks, next action.
28855
+
28856
+ META DESCRIPTION Practical project-planning assistant.
28857
+ META INPUT PLACEHOLDER Describe your project goal or blocker...
28858
+
28859
+ INITIAL MESSAGE Share your project goal and current blocker, and I will propose a concrete next-step plan.
28860
+ CLOSED
28861
+ `), 'book'))}
28862
+
28863
+ Validation checklist:
28864
+
28865
+ - Does each commitment have a clear purpose?
28866
+ - Are there explicit constraints against hallucination and unsafe behavior?
28867
+ - Are tools only enabled when genuinely needed?
28868
+ - Is memory usage bounded by clear rules?
28869
+ - Is composition (\`FROM\`/\`TEAM\`/\`IMPORT\`) justified and understandable?
28870
+
28871
+ ---
28872
+
28873
+ Generated from:
28874
+
28875
+ - Commitments registry and runtime docs in \`src/commitments\`
28876
+ - Parser/compiler behavior in \`src/book-2.0/agent-source\`
28877
+ - Agents Server reference/inheritance resolution in \`apps/agents-server/src/utils\`
28878
+ - Standalone docs source blocks in \`apps/agents-server/src/utils/bookLanguageDocumentation\`
28879
+ `);
28880
+ }
28881
+ /**
28882
+ * Renders one commitment section in the generated catalog.
28883
+ *
28884
+ * @param groupedCommitment - Grouped commitment definition with aliases.
28885
+ * @returns Markdown section for a single commitment.
28886
+ *
28887
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28888
+ */
28889
+ function renderCommitmentCatalogSection(groupedCommitment) {
28890
+ var _a;
28891
+ const { primary, aliases } = groupedCommitment;
28892
+ const notice = getCommitmentNoticeMetadata(primary);
28893
+ const status = primary instanceof NotYetImplementedCommitmentDefinition
28894
+ ? 'Placeholder (not fully implemented)'
28895
+ : notice
28896
+ ? `Implemented (${notice.detailLabel})`
28897
+ : 'Implemented';
28898
+ const aliasText = aliases.length === 0 ? 'None' : aliases.map((alias) => `\`${alias}\``).join(', ');
28899
+ const noticeText = notice
28900
+ ? notice.kind === 'deprecated'
28901
+ ? `- **Deprecation:** ${notice.message}${formatCommitmentReplacementText((_a = primary.deprecation) === null || _a === void 0 ? void 0 : _a.replacedBy)}`
28902
+ : `- **Low-level commitment:** ${notice.message}`
28903
+ : '';
28904
+ const documentationMarkdown = renderGroupedCommitmentDocumentationMarkdown(groupedCommitment);
28905
+ return spaceTrim$1((block) => `
28906
+ ### <a id="commitment-${toStableAnchorId(primary.type)}"></a>${primary.icon} ${primary.type}
28907
+
28908
+ - **Status:** ${status}
28909
+ - **Aliases:** ${aliasText}
28910
+ - **Semantics:** ${primary.description}
28911
+ - **Type schema (\`createTypeRegex\`):** \`${stringifyRegex(primary.createTypeRegex())}\`
28912
+ - **Block schema (\`createRegex\`):** \`${stringifyRegex(primary.createRegex())}\`
28913
+ ${noticeText}
28914
+
28915
+ ${block(documentationMarkdown)}
28916
+ `);
28917
+ }
28918
+ /**
28919
+ * Renders one end-to-end example section.
28920
+ *
28921
+ * @param example - Example definition.
28922
+ * @returns Markdown section for one example.
28923
+ *
28924
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28925
+ */
28926
+ function renderExampleSection(example) {
28927
+ return spaceTrim$1((block) => `
28928
+ ### <a id="example-${toStableAnchorId(example.id)}"></a>${example.title}
28929
+
28930
+ **Goal:** ${example.goal}
28931
+
28932
+ **Full source**
28933
+
28934
+ ${block(getSafeCodeBlock(example.source, 'book'))}
28935
+
28936
+ **Walkthrough**
28937
+
28938
+ ${block(example.walkthrough.map((step, index) => `${index + 1}. ${step}`).join('\n'))}
28939
+ `);
28940
+ }
28941
+ /**
28942
+ * Converts a heading label into a stable markdown anchor id.
28943
+ *
28944
+ * @param value - Raw heading/identifier text.
28945
+ * @returns Stable lowercase anchor id.
28946
+ *
28947
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28948
+ */
28949
+ function toStableAnchorId(value) {
28950
+ return value
28951
+ .trim()
28952
+ .toLowerCase()
28953
+ .replace(/[^a-z0-9]+/g, '-')
28954
+ .replace(/^-+|-+$/g, '');
28955
+ }
28956
+ /**
28957
+ * Converts a regular expression into a concise literal-like string.
28958
+ *
28959
+ * @param regex - Regex instance.
28960
+ * @returns Printable regex pattern and flags.
28961
+ *
28962
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28963
+ */
28964
+ function stringifyRegex(regex) {
28965
+ return `/${regex.source}/${regex.flags}`;
28966
+ }
28967
+ /**
28968
+ * Creates a safe markdown fenced code block even when content contains backticks.
28969
+ *
28970
+ * @param content - Raw code content.
28971
+ * @param language - Optional info-string language label.
28972
+ * @returns Fenced code block.
28973
+ *
28974
+ * @private internal utility of `createStandaloneBookLanguageMarkdown`
28975
+ */
28976
+ function getSafeCodeBlock(content, language = 'markdown') {
28977
+ const maxBacktickCount = Math.max(0, ...(content.match(/`+/g) || []).map((match) => match.length));
28978
+ const fence = '`'.repeat(Math.max(3, maxBacktickCount + 1));
28979
+ return `${fence}${language}\n${content}\n${fence}`;
28980
+ }
28981
+
27702
28982
  /**
27703
28983
  * Generates an image for the agent to use as profile image
27704
28984
  *
@@ -29706,8 +30986,10 @@ const ImageGeneratorFormfactorDefinition = {
29706
30986
  */
29707
30987
  const MatcherFormfactorDefinition = {
29708
30988
  name: 'EXPERIMENTAL_MATCHER',
29709
- description: `An evaluation system that determines whether content meets specific criteria or patterns.
29710
- Used for content validation, quality assessment, and intelligent filtering tasks. Currently in experimental phase.`,
30989
+ description: spaceTrim$1(`
30990
+ An evaluation system that determines whether content meets specific criteria or patterns.
30991
+ Used for content validation, quality assessment, and intelligent filtering tasks. Currently in experimental phase.
30992
+ `),
29711
30993
  documentationUrl: `https://github.com/webgptorg/promptbook/discussions/177`,
29712
30994
  pipelineInterface: {
29713
30995
  inputParameters: [
@@ -29764,9 +31046,11 @@ const SheetsFormfactorDefinition = {
29764
31046
  */
29765
31047
  const TranslatorFormfactorDefinition = {
29766
31048
  name: 'TRANSLATOR',
29767
- description: `A text transformation system that converts input content into different forms,
29768
- including language translations, paraphrasing, style conversions, and tone adjustments.
29769
- This form factor takes one input and produces one transformed output.`,
31049
+ description: spaceTrim$1(`
31050
+ A text transformation system that converts input content into different forms,
31051
+ including language translations, paraphrasing, style conversions, and tone adjustments.
31052
+ This form factor takes one input and produces one transformed output.
31053
+ `),
29770
31054
  documentationUrl: `https://github.com/webgptorg/promptbook/discussions/175`,
29771
31055
  pipelineInterface: {
29772
31056
  inputParameters: [
@@ -31126,12 +32410,21 @@ const QuickChatbotHla = {
31126
32410
  // <- TODO: [🧠] Make this dynamic, async, prepare-phase HLAs
31127
32411
  ],
31128
32412
  });
31129
- // TODO: Use spaceTrim in multiline strings
31130
32413
  $pipelineJson.tasks.push({
31131
32414
  taskType: 'PROMPT_TASK',
31132
32415
  name: 'create-an-answer',
31133
32416
  title: 'Create an answer',
31134
- content: 'Write a response to the user message:\n\n**Question from user**\n\n> {userMessage}\n\n**Previous conversation**\n\n> {previousConversationSummary}',
32417
+ content: spaceTrim$1(`
32418
+ Write a response to the user message:
32419
+
32420
+ **Question from user**
32421
+
32422
+ > {userMessage}
32423
+
32424
+ **Previous conversation**
32425
+
32426
+ > {previousConversationSummary}
32427
+ `),
31135
32428
  resultingParameterName: 'chatbotResponse',
31136
32429
  personaName,
31137
32430
  dependentParameterNames: [
@@ -31143,7 +32436,26 @@ const QuickChatbotHla = {
31143
32436
  taskType: 'PROMPT_TASK',
31144
32437
  name: 'summarize-the-conversation',
31145
32438
  title: 'Summarize the conversation',
31146
- content: 'Summarize the conversation in a few words:\n\n## Rules\n\n- Summarise the text of the conversation in a few words\n- Convert the text to its basic idea\n- Imagine you are writing the headline or subject line of an email\n- Respond with a few words of summary only\n\n## Conversation\n\n**User:**\n\n> {userMessage}\n\n**You:**\n\n> {chatbotResponse}',
32439
+ content: spaceTrim$1(`
32440
+ Summarize the conversation in a few words:
32441
+
32442
+ ## Rules
32443
+
32444
+ - Summarise the text of the conversation in a few words
32445
+ - Convert the text to its basic idea
32446
+ - Imagine you are writing the headline or subject line of an email
32447
+ - Respond with a few words of summary only
32448
+
32449
+ ## Conversation
32450
+
32451
+ **User:**
32452
+
32453
+ > {userMessage}
32454
+
32455
+ **You:**
32456
+
32457
+ > {chatbotResponse}
32458
+ `),
31147
32459
  resultingParameterName: 'conversationSummary',
31148
32460
  personaName,
31149
32461
  expectations: {
@@ -33547,11 +34859,11 @@ function formatChatAttachmentContext(attachments) {
33547
34859
  if (attachments.length === 0) {
33548
34860
  return '';
33549
34861
  }
33550
- return [
33551
- CHAT_ATTACHMENTS_HEADING,
33552
- ...attachments.map((attachment) => formatChatAttachmentLine(attachment)),
33553
- CHAT_ATTACHMENTS_INSTRUCTION,
33554
- ].join('\n');
34862
+ return spaceTrim$1((block) => `
34863
+ ${CHAT_ATTACHMENTS_HEADING}
34864
+ ${block(attachments.map((attachment) => formatChatAttachmentLine(attachment)).join('\n'))}
34865
+ ${CHAT_ATTACHMENTS_INSTRUCTION}
34866
+ `);
33555
34867
  }
33556
34868
 
33557
34869
  /**
@@ -33792,24 +35104,24 @@ function formatResolvedChatAttachmentContent(contentResolution) {
33792
35104
  : ''}`
33793
35105
  : null;
33794
35106
  const warningsLine = contentResolution.warnings.length > 0 ? `Warnings: ${contentResolution.warnings.join(' | ')}` : null;
33795
- if (!contentResolution.content) {
35107
+ const metadataLines = [decodingLine, warningsLine].filter((line) => Boolean(line)).join('\n');
35108
+ const resolvedContent = contentResolution.content;
35109
+ if (!resolvedContent) {
33796
35110
  const reason = contentResolution.reason || 'content unavailable';
33797
- return [`- ${attachmentLabel}: ${reason}. URL: ${contentResolution.attachment.url}`, decodingLine, warningsLine]
33798
- .filter(Boolean)
33799
- .join('\n');
35111
+ return spaceTrim$1((block) => `
35112
+ - ${attachmentLabel}: ${reason}. URL: ${contentResolution.attachment.url}
35113
+ ${block(metadataLines)}
35114
+ `);
33800
35115
  }
33801
35116
  const truncatedLabel = contentResolution.isTruncated ? ' [truncated]' : '';
33802
- return [
33803
- `File: ${attachmentLabel}${truncatedLabel}`,
33804
- `URL: ${contentResolution.attachment.url}`,
33805
- decodingLine,
33806
- warningsLine,
33807
- '```text',
33808
- contentResolution.content,
33809
- '```',
33810
- ]
33811
- .filter(Boolean)
33812
- .join('\n');
35117
+ return spaceTrim$1((block) => `
35118
+ File: ${attachmentLabel}${truncatedLabel}
35119
+ URL: ${contentResolution.attachment.url}
35120
+ ${block(metadataLines)}
35121
+ \`\`\`text
35122
+ ${block(resolvedContent)}
35123
+ \`\`\`
35124
+ `);
33813
35125
  }
33814
35126
  /**
33815
35127
  * Formats inline attachment-content context section for the model.
@@ -33823,11 +35135,14 @@ function formatChatAttachmentContentContext(resolvedContents) {
33823
35135
  if (resolvedContents.length === 0) {
33824
35136
  return '';
33825
35137
  }
33826
- return [
33827
- CHAT_ATTACHMENT_CONTENT_HEADING,
33828
- CHAT_ATTACHMENT_CONTENT_INSTRUCTION,
33829
- ...resolvedContents.map((resolvedContent) => formatResolvedChatAttachmentContent(resolvedContent)),
33830
- ].join('\n\n');
35138
+ return spaceTrim$1((block) => `
35139
+ ${CHAT_ATTACHMENT_CONTENT_HEADING}
35140
+ ${CHAT_ATTACHMENT_CONTENT_INSTRUCTION}
35141
+
35142
+ ${block(resolvedContents
35143
+ .map((resolvedContent) => formatResolvedChatAttachmentContent(resolvedContent))
35144
+ .join('\n\n'))}
35145
+ `);
33831
35146
  }
33832
35147
 
33833
35148
  /**
@@ -34986,9 +36301,11 @@ class OpenAiCompatibleUnsupportedParameterRetrier {
34986
36301
  * Creates the retry-history error message shared by all OpenAI-compatible model variants.
34987
36302
  */
34988
36303
  createAttemptHistoryError(finalErrorMessage) {
34989
- return new PipelineExecutionError(`All attempts failed. Attempt history:\n` +
34990
- formatUnsupportedParameterAttemptHistory(this.attemptStack) +
34991
- `\nFinal error: ${finalErrorMessage}`);
36304
+ return new PipelineExecutionError(spaceTrim$1((block) => `
36305
+ All attempts failed. Attempt history:
36306
+ ${block(formatUnsupportedParameterAttemptHistory(this.attemptStack))}
36307
+ Final error: ${finalErrorMessage}
36308
+ `));
34992
36309
  }
34993
36310
  }
34994
36311
 
@@ -37582,7 +38899,7 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
37582
38899
  });
37583
38900
  }
37584
38901
  let vectorStoreId = cachedVectorStoreId;
37585
- if (this.isNativeKnowledgeSearchEnabled && !vectorStoreId && knowledgeSources && knowledgeSources.length > 0) {
38902
+ if (!vectorStoreId && knowledgeSources && knowledgeSources.length > 0) {
37586
38903
  const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({
37587
38904
  client: await this.getClient(),
37588
38905
  name,
@@ -37591,19 +38908,13 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
37591
38908
  });
37592
38909
  vectorStoreId = vectorStoreResult.vectorStoreId;
37593
38910
  }
37594
- else if (this.isNativeKnowledgeSearchEnabled && vectorStoreId && this.options.isVerbose) {
38911
+ else if (vectorStoreId && this.options.isVerbose) {
37595
38912
  console.info('[🤰]', 'Using cached vector store for AgentKit agent', {
37596
38913
  name,
37597
38914
  vectorStoreId,
37598
38915
  });
37599
38916
  }
37600
- if (!this.isNativeKnowledgeSearchEnabled) {
37601
- vectorStoreId = undefined;
37602
- }
37603
- const agentKitTools = this.buildAgentKitTools({
37604
- tools,
37605
- vectorStoreId,
37606
- });
38917
+ const agentKitTools = this.buildAgentKitTools({ tools, vectorStoreId });
37607
38918
  const openAiAgentKitAgent = new Agent$1({
37608
38919
  name,
37609
38920
  model: this.agentKitModelName,
@@ -37622,7 +38933,7 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
37622
38933
  name,
37623
38934
  model: this.agentKitModelName,
37624
38935
  toolCount: agentKitTools.length,
37625
- hasVectorStore: this.isNativeKnowledgeSearchEnabled && Boolean(vectorStoreId),
38936
+ hasVectorStore: Boolean(vectorStoreId),
37626
38937
  });
37627
38938
  }
37628
38939
  return preparedAgent;
@@ -38121,12 +39432,6 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
38121
39432
  get agentKitOptions() {
38122
39433
  return this.options;
38123
39434
  }
38124
- /**
38125
- * Returns true when hosted OpenAI vector-store search should back `knowledgeSources`.
38126
- */
38127
- get isNativeKnowledgeSearchEnabled() {
38128
- return this.agentKitOptions.isNativeKnowledgeSearchEnabled !== false;
38129
- }
38130
39435
  /**
38131
39436
  * Discriminant for type guards.
38132
39437
  */
@@ -42650,7 +43955,7 @@ const SDK_TRANSPILER_KNOWLEDGE_THRESHOLD = 1000;
42650
43955
  */
42651
43956
  async function prepareSdkTranspilerContext(book, options) {
42652
43957
  const { agentName } = await parseAgentSource(book);
42653
- const rawModelRequirements = await createAgentModelRequirements(book, undefined, undefined, undefined, {
43958
+ const modelRequirements = await createAgentModelRequirements(book, undefined, undefined, undefined, {
42654
43959
  agentReferenceResolver: options === null || options === void 0 ? void 0 : options.agentReferenceResolver,
42655
43960
  inlineKnowledgeSourceUploader: options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader,
42656
43961
  teammateProfileResolver: options === null || options === void 0 ? void 0 : options.teammateProfileResolver,
@@ -42660,12 +43965,7 @@ async function prepareSdkTranspilerContext(book, options) {
42660
43965
  const knowledgeContent = knowledgeCommitments.map((commitment) => commitment.content.trim());
42661
43966
  const directKnowledge = knowledgeContent.filter((content) => !isKnowledgeSourceUrl(content));
42662
43967
  const knowledgeSources = knowledgeContent.filter((content) => isKnowledgeSourceUrl(content));
42663
- const isKnowledgeHandledWithRetrieval = directKnowledge.join('\n').length > SDK_TRANSPILER_KNOWLEDGE_THRESHOLD ||
42664
- knowledgeSources.length > 0 ||
42665
- knowledgeCommitments.length > 0;
42666
- const modelRequirements = normalizeSdkTranspilerModelRequirements(rawModelRequirements, {
42667
- isKnowledgeHandledWithRetrieval,
42668
- });
43968
+ const isKnowledgeHandledWithRetrieval = directKnowledge.join('\n').length > SDK_TRANSPILER_KNOWLEDGE_THRESHOLD || knowledgeSources.length > 0;
42669
43969
  const transpiledTeam = createTranspiledTeamExportForContext({
42670
43970
  agentName,
42671
43971
  agentSource: book,
@@ -42683,36 +43983,6 @@ async function prepareSdkTranspilerContext(book, options) {
42683
43983
  transpiledTeam,
42684
43984
  };
42685
43985
  }
42686
- /**
42687
- * Removes the runtime-only knowledge-search tool from SDK harnesses that provide
42688
- * their own generated retrieval scaffold.
42689
- *
42690
- * @param modelRequirements - Raw compiled model requirements.
42691
- * @param options - Knowledge handling mode selected for the generated harness.
42692
- * @returns Model requirements safe to embed into a standalone SDK export.
42693
- */
42694
- function normalizeSdkTranspilerModelRequirements(modelRequirements, options) {
42695
- var _a;
42696
- if (!options.isKnowledgeHandledWithRetrieval) {
42697
- return modelRequirements;
42698
- }
42699
- const tools = (_a = modelRequirements.tools) === null || _a === void 0 ? void 0 : _a.filter((tool) => tool.name !== KNOWLEDGE_SEARCH_TOOL_NAME);
42700
- return {
42701
- ...modelRequirements,
42702
- systemMessage: removeKnowledgeSearchSystemSection(modelRequirements.systemMessage),
42703
- ...(tools ? { tools } : {}),
42704
- };
42705
- }
42706
- /**
42707
- * Removes the generated `## Knowledge Search` instructions from SDK exports
42708
- * that answer with the transpiler's native retrieval scaffold instead.
42709
- *
42710
- * @param systemMessage - Raw system message from compiled model requirements.
42711
- * @returns System message without the runtime-only knowledge-search section.
42712
- */
42713
- function removeKnowledgeSearchSystemSection(systemMessage) {
42714
- return systemMessage.replace(/(?:^|\n\n)## Knowledge Search[\s\S]*?(?=\n\n##|$)/, '').trim();
42715
- }
42716
43986
  /**
42717
43987
  * Detects whether one knowledge commitment points to a URL instead of inline text.
42718
43988
  *
@@ -45383,5 +46653,5 @@ function $generateBookBoilerplate(options) {
45383
46653
  }
45384
46654
  // TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
45385
46655
 
45386
- export { $bookTranspilersRegister, $generateBookBoilerplate, $llmToolsMetadataRegister, $llmToolsRegister, $scrapersMetadataRegister, $scrapersRegister, ADMIN_EMAIL, ADMIN_GITHUB_NAME, API_REQUEST_TIMEOUT, AbstractFormatError, Agent, AgentCollectionInSupabase, AgentLlmExecutionTools, AgentOsTranspiler, AnthropicClaudeManagedTranspiler, AnthropicClaudeSdkTranspiler, AuthenticationError, BIG_DATASET_TRESHOLD, BOOK_LANGUAGE_VERSION, BlackholeStorage, BoilerplateError, BoilerplateFormfactorDefinition, CLAIM, CLI_APP_ID, COLOR_CONSTANTS, CORE_AGENTS_SERVER, CORE_AGENTS_SERVER_WELL_KNOWN_AGENT_NAMES, CallbackInterfaceTools, ChatbotFormfactorDefinition, CollectionError, CompletionFormfactorDefinition, ConflictError, CsvFormatError, CsvFormatParser, DEFAULT_AGENTS_DIRNAME, 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_CONCURRENT_UPLOADS, 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_RECURSION, 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, DatabaseError, E2BTranspiler, EXPECTATION_UNITS, EnvironmentMismatchError, ExecutionReportStringOptionsDefaults, ExpectError, FAILED_VALUE_PLACEHOLDER, FORMFACTOR_DEFINITIONS, FormattedBookInMarkdownTranspiler, GENERIC_PIPELINE_INTERFACE, GeneratorFormfactorDefinition, GenericFormfactorDefinition, HTTP_STATUS_CODES, ImageGeneratorFormfactorDefinition, KNOWLEDGE_SEARCH_TOOL_NAME, KnowledgeScrapeError, LIMITS, LimitReachedError, MANDATORY_CSV_SETTINGS, MAX_FILENAME_LENGTH, MODEL_ORDERS, MODEL_TRUST_LEVELS, MODEL_VARIANTS, MatcherFormfactorDefinition, MemoryStorage, MissingToolsError, MultipleLlmExecutionTools, NAME, NETWORK_LIMITS, NonTaskSectionTypes, NotAllowed, NotFoundError, NotYetImplementedCommitmentDefinition, NotYetImplementedError, ORDER_OF_PIPELINE_JSON, OpenAiAgentsTranspiler, OpenAiSdkTranspiler, PADDING_LINES, PENDING_VALUE_PLACEHOLDER, PLAYGROUND_APP_ID, PROMPTBOOK_CHAT_COLOR, PROMPTBOOK_COLOR, PROMPTBOOK_ENGINE_VERSION, PROMPTBOOK_ERRORS, PROMPTBOOK_LEGAL_ENTITY, PROMPTBOOK_LOGO_URL, PROMPTBOOK_SYNTAX_COLORS, PROMPT_PARAMETER_SELF_LEARNING_ENABLED, PUBLIC_AGENTS_SERVERS, ParseError, PipelineExecutionError, PipelineLogicError, PipelineUrlError, PrefixStorage, PromptbookFetchError, RESERVED_PARAMETER_NAMES, RemoteAgent, SET_IS_VERBOSE, SectionTypes, SheetsFormfactorDefinition, TIME_INTERVALS, TaskTypes, TextFormatParser, TranslatorFormfactorDefinition, UNCERTAIN_USAGE, UNCERTAIN_ZERO_VALUE, USER_CHAT_COLOR, UnexpectedError, VirusTotalFileSecurityChecker, WrappedError, ZERO_USAGE, ZERO_VALUE, _AgentMetadata, _AgentRegistration, _AnthropicClaudeMetadataRegistration, _AzureOpenAiMetadataRegistration, _BoilerplateScraperMetadataRegistration, _DeepseekMetadataRegistration, _DocumentScraperMetadataRegistration, _GoogleMetadataRegistration, _LegacyDocumentScraperMetadataRegistration, _MarkdownScraperMetadataRegistration, _MarkitdownScraperMetadataRegistration, _OllamaMetadataRegistration, _OpenAiAssistantMetadataRegistration, _OpenAiCompatibleMetadataRegistration, _OpenAiMetadataRegistration, _PdfScraperMetadataRegistration, _WebsiteScraperMetadataRegistration, aboutPromptbookInformation, addUsage, appendChatAttachmentContext, appendChatAttachmentContextWithContent, book, cacheLlmTools, compilePipeline, computeAgentHash, computeCosineSimilarity, countUsage, createAgentLlmExecutionTools, createAgentModelRequirements, createBasicAgentModelRequirements, createDefaultAgentName, createEmptyAgentModelRequirements, createLlmToolsFromConfiguration, createPipelineCollectionFromJson, createPipelineCollectionFromPromise, createPipelineCollectionFromUrl, createPipelineExecutor, createPipelineSubcollection, embeddingVectorToString, executionReportJsonToString, extractParameterNamesFromTask, filterModels, formatChatAttachmentContentContext, formatChatAttachmentContext, generatePlaceholderAgentProfileImageUrl, getAllCommitmentDefinitions, getAllCommitmentTypes, getAllCommitmentsToolTitles, getCommitmentDefinition, getGroupedCommitmentDefinitions, getPipelineInterface, getSingleLlmExecutionTools, identificationToPromptbookToken, isCommitmentSupported, isPassingExpectations, isPipelineImplementingInterface, isPipelineInterfacesEqual, isPipelinePrepared, isValidBook, isValidPipelineString, joinLlmExecutionTools, limitTotalUsage, makeKnowledgeSourceHandler, migratePipeline, normalizeAgentName, normalizeChatAttachments, padBook, parseAgentSource, parseParameters, parsePipeline, pipelineCollectionToJson, pipelineJsonToString, prepareKnowledgePieces, preparePersona, preparePipeline, prettifyPipelineString, promptbookFetch, promptbookTokenToIdentification, resolveChatAttachmentContents, unpreparePipeline, usageToHuman, usageToWorktime, validateBook, validatePipeline, validatePipelineString };
46656
+ export { $bookTranspilersRegister, $generateBookBoilerplate, $llmToolsMetadataRegister, $llmToolsRegister, $scrapersMetadataRegister, $scrapersRegister, ADMIN_EMAIL, ADMIN_GITHUB_NAME, API_REQUEST_TIMEOUT, AbstractFormatError, Agent, AgentCollectionInSupabase, AgentLlmExecutionTools, AgentOsTranspiler, AnthropicClaudeManagedTranspiler, AnthropicClaudeSdkTranspiler, AuthenticationError, BIG_DATASET_TRESHOLD, BOOK_LANGUAGE_VERSION, BlackholeStorage, BoilerplateError, BoilerplateFormfactorDefinition, CLAIM, CLI_APP_ID, COLOR_CONSTANTS, CORE_AGENTS_SERVER, CORE_AGENTS_SERVER_WELL_KNOWN_AGENT_NAMES, CallbackInterfaceTools, ChatbotFormfactorDefinition, CollectionError, CompletionFormfactorDefinition, ConflictError, CsvFormatError, CsvFormatParser, DEFAULT_AGENTS_DIRNAME, 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_CONCURRENT_UPLOADS, 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_RECURSION, 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, DatabaseError, E2BTranspiler, EXPECTATION_UNITS, EnvironmentMismatchError, ExecutionReportStringOptionsDefaults, ExpectError, FAILED_VALUE_PLACEHOLDER, FORMFACTOR_DEFINITIONS, FormattedBookInMarkdownTranspiler, GENERIC_PIPELINE_INTERFACE, GeneratorFormfactorDefinition, GenericFormfactorDefinition, HTTP_STATUS_CODES, ImageGeneratorFormfactorDefinition, KnowledgeScrapeError, LIMITS, LimitReachedError, MANDATORY_CSV_SETTINGS, MAX_FILENAME_LENGTH, MODEL_ORDERS, MODEL_TRUST_LEVELS, MODEL_VARIANTS, MatcherFormfactorDefinition, MemoryStorage, MissingToolsError, MultipleLlmExecutionTools, NAME, NETWORK_LIMITS, NonTaskSectionTypes, NotAllowed, NotFoundError, NotYetImplementedCommitmentDefinition, NotYetImplementedError, ORDER_OF_PIPELINE_JSON, OpenAiAgentsTranspiler, OpenAiSdkTranspiler, PADDING_LINES, PENDING_VALUE_PLACEHOLDER, PLAYGROUND_APP_ID, PROMPTBOOK_CHAT_COLOR, PROMPTBOOK_COLOR, PROMPTBOOK_ENGINE_VERSION, PROMPTBOOK_ERRORS, PROMPTBOOK_LEGAL_ENTITY, PROMPTBOOK_LOGO_URL, PROMPTBOOK_SYNTAX_COLORS, PROMPT_PARAMETER_SELF_LEARNING_ENABLED, PUBLIC_AGENTS_SERVERS, ParseError, PipelineExecutionError, PipelineLogicError, PipelineUrlError, PrefixStorage, PromptbookFetchError, RESERVED_PARAMETER_NAMES, RemoteAgent, SET_IS_VERBOSE, SectionTypes, SheetsFormfactorDefinition, TIME_INTERVALS, TaskTypes, TextFormatParser, TranslatorFormfactorDefinition, UNCERTAIN_USAGE, UNCERTAIN_ZERO_VALUE, USER_CHAT_COLOR, UnexpectedError, VirusTotalFileSecurityChecker, WrappedError, ZERO_USAGE, ZERO_VALUE, _AgentMetadata, _AgentRegistration, _AnthropicClaudeMetadataRegistration, _AzureOpenAiMetadataRegistration, _BoilerplateScraperMetadataRegistration, _DeepseekMetadataRegistration, _DocumentScraperMetadataRegistration, _GoogleMetadataRegistration, _LegacyDocumentScraperMetadataRegistration, _MarkdownScraperMetadataRegistration, _MarkitdownScraperMetadataRegistration, _OllamaMetadataRegistration, _OpenAiAssistantMetadataRegistration, _OpenAiCompatibleMetadataRegistration, _OpenAiMetadataRegistration, _PdfScraperMetadataRegistration, _WebsiteScraperMetadataRegistration, aboutPromptbookInformation, addUsage, appendChatAttachmentContext, appendChatAttachmentContextWithContent, book, cacheLlmTools, compilePipeline, computeAgentHash, computeCosineSimilarity, countUsage, createAgentLlmExecutionTools, createAgentModelRequirements, createBasicAgentModelRequirements, createDefaultAgentName, createEmptyAgentModelRequirements, createLlmToolsFromConfiguration, createPipelineCollectionFromJson, createPipelineCollectionFromPromise, createPipelineCollectionFromUrl, createPipelineExecutor, createPipelineSubcollection, createStandaloneBookLanguageMarkdown, embeddingVectorToString, executionReportJsonToString, extractParameterNamesFromTask, filterModels, formatChatAttachmentContentContext, formatChatAttachmentContext, generatePlaceholderAgentProfileImageUrl, getAllCommitmentDefinitions, getAllCommitmentTypes, getAllCommitmentsToolTitles, getCommitmentDefinition, getGroupedCommitmentDefinitions, getPipelineInterface, getSingleLlmExecutionTools, identificationToPromptbookToken, isCommitmentSupported, isPassingExpectations, isPipelineImplementingInterface, isPipelineInterfacesEqual, isPipelinePrepared, isValidBook, isValidPipelineString, joinLlmExecutionTools, limitTotalUsage, makeKnowledgeSourceHandler, migratePipeline, normalizeAgentName, normalizeChatAttachments, padBook, parseAgentSource, parseParameters, parsePipeline, pipelineCollectionToJson, pipelineJsonToString, prepareKnowledgePieces, preparePersona, preparePipeline, prettifyPipelineString, promptbookFetch, promptbookTokenToIdentification, resolveChatAttachmentContents, unpreparePipeline, usageToHuman, usageToWorktime, validateBook, validatePipeline, validatePipelineString };
45387
46657
  //# sourceMappingURL=index.es.js.map