@promptbook/node 0.105.0-6 → 0.105.0-8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esm/index.es.js CHANGED
@@ -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.105.0-6';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.105.0-8';
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
@@ -11830,6 +11830,16 @@ function unwrapResult(text, options) {
11830
11830
  trimmedText = spaceTrim$1(trimmedText);
11831
11831
  }
11832
11832
  let processedText = trimmedText;
11833
+ // Check for markdown code block
11834
+ const codeBlockRegex = /^```[a-z]*\n([\s\S]*?)\n```\s*$/;
11835
+ const codeBlockMatch = processedText.match(codeBlockRegex);
11836
+ if (codeBlockMatch && codeBlockMatch[1] !== undefined) {
11837
+ // Check if there's only one code block
11838
+ const codeBlockCount = (processedText.match(/```/g) || []).length / 2;
11839
+ if (codeBlockCount === 1) {
11840
+ return unwrapResult(codeBlockMatch[1], { isTrimmed: false, isIntroduceSentenceRemoved: false });
11841
+ }
11842
+ }
11833
11843
  if (isIntroduceSentenceRemoved) {
11834
11844
  const introduceSentenceRegex = /^[a-zěščřžýáíéúů:\s]*:\s*/i;
11835
11845
  if (introduceSentenceRegex.test(text)) {
@@ -11837,6 +11847,14 @@ function unwrapResult(text, options) {
11837
11847
  processedText = processedText.replace(introduceSentenceRegex, '');
11838
11848
  }
11839
11849
  processedText = spaceTrim$1(processedText);
11850
+ // Check again for code block after removing introduce sentence
11851
+ const codeBlockMatch2 = processedText.match(codeBlockRegex);
11852
+ if (codeBlockMatch2 && codeBlockMatch2[1] !== undefined) {
11853
+ const codeBlockCount = (processedText.match(/```/g) || []).length / 2;
11854
+ if (codeBlockCount === 1) {
11855
+ return unwrapResult(codeBlockMatch2[1], { isTrimmed: false, isIntroduceSentenceRemoved: false });
11856
+ }
11857
+ }
11840
11858
  }
11841
11859
  if (processedText.length < 3) {
11842
11860
  return trimmedText;
@@ -15236,6 +15254,46 @@ class UseMcpCommitmentDefinition extends BaseCommitmentDefinition {
15236
15254
  * Note: [💞] Ignore a discrepancy between file name and entity name
15237
15255
  */
15238
15256
 
15257
+ /**
15258
+ * A search engine implementation that uses the SerpApi to fetch Google search results.
15259
+ *
15260
+ * @private <- TODO: !!!! Export via some package
15261
+ */
15262
+ class SerpSearchEngine {
15263
+ get title() {
15264
+ return 'SerpApi Search Engine';
15265
+ }
15266
+ get description() {
15267
+ return 'Search engine that uses SerpApi to fetch Google search results';
15268
+ }
15269
+ checkConfiguration() {
15270
+ if (!process.env.SERP_API_KEY) {
15271
+ throw new Error('SERP_API_KEY is not configured');
15272
+ }
15273
+ }
15274
+ async search(query) {
15275
+ const apiKey = process.env.SERP_API_KEY;
15276
+ if (!apiKey) {
15277
+ throw new Error('SERP_API_KEY is not configured');
15278
+ }
15279
+ const url = new URL('https://serpapi.com/search');
15280
+ url.searchParams.set('q', query);
15281
+ url.searchParams.set('api_key', apiKey);
15282
+ url.searchParams.set('engine', 'google');
15283
+ const response = await fetch(url.toString());
15284
+ if (!response.ok) {
15285
+ const body = await response.text();
15286
+ throw new Error(`SerpApi failed with status ${response.status}: ${response.statusText}\n${body}`);
15287
+ }
15288
+ const data = (await response.json());
15289
+ return (data.organic_results || []).map((item) => ({
15290
+ title: item.title,
15291
+ url: item.link,
15292
+ snippet: item.snippet || '',
15293
+ }));
15294
+ }
15295
+ }
15296
+
15239
15297
  /**
15240
15298
  * USE SEARCH ENGINE commitment definition
15241
15299
  *
@@ -15312,18 +15370,13 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
15312
15370
  ? existingTools
15313
15371
  : [
15314
15372
  ...existingTools,
15315
- { type: 'web_search' },
15316
- // <- Note: [🔰] This is just using simple native search tool by OpenAI @see https://platform.openai.com/docs/guides/tools-web-search
15317
- // In future we will use proper MCP search tool:
15318
- /*
15319
-
15320
15373
  {
15321
15374
  name: 'web_search',
15322
- description: spaceTrim(`
15323
- Search the internet for information.
15324
- Use this tool when you need to find up-to-date information or facts that you don't know.
15325
- ${!content ? '' : `Search scope / instructions: ${content}`}
15326
- `),
15375
+ description: spaceTrim$1(`
15376
+ Search the internet for information.
15377
+ Use this tool when you need to find up-to-date information or facts that you don't know.
15378
+ ${!content ? '' : `Search scope / instructions: ${content}`}
15379
+ `),
15327
15380
  parameters: {
15328
15381
  type: 'object',
15329
15382
  properties: {
@@ -15335,7 +15388,6 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
15335
15388
  required: ['query'],
15336
15389
  },
15337
15390
  },
15338
- */
15339
15391
  ];
15340
15392
  // Return requirements with updated tools and metadata
15341
15393
  return {
@@ -15347,6 +15399,33 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
15347
15399
  },
15348
15400
  };
15349
15401
  }
15402
+ /**
15403
+ * Gets the `web_search` tool function implementation.
15404
+ */
15405
+ getToolFunctions() {
15406
+ return {
15407
+ async web_search(args) {
15408
+ console.log('!!!! [Tool] web_search called', { args });
15409
+ const { query } = args;
15410
+ if (!query) {
15411
+ throw new Error('Search query is required');
15412
+ }
15413
+ const searchEngine = new SerpSearchEngine();
15414
+ const results = await searchEngine.search(query);
15415
+ return spaceTrim$1((block) => `
15416
+ Search results for "${query}":
15417
+
15418
+ ${block(results
15419
+ .map((result) => spaceTrim$1(`
15420
+ - **${result.title}**
15421
+ ${result.url}
15422
+ ${result.snippet}
15423
+ `))
15424
+ .join('\n\n'))}
15425
+ `);
15426
+ },
15427
+ };
15428
+ }
15350
15429
  }
15351
15430
  /**
15352
15431
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -15590,6 +15669,7 @@ const COMMITMENT_REGISTRY = [
15590
15669
  new NoteCommitmentDefinition('NOTES'),
15591
15670
  new NoteCommitmentDefinition('COMMENT'),
15592
15671
  new NoteCommitmentDefinition('NONCE'),
15672
+ new NoteCommitmentDefinition('TODO'),
15593
15673
  new GoalCommitmentDefinition('GOAL'),
15594
15674
  new GoalCommitmentDefinition('GOALS'),
15595
15675
  new InitialMessageCommitmentDefinition(),