@promptbook/wizard 0.112.0-12 → 0.112.0-15
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 +714 -2522
- package/esm/index.es.js.map +1 -1
- package/esm/src/cli/cli-commands/coder/{find-fresh-emoji-tag.d.ts → find-fresh-emoji-tags.d.ts} +1 -1
- package/esm/src/cli/cli-commands/coder.d.ts +1 -1
- package/esm/src/commitments/USE_BROWSER/resolveRunBrowserToolForNode.d.ts +1 -1
- package/esm/src/commitments/USE_TIMEOUT/TimeoutToolNames.d.ts +1 -0
- package/esm/src/commitments/USE_TIMEOUT/TimeoutToolRuntimeAdapter.d.ts +51 -2
- package/esm/src/commitments/USE_TIMEOUT/USE_TIMEOUT.d.ts +2 -2
- package/esm/src/commitments/USE_TIMEOUT/getTimeoutToolRuntimeAdapterOrDisabledResult.d.ts +2 -2
- package/esm/src/commitments/USE_TIMEOUT/parseTimeoutToolArgs.d.ts +14 -1
- package/esm/src/execution/createPipelineExecutor/30-executeFormatSubvalues.d.ts +1 -1
- package/esm/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
- package/esm/src/llm-providers/deepseek/deepseek-models.d.ts +1 -1
- package/esm/src/llm-providers/google/google-models.d.ts +1 -1
- package/esm/src/llm-providers/openai/openai-models.d.ts +1 -1
- package/esm/src/scrapers/_boilerplate/BoilerplateScraper.d.ts +1 -2
- package/esm/src/scrapers/document/DocumentScraper.d.ts +1 -2
- package/esm/src/scrapers/document-legacy/LegacyDocumentScraper.d.ts +1 -2
- package/esm/src/scripting/javascript/postprocessing-functions.d.ts +1 -1
- package/esm/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +1 -2
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -3
- package/umd/index.umd.js +950 -2755
- package/umd/index.umd.js.map +1 -1
- package/umd/src/cli/cli-commands/coder/{find-fresh-emoji-tag.d.ts → find-fresh-emoji-tags.d.ts} +1 -1
- package/umd/src/cli/cli-commands/coder.d.ts +1 -1
- package/umd/src/commitments/USE_BROWSER/resolveRunBrowserToolForNode.d.ts +1 -1
- package/umd/src/commitments/USE_TIMEOUT/TimeoutToolNames.d.ts +1 -0
- package/umd/src/commitments/USE_TIMEOUT/TimeoutToolRuntimeAdapter.d.ts +51 -2
- package/umd/src/commitments/USE_TIMEOUT/USE_TIMEOUT.d.ts +2 -2
- package/umd/src/commitments/USE_TIMEOUT/getTimeoutToolRuntimeAdapterOrDisabledResult.d.ts +2 -2
- package/umd/src/commitments/USE_TIMEOUT/parseTimeoutToolArgs.d.ts +14 -1
- package/umd/src/execution/createPipelineExecutor/30-executeFormatSubvalues.d.ts +1 -1
- package/umd/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
- package/umd/src/llm-providers/deepseek/deepseek-models.d.ts +1 -1
- package/umd/src/llm-providers/google/google-models.d.ts +1 -1
- package/umd/src/llm-providers/openai/openai-models.d.ts +1 -1
- package/umd/src/scrapers/_boilerplate/BoilerplateScraper.d.ts +1 -2
- package/umd/src/scrapers/document/DocumentScraper.d.ts +1 -2
- package/umd/src/scrapers/document-legacy/LegacyDocumentScraper.d.ts +1 -2
- package/umd/src/scripting/javascript/postprocessing-functions.d.ts +1 -1
- package/umd/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +1 -2
- package/umd/src/version.d.ts +1 -1
- package/esm/apps/agents-server/config.d.ts +0 -86
- package/esm/apps/agents-server/src/tools/$provideBrowserForServer.d.ts +0 -28
- package/esm/apps/agents-server/src/tools/BrowserConnectionProvider.d.ts +0 -142
- package/esm/apps/agents-server/src/tools/runBrowserArtifacts.d.ts +0 -25
- package/esm/apps/agents-server/src/tools/runBrowserConstants.d.ts +0 -21
- package/esm/apps/agents-server/src/tools/runBrowserErrorHandling.d.ts +0 -60
- package/esm/apps/agents-server/src/tools/runBrowserErrors.d.ts +0 -73
- package/esm/apps/agents-server/src/tools/runBrowserObservability.d.ts +0 -36
- package/esm/apps/agents-server/src/tools/runBrowserResultFormatting.d.ts +0 -47
- package/esm/apps/agents-server/src/tools/runBrowserRuntime.d.ts +0 -24
- package/esm/apps/agents-server/src/tools/runBrowserWorkflow.d.ts +0 -36
- package/esm/apps/agents-server/src/tools/run_browser.d.ts +0 -11
- package/esm/apps/agents-server/src/utils/retryWithBackoff.d.ts +0 -95
- package/esm/apps/agents-server/src/utils/runBrowserArtifactStorage.d.ts +0 -26
- package/umd/apps/agents-server/config.d.ts +0 -86
- package/umd/apps/agents-server/src/tools/$provideBrowserForServer.d.ts +0 -28
- package/umd/apps/agents-server/src/tools/BrowserConnectionProvider.d.ts +0 -142
- package/umd/apps/agents-server/src/tools/runBrowserArtifacts.d.ts +0 -25
- package/umd/apps/agents-server/src/tools/runBrowserConstants.d.ts +0 -21
- package/umd/apps/agents-server/src/tools/runBrowserErrorHandling.d.ts +0 -60
- package/umd/apps/agents-server/src/tools/runBrowserErrors.d.ts +0 -73
- package/umd/apps/agents-server/src/tools/runBrowserObservability.d.ts +0 -36
- package/umd/apps/agents-server/src/tools/runBrowserResultFormatting.d.ts +0 -47
- package/umd/apps/agents-server/src/tools/runBrowserRuntime.d.ts +0 -24
- package/umd/apps/agents-server/src/tools/runBrowserWorkflow.d.ts +0 -36
- package/umd/apps/agents-server/src/tools/run_browser.d.ts +0 -11
- package/umd/apps/agents-server/src/utils/retryWithBackoff.d.ts +0 -95
- package/umd/apps/agents-server/src/utils/runBrowserArtifactStorage.d.ts +0 -26
package/esm/index.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { io } from 'socket.io-client';
|
|
2
|
-
import
|
|
2
|
+
import _spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
|
|
3
3
|
import Anthropic from '@anthropic-ai/sdk';
|
|
4
4
|
import Bottleneck from 'bottleneck';
|
|
5
5
|
import colors from 'colors';
|
|
@@ -13,10 +13,7 @@ import { basename, join, dirname, isAbsolute, relative } from 'path';
|
|
|
13
13
|
import { Readability } from '@mozilla/readability';
|
|
14
14
|
import { JSDOM } from 'jsdom';
|
|
15
15
|
import { Converter } from 'showdown';
|
|
16
|
-
import { randomBytes
|
|
17
|
-
import { tmpdir } from 'os';
|
|
18
|
-
import { ConfigChecker } from 'configchecker';
|
|
19
|
-
import { chromium } from 'playwright';
|
|
16
|
+
import { randomBytes } from 'crypto';
|
|
20
17
|
import * as dotenv from 'dotenv';
|
|
21
18
|
import sha256 from 'crypto-js/sha256';
|
|
22
19
|
import JSZip from 'jszip';
|
|
@@ -41,7 +38,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
41
38
|
* @generated
|
|
42
39
|
* @see https://github.com/webgptorg/promptbook
|
|
43
40
|
*/
|
|
44
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
41
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-15';
|
|
45
42
|
/**
|
|
46
43
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
47
44
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -1309,7 +1306,7 @@ function $deepFreeze(objectValue) {
|
|
|
1309
1306
|
function getErrorReportUrl(error) {
|
|
1310
1307
|
const report = {
|
|
1311
1308
|
title: `🐜 Error report from ${NAME}`,
|
|
1312
|
-
body: spaceTrim$
|
|
1309
|
+
body: spaceTrim$1((block) => `
|
|
1313
1310
|
|
|
1314
1311
|
|
|
1315
1312
|
\`${error.name || 'Error'}\` has occurred in the [${NAME}], please look into it @${ADMIN_GITHUB_NAME}.
|
|
@@ -1467,7 +1464,7 @@ function checkSerializableAsJson(options) {
|
|
|
1467
1464
|
}
|
|
1468
1465
|
else if (typeof value === 'object') {
|
|
1469
1466
|
if (value instanceof Date) {
|
|
1470
|
-
throw new UnexpectedError(spaceTrim$
|
|
1467
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1471
1468
|
\`${name}\` is Date
|
|
1472
1469
|
|
|
1473
1470
|
Use \`string_date_iso8601\` instead
|
|
@@ -1486,7 +1483,7 @@ function checkSerializableAsJson(options) {
|
|
|
1486
1483
|
throw new UnexpectedError(`${name} is RegExp`);
|
|
1487
1484
|
}
|
|
1488
1485
|
else if (value instanceof Error) {
|
|
1489
|
-
throw new UnexpectedError(spaceTrim$
|
|
1486
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1490
1487
|
\`${name}\` is unserialized Error
|
|
1491
1488
|
|
|
1492
1489
|
Use function \`serializeError\`
|
|
@@ -1509,7 +1506,7 @@ function checkSerializableAsJson(options) {
|
|
|
1509
1506
|
}
|
|
1510
1507
|
catch (error) {
|
|
1511
1508
|
assertsError(error);
|
|
1512
|
-
throw new UnexpectedError(spaceTrim$
|
|
1509
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1513
1510
|
\`${name}\` is not serializable
|
|
1514
1511
|
|
|
1515
1512
|
${block(error.stack || error.message)}
|
|
@@ -1541,7 +1538,7 @@ function checkSerializableAsJson(options) {
|
|
|
1541
1538
|
}
|
|
1542
1539
|
}
|
|
1543
1540
|
else {
|
|
1544
|
-
throw new UnexpectedError(spaceTrim$
|
|
1541
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1545
1542
|
\`${name}\` is unknown type
|
|
1546
1543
|
|
|
1547
1544
|
Additional message for \`${name}\`:
|
|
@@ -2331,7 +2328,7 @@ function deserializeError(error, isStackAddedToMessage = true) {
|
|
|
2331
2328
|
message = `${name}: ${message}`;
|
|
2332
2329
|
}
|
|
2333
2330
|
if (isStackAddedToMessage && stack !== undefined && stack !== '') {
|
|
2334
|
-
message = spaceTrim$
|
|
2331
|
+
message = spaceTrim$1((block) => `
|
|
2335
2332
|
${block(message)}
|
|
2336
2333
|
|
|
2337
2334
|
Original stack trace:
|
|
@@ -2389,7 +2386,7 @@ async function createRemoteClient(options) {
|
|
|
2389
2386
|
const remoteServerUrlParsed = new URL(remoteServerUrl);
|
|
2390
2387
|
if (remoteServerUrlParsed.pathname !== '/' && remoteServerUrlParsed.pathname !== '') {
|
|
2391
2388
|
remoteServerUrlParsed.pathname = '/';
|
|
2392
|
-
throw new Error(spaceTrim$
|
|
2389
|
+
throw new Error(spaceTrim$1((block) => `
|
|
2393
2390
|
Remote server requires root url \`/\`
|
|
2394
2391
|
|
|
2395
2392
|
You have provided \`remoteServerUrl\`:
|
|
@@ -2826,7 +2823,7 @@ function pricing(value) {
|
|
|
2826
2823
|
/**
|
|
2827
2824
|
* List of available Anthropic Claude models with pricing
|
|
2828
2825
|
*
|
|
2829
|
-
* Note: Synced with official API docs at
|
|
2826
|
+
* Note: Synced with official API docs at 2026-03-22
|
|
2830
2827
|
*
|
|
2831
2828
|
* @see https://docs.anthropic.com/en/docs/models-overview
|
|
2832
2829
|
* @public exported from `@promptbook/anthropic-claude`
|
|
@@ -2834,6 +2831,26 @@ function pricing(value) {
|
|
|
2834
2831
|
const ANTHROPIC_CLAUDE_MODELS = exportJson({
|
|
2835
2832
|
name: 'ANTHROPIC_CLAUDE_MODELS',
|
|
2836
2833
|
value: [
|
|
2834
|
+
{
|
|
2835
|
+
modelVariant: 'CHAT',
|
|
2836
|
+
modelTitle: 'Claude Opus 4.6',
|
|
2837
|
+
modelName: 'claude-opus-4-6',
|
|
2838
|
+
modelDescription: "Anthropic's most capable model for advanced coding, complex reasoning, and agentic workflows with 1M token context window.",
|
|
2839
|
+
pricing: {
|
|
2840
|
+
prompt: pricing(`$5.00 / 1M tokens`),
|
|
2841
|
+
output: pricing(`$25.00 / 1M tokens`),
|
|
2842
|
+
},
|
|
2843
|
+
},
|
|
2844
|
+
{
|
|
2845
|
+
modelVariant: 'CHAT',
|
|
2846
|
+
modelTitle: 'Claude Sonnet 4.6',
|
|
2847
|
+
modelName: 'claude-sonnet-4-6',
|
|
2848
|
+
modelDescription: 'Best speed and intelligence balance for production-ready workloads with 1M token context window. Ideal for high-performance, lower-latency applications.',
|
|
2849
|
+
pricing: {
|
|
2850
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
2851
|
+
output: pricing(`$15.00 / 1M tokens`),
|
|
2852
|
+
},
|
|
2853
|
+
},
|
|
2837
2854
|
{
|
|
2838
2855
|
modelVariant: 'CHAT',
|
|
2839
2856
|
modelTitle: 'Claude Sonnet 4.5',
|
|
@@ -3622,7 +3639,7 @@ class AnthropicClaudeExecutionTools {
|
|
|
3622
3639
|
getDefaultModel(defaultModelName) {
|
|
3623
3640
|
const model = ANTHROPIC_CLAUDE_MODELS.find(({ modelName }) => modelName.startsWith(defaultModelName));
|
|
3624
3641
|
if (model === undefined) {
|
|
3625
|
-
throw new UnexpectedError(spaceTrim$
|
|
3642
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
3626
3643
|
Cannot find model in Anthropic Claude models with name "${defaultModelName}" which should be used as default.
|
|
3627
3644
|
|
|
3628
3645
|
Available models:
|
|
@@ -3779,7 +3796,7 @@ const _AzureOpenAiMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
3779
3796
|
/**
|
|
3780
3797
|
* List of available OpenAI models with pricing
|
|
3781
3798
|
*
|
|
3782
|
-
* Note: Synced with official API docs at
|
|
3799
|
+
* Note: Synced with official API docs at 2026-03-22
|
|
3783
3800
|
*
|
|
3784
3801
|
* @see https://platform.openai.com/docs/models/
|
|
3785
3802
|
* @see https://openai.com/api/pricing/
|
|
@@ -3901,8 +3918,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
3901
3918
|
modelName: 'gpt-4.1',
|
|
3902
3919
|
modelDescription: 'Smartest non-reasoning model with 128K context window. Enhanced version of GPT-4 with improved instruction following, better factual accuracy, and reduced hallucinations. Features advanced function calling capabilities and superior performance on coding tasks. Ideal for applications requiring high intelligence without reasoning overhead.',
|
|
3903
3920
|
pricing: {
|
|
3904
|
-
prompt: pricing(`$
|
|
3905
|
-
output: pricing(`$
|
|
3921
|
+
prompt: pricing(`$2.00 / 1M tokens`),
|
|
3922
|
+
output: pricing(`$8.00 / 1M tokens`),
|
|
3906
3923
|
},
|
|
3907
3924
|
},
|
|
3908
3925
|
/**/
|
|
@@ -3913,8 +3930,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
3913
3930
|
modelName: 'gpt-4.1-mini',
|
|
3914
3931
|
modelDescription: 'Smaller, faster version of GPT-4.1 with 128K context window. Balances intelligence and efficiency with 3x faster inference than base GPT-4.1. Maintains strong capabilities across text generation, reasoning, and coding while offering better cost-performance ratio for most applications.',
|
|
3915
3932
|
pricing: {
|
|
3916
|
-
prompt: pricing(`$0.
|
|
3917
|
-
output: pricing(`$
|
|
3933
|
+
prompt: pricing(`$0.40 / 1M tokens`),
|
|
3934
|
+
output: pricing(`$1.60 / 1M tokens`),
|
|
3918
3935
|
},
|
|
3919
3936
|
},
|
|
3920
3937
|
/**/
|
|
@@ -3925,8 +3942,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
3925
3942
|
modelName: 'gpt-4.1-nano',
|
|
3926
3943
|
modelDescription: 'Fastest, most cost-efficient version of GPT-4.1 with 128K context window. Optimized for high-throughput applications requiring good quality at minimal cost. Features 5x faster inference than GPT-4.1 while maintaining adequate performance for most general-purpose tasks.',
|
|
3927
3944
|
pricing: {
|
|
3928
|
-
prompt: pricing(`$0.
|
|
3929
|
-
output: pricing(`$0.
|
|
3945
|
+
prompt: pricing(`$0.10 / 1M tokens`),
|
|
3946
|
+
output: pricing(`$0.40 / 1M tokens`),
|
|
3930
3947
|
},
|
|
3931
3948
|
},
|
|
3932
3949
|
/**/
|
|
@@ -3937,8 +3954,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
3937
3954
|
modelName: 'o3',
|
|
3938
3955
|
modelDescription: 'Advanced reasoning model with 128K context window specializing in complex logical, mathematical, and analytical tasks. Successor to o1 with enhanced step-by-step problem-solving capabilities and superior performance on STEM-focused problems. Ideal for professional applications requiring deep analytical thinking and precise reasoning.',
|
|
3939
3956
|
pricing: {
|
|
3940
|
-
prompt: pricing(`$
|
|
3941
|
-
output: pricing(`$
|
|
3957
|
+
prompt: pricing(`$2.00 / 1M tokens`),
|
|
3958
|
+
output: pricing(`$8.00 / 1M tokens`),
|
|
3942
3959
|
},
|
|
3943
3960
|
},
|
|
3944
3961
|
/**/
|
|
@@ -3949,8 +3966,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
3949
3966
|
modelName: 'o3-pro',
|
|
3950
3967
|
modelDescription: 'Enhanced version of o3 with more compute allocated for better responses on the most challenging problems. Features extended reasoning time and improved accuracy on complex analytical tasks. Designed for applications where maximum reasoning quality is more important than response speed.',
|
|
3951
3968
|
pricing: {
|
|
3952
|
-
prompt: pricing(`$
|
|
3953
|
-
output: pricing(`$
|
|
3969
|
+
prompt: pricing(`$20.00 / 1M tokens`),
|
|
3970
|
+
output: pricing(`$80.00 / 1M tokens`),
|
|
3954
3971
|
},
|
|
3955
3972
|
},
|
|
3956
3973
|
/**/
|
|
@@ -3961,8 +3978,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
3961
3978
|
modelName: 'o4-mini',
|
|
3962
3979
|
modelDescription: 'Fast, cost-efficient reasoning model with 128K context window. Successor to o1-mini with improved analytical capabilities while maintaining speed advantages. Features enhanced mathematical reasoning and logical problem-solving at significantly lower cost than full reasoning models.',
|
|
3963
3980
|
pricing: {
|
|
3964
|
-
prompt: pricing(`$
|
|
3965
|
-
output: pricing(`$
|
|
3981
|
+
prompt: pricing(`$1.10 / 1M tokens`),
|
|
3982
|
+
output: pricing(`$4.40 / 1M tokens`),
|
|
3966
3983
|
},
|
|
3967
3984
|
},
|
|
3968
3985
|
/**/
|
|
@@ -4320,8 +4337,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
4320
4337
|
modelName: 'gpt-4o-2024-05-13',
|
|
4321
4338
|
modelDescription: 'May 2024 version of GPT-4o with 128K context window. Features enhanced multimodal capabilities including superior image understanding (up to 20MP), audio processing, and improved reasoning. Optimized for 2x lower latency than GPT-4 Turbo while maintaining high performance. Includes knowledge up to October 2023. Ideal for production applications requiring reliable multimodal capabilities.',
|
|
4322
4339
|
pricing: {
|
|
4323
|
-
prompt: pricing(`$
|
|
4324
|
-
output: pricing(`$
|
|
4340
|
+
prompt: pricing(`$2.50 / 1M tokens`),
|
|
4341
|
+
output: pricing(`$10.00 / 1M tokens`),
|
|
4325
4342
|
},
|
|
4326
4343
|
},
|
|
4327
4344
|
/**/
|
|
@@ -4332,8 +4349,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
4332
4349
|
modelName: 'gpt-4o',
|
|
4333
4350
|
modelDescription: "OpenAI's most advanced general-purpose multimodal model with 128K context window. Optimized for balanced performance, speed, and cost with 2x faster responses than GPT-4 Turbo. Features excellent vision processing, audio understanding, reasoning, and text generation quality. Represents optimal balance of capability and efficiency for most advanced applications.",
|
|
4334
4351
|
pricing: {
|
|
4335
|
-
prompt: pricing(`$
|
|
4336
|
-
output: pricing(`$
|
|
4352
|
+
prompt: pricing(`$2.50 / 1M tokens`),
|
|
4353
|
+
output: pricing(`$10.00 / 1M tokens`),
|
|
4337
4354
|
},
|
|
4338
4355
|
},
|
|
4339
4356
|
/**/
|
|
@@ -4404,8 +4421,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
4404
4421
|
modelName: 'o3-mini',
|
|
4405
4422
|
modelDescription: 'Cost-effective reasoning model with 128K context window optimized for academic and scientific problem-solving. Features efficient performance on STEM tasks with specialized capabilities in mathematics, physics, chemistry, and computer science. Offers 80% of O1 performance on technical domains at significantly lower cost. Ideal for educational applications and research support.',
|
|
4406
4423
|
pricing: {
|
|
4407
|
-
prompt: pricing(`$
|
|
4408
|
-
output: pricing(`$
|
|
4424
|
+
prompt: pricing(`$1.10 / 1M tokens`),
|
|
4425
|
+
output: pricing(`$4.40 / 1M tokens`),
|
|
4409
4426
|
},
|
|
4410
4427
|
},
|
|
4411
4428
|
/**/
|
|
@@ -4940,7 +4957,7 @@ function createExecutionToolsFromVercelProvider(options) {
|
|
|
4940
4957
|
const modelName = modelRequirements.modelName ||
|
|
4941
4958
|
((_a = availableModels.find(({ modelVariant }) => modelVariant === 'CHAT')) === null || _a === void 0 ? void 0 : _a.modelName);
|
|
4942
4959
|
if (!modelName) {
|
|
4943
|
-
throw new PipelineExecutionError(spaceTrim$
|
|
4960
|
+
throw new PipelineExecutionError(spaceTrim$1(`
|
|
4944
4961
|
Can not determine which model to use.
|
|
4945
4962
|
|
|
4946
4963
|
You need to provide at least one of:
|
|
@@ -5055,7 +5072,7 @@ function createExecutionToolsFromVercelProvider(options) {
|
|
|
5055
5072
|
/**
|
|
5056
5073
|
* List of available Deepseek models with descriptions
|
|
5057
5074
|
*
|
|
5058
|
-
* Note: Synced with official API docs at
|
|
5075
|
+
* Note: Synced with official API docs at 2026-03-22
|
|
5059
5076
|
*
|
|
5060
5077
|
* @see https://www.deepseek.com/models
|
|
5061
5078
|
* @public exported from `@promptbook/deepseek`
|
|
@@ -5069,8 +5086,8 @@ const DEEPSEEK_MODELS = exportJson({
|
|
|
5069
5086
|
modelName: 'deepseek-chat',
|
|
5070
5087
|
modelDescription: 'Latest flagship general-purpose model with 128K context window. Features exceptional reasoning capabilities, advanced code generation, and strong performance across diverse domains. Offers competitive performance with leading models while maintaining cost efficiency. Ideal for complex reasoning, coding, and knowledge-intensive tasks.',
|
|
5071
5088
|
pricing: {
|
|
5072
|
-
prompt: pricing(`$0.
|
|
5073
|
-
output: pricing(`$0.
|
|
5089
|
+
prompt: pricing(`$0.28 / 1M tokens`),
|
|
5090
|
+
output: pricing(`$0.42 / 1M tokens`),
|
|
5074
5091
|
},
|
|
5075
5092
|
},
|
|
5076
5093
|
{
|
|
@@ -5336,7 +5353,7 @@ const _GoogleMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
5336
5353
|
/**
|
|
5337
5354
|
* List of available Google models with descriptions
|
|
5338
5355
|
*
|
|
5339
|
-
* Note: Synced with official API docs at
|
|
5356
|
+
* Note: Synced with official API docs at 2026-03-22
|
|
5340
5357
|
*
|
|
5341
5358
|
* @see https://ai.google.dev/models/gemini
|
|
5342
5359
|
* @public exported from `@promptbook/google`
|
|
@@ -5357,8 +5374,8 @@ const GOOGLE_MODELS = exportJson({
|
|
|
5357
5374
|
modelName: 'gemini-2.5-pro',
|
|
5358
5375
|
modelDescription: 'State-of-the-art thinking model with 1M token context window capable of reasoning over complex problems in code, math, and STEM. Features enhanced thinking capabilities, advanced multimodal understanding, and superior performance on analytical tasks. Ideal for complex enterprise applications requiring maximum intelligence and reasoning.',
|
|
5359
5376
|
pricing: {
|
|
5360
|
-
prompt: pricing(`$
|
|
5361
|
-
output: pricing(`$
|
|
5377
|
+
prompt: pricing(`$1.25 / 1M tokens`),
|
|
5378
|
+
output: pricing(`$10.00 / 1M tokens`),
|
|
5362
5379
|
},
|
|
5363
5380
|
},
|
|
5364
5381
|
{
|
|
@@ -5367,8 +5384,8 @@ const GOOGLE_MODELS = exportJson({
|
|
|
5367
5384
|
modelName: 'gemini-2.5-flash',
|
|
5368
5385
|
modelDescription: 'Best model in terms of price-performance with 1M token context window offering well-rounded capabilities. Features adaptive thinking, cost efficiency, and enhanced reasoning for large-scale processing. Ideal for low-latency, high-volume tasks that require thinking and agentic use cases.',
|
|
5369
5386
|
pricing: {
|
|
5370
|
-
prompt: pricing(`$0.
|
|
5371
|
-
output: pricing(`$
|
|
5387
|
+
prompt: pricing(`$0.30 / 1M tokens`),
|
|
5388
|
+
output: pricing(`$2.50 / 1M tokens`),
|
|
5372
5389
|
},
|
|
5373
5390
|
},
|
|
5374
5391
|
{
|
|
@@ -5377,8 +5394,8 @@ const GOOGLE_MODELS = exportJson({
|
|
|
5377
5394
|
modelName: 'gemini-2.5-flash-lite',
|
|
5378
5395
|
modelDescription: 'Cost-efficient Gemini 2.5 Flash model optimized for high throughput with 1M token context window. Features thinking capabilities while maintaining the most cost-efficient pricing. Perfect for real-time, low-latency use cases requiring good quality at scale.',
|
|
5379
5396
|
pricing: {
|
|
5380
|
-
prompt: pricing(`$0.
|
|
5381
|
-
output: pricing(`$0.
|
|
5397
|
+
prompt: pricing(`$0.10 / 1M tokens`),
|
|
5398
|
+
output: pricing(`$0.40 / 1M tokens`),
|
|
5382
5399
|
},
|
|
5383
5400
|
},
|
|
5384
5401
|
{
|
|
@@ -5898,188 +5915,6 @@ resultContent, rawResponse, duration = ZERO_VALUE) {
|
|
|
5898
5915
|
* TODO: [🤝] DRY Maybe some common abstraction between `computeOpenAiUsage` and `computeAnthropicClaudeUsage`
|
|
5899
5916
|
*/
|
|
5900
5917
|
|
|
5901
|
-
/**
|
|
5902
|
-
* Prompt parameter key used to pass hidden runtime context to tool execution.
|
|
5903
|
-
*
|
|
5904
|
-
* @private internal runtime wiring for commitment tools
|
|
5905
|
-
*/
|
|
5906
|
-
const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
|
|
5907
|
-
/**
|
|
5908
|
-
* Hidden argument key used to pass runtime context into individual tool calls.
|
|
5909
|
-
*
|
|
5910
|
-
* @private internal runtime wiring for commitment tools
|
|
5911
|
-
*/
|
|
5912
|
-
const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
|
|
5913
|
-
/**
|
|
5914
|
-
* Prompt parameter key used to pass a hidden tool-progress listener token into script execution.
|
|
5915
|
-
*
|
|
5916
|
-
* @private internal runtime wiring for commitment tools
|
|
5917
|
-
*/
|
|
5918
|
-
const TOOL_PROGRESS_TOKEN_PARAMETER = 'promptbookToolProgressToken';
|
|
5919
|
-
/**
|
|
5920
|
-
* Hidden argument key used to pass a tool-progress listener token into individual tool calls.
|
|
5921
|
-
*
|
|
5922
|
-
* @private internal runtime wiring for commitment tools
|
|
5923
|
-
*/
|
|
5924
|
-
const TOOL_PROGRESS_TOKEN_ARGUMENT = '__promptbookToolProgressToken';
|
|
5925
|
-
/**
|
|
5926
|
-
* Monotonic counter used for hidden progress-listener tokens.
|
|
5927
|
-
*
|
|
5928
|
-
* @private internal runtime wiring for commitment tools
|
|
5929
|
-
*/
|
|
5930
|
-
let toolCallProgressListenerCounter = 0;
|
|
5931
|
-
/**
|
|
5932
|
-
* Active tool-progress listeners keyed by hidden execution token.
|
|
5933
|
-
*
|
|
5934
|
-
* @private internal runtime wiring for commitment tools
|
|
5935
|
-
*/
|
|
5936
|
-
const toolCallProgressListeners = new Map();
|
|
5937
|
-
/**
|
|
5938
|
-
* Parses unknown runtime context payload into a normalized object.
|
|
5939
|
-
*
|
|
5940
|
-
* @private internal runtime wiring for commitment tools
|
|
5941
|
-
*/
|
|
5942
|
-
function parseToolRuntimeContext(rawValue) {
|
|
5943
|
-
if (!rawValue) {
|
|
5944
|
-
return null;
|
|
5945
|
-
}
|
|
5946
|
-
let parsed = rawValue;
|
|
5947
|
-
if (typeof rawValue === 'string') {
|
|
5948
|
-
try {
|
|
5949
|
-
parsed = JSON.parse(rawValue);
|
|
5950
|
-
}
|
|
5951
|
-
catch (_a) {
|
|
5952
|
-
return null;
|
|
5953
|
-
}
|
|
5954
|
-
}
|
|
5955
|
-
if (!parsed || typeof parsed !== 'object') {
|
|
5956
|
-
return null;
|
|
5957
|
-
}
|
|
5958
|
-
return parsed;
|
|
5959
|
-
}
|
|
5960
|
-
/**
|
|
5961
|
-
* Reads runtime context attached to tool call arguments.
|
|
5962
|
-
*
|
|
5963
|
-
* @private internal runtime wiring for commitment tools
|
|
5964
|
-
*/
|
|
5965
|
-
function readToolRuntimeContextFromToolArgs(args) {
|
|
5966
|
-
return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
|
|
5967
|
-
}
|
|
5968
|
-
/**
|
|
5969
|
-
* Reads the hidden tool-progress token from tool arguments.
|
|
5970
|
-
*
|
|
5971
|
-
* @private internal runtime wiring for commitment tools
|
|
5972
|
-
*/
|
|
5973
|
-
function readToolProgressTokenFromToolArgs(args) {
|
|
5974
|
-
const token = args[TOOL_PROGRESS_TOKEN_ARGUMENT];
|
|
5975
|
-
return typeof token === 'string' && token.trim().length > 0 ? token : null;
|
|
5976
|
-
}
|
|
5977
|
-
/**
|
|
5978
|
-
* Serializes runtime context for prompt parameters.
|
|
5979
|
-
*
|
|
5980
|
-
* @private internal runtime wiring for commitment tools
|
|
5981
|
-
*/
|
|
5982
|
-
function serializeToolRuntimeContext(context) {
|
|
5983
|
-
return JSON.stringify(context);
|
|
5984
|
-
}
|
|
5985
|
-
/**
|
|
5986
|
-
* Registers one in-memory listener that receives progress updates emitted by a running tool.
|
|
5987
|
-
*
|
|
5988
|
-
* The returned token is passed into script execution as a hidden argument so tool implementations
|
|
5989
|
-
* can stream progress without exposing extra parameters to the model.
|
|
5990
|
-
*
|
|
5991
|
-
* @param listener - Listener notified about tool progress.
|
|
5992
|
-
* @returns Hidden token used to route progress updates.
|
|
5993
|
-
* @private internal runtime wiring for commitment tools
|
|
5994
|
-
*/
|
|
5995
|
-
function registerToolCallProgressListener(listener) {
|
|
5996
|
-
toolCallProgressListenerCounter += 1;
|
|
5997
|
-
const token = `tool-progress:${Date.now()}:${toolCallProgressListenerCounter}`;
|
|
5998
|
-
toolCallProgressListeners.set(token, listener);
|
|
5999
|
-
return token;
|
|
6000
|
-
}
|
|
6001
|
-
/**
|
|
6002
|
-
* Unregisters one in-memory progress listener.
|
|
6003
|
-
*
|
|
6004
|
-
* @param token - Token previously created by `registerToolCallProgressListener`.
|
|
6005
|
-
* @private internal runtime wiring for commitment tools
|
|
6006
|
-
*/
|
|
6007
|
-
function unregisterToolCallProgressListener(token) {
|
|
6008
|
-
toolCallProgressListeners.delete(token);
|
|
6009
|
-
}
|
|
6010
|
-
/**
|
|
6011
|
-
* Emits one tool progress update using a hidden token carried in tool arguments.
|
|
6012
|
-
*
|
|
6013
|
-
* @param args - Raw tool arguments including hidden runtime keys.
|
|
6014
|
-
* @param update - Incremental progress update.
|
|
6015
|
-
* @returns `true` when a listener was found and notified.
|
|
6016
|
-
* @private internal runtime wiring for commitment tools
|
|
6017
|
-
*/
|
|
6018
|
-
function emitToolCallProgressFromToolArgs(args, update) {
|
|
6019
|
-
const token = readToolProgressTokenFromToolArgs(args);
|
|
6020
|
-
if (!token) {
|
|
6021
|
-
return false;
|
|
6022
|
-
}
|
|
6023
|
-
const listener = toolCallProgressListeners.get(token);
|
|
6024
|
-
if (!listener) {
|
|
6025
|
-
return false;
|
|
6026
|
-
}
|
|
6027
|
-
listener(update);
|
|
6028
|
-
return true;
|
|
6029
|
-
}
|
|
6030
|
-
/**
|
|
6031
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
6032
|
-
*/
|
|
6033
|
-
|
|
6034
|
-
/**
|
|
6035
|
-
* Marker property stored inside serialized tool-execution envelopes.
|
|
6036
|
-
*
|
|
6037
|
-
* @private internal tool-execution transport
|
|
6038
|
-
*/
|
|
6039
|
-
const TOOL_EXECUTION_ENVELOPE_MARKER = '__promptbookToolExecutionEnvelope';
|
|
6040
|
-
/**
|
|
6041
|
-
* Creates one serialized tool-execution envelope.
|
|
6042
|
-
*
|
|
6043
|
-
* @private internal tool-execution transport
|
|
6044
|
-
*/
|
|
6045
|
-
function createToolExecutionEnvelope(options) {
|
|
6046
|
-
const envelope = {
|
|
6047
|
-
[TOOL_EXECUTION_ENVELOPE_MARKER]: true,
|
|
6048
|
-
assistantMessage: options.assistantMessage,
|
|
6049
|
-
toolResult: options.toolResult,
|
|
6050
|
-
};
|
|
6051
|
-
return JSON.stringify(envelope);
|
|
6052
|
-
}
|
|
6053
|
-
/**
|
|
6054
|
-
* Parses one serialized tool-execution envelope when present.
|
|
6055
|
-
*
|
|
6056
|
-
* @private internal tool-execution transport
|
|
6057
|
-
*/
|
|
6058
|
-
function parseToolExecutionEnvelope(rawValue) {
|
|
6059
|
-
if (typeof rawValue !== 'string') {
|
|
6060
|
-
return null;
|
|
6061
|
-
}
|
|
6062
|
-
try {
|
|
6063
|
-
const parsedValue = JSON.parse(rawValue);
|
|
6064
|
-
if (!parsedValue ||
|
|
6065
|
-
typeof parsedValue !== 'object' ||
|
|
6066
|
-
parsedValue[TOOL_EXECUTION_ENVELOPE_MARKER] !== true ||
|
|
6067
|
-
typeof parsedValue.assistantMessage !== 'string') {
|
|
6068
|
-
return null;
|
|
6069
|
-
}
|
|
6070
|
-
return {
|
|
6071
|
-
assistantMessage: parsedValue.assistantMessage,
|
|
6072
|
-
toolResult: parsedValue.toolResult,
|
|
6073
|
-
};
|
|
6074
|
-
}
|
|
6075
|
-
catch (_a) {
|
|
6076
|
-
return null;
|
|
6077
|
-
}
|
|
6078
|
-
}
|
|
6079
|
-
/**
|
|
6080
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
6081
|
-
*/
|
|
6082
|
-
|
|
6083
5918
|
/**
|
|
6084
5919
|
* Normalizes a given text to camelCase format.
|
|
6085
5920
|
*
|
|
@@ -6296,7 +6131,7 @@ function serializeError(error) {
|
|
|
6296
6131
|
const { name, message, stack } = error;
|
|
6297
6132
|
const { id } = error;
|
|
6298
6133
|
if (!Object.keys(ALL_ERRORS).includes(name)) {
|
|
6299
|
-
console.error(spaceTrim$
|
|
6134
|
+
console.error(spaceTrim$1((block) => `
|
|
6300
6135
|
|
|
6301
6136
|
Cannot serialize error with name "${name}"
|
|
6302
6137
|
|
|
@@ -6402,7 +6237,7 @@ function jsonParse(value) {
|
|
|
6402
6237
|
}
|
|
6403
6238
|
else if (typeof value !== 'string') {
|
|
6404
6239
|
console.error('Can not parse JSON from non-string value.', { text: value });
|
|
6405
|
-
throw new Error(spaceTrim$
|
|
6240
|
+
throw new Error(spaceTrim$1(`
|
|
6406
6241
|
Can not parse JSON from non-string value.
|
|
6407
6242
|
|
|
6408
6243
|
The value type: ${typeof value}
|
|
@@ -6416,7 +6251,7 @@ function jsonParse(value) {
|
|
|
6416
6251
|
if (!(error instanceof Error)) {
|
|
6417
6252
|
throw error;
|
|
6418
6253
|
}
|
|
6419
|
-
throw new Error(spaceTrim$
|
|
6254
|
+
throw new Error(spaceTrim$1((block) => `
|
|
6420
6255
|
${block(error.message)}
|
|
6421
6256
|
|
|
6422
6257
|
The expected JSON text:
|
|
@@ -6705,7 +6540,7 @@ function buildParametersSection(items) {
|
|
|
6705
6540
|
const entries = items
|
|
6706
6541
|
.flatMap((item) => formatParameterListItem(item).split(/\r?\n/))
|
|
6707
6542
|
.filter((line) => line !== '');
|
|
6708
|
-
return spaceTrim$
|
|
6543
|
+
return spaceTrim$1((block) => `
|
|
6709
6544
|
**Parameters:**
|
|
6710
6545
|
${block(entries.join('\n'))}
|
|
6711
6546
|
|
|
@@ -6778,7 +6613,7 @@ function isPromptString(value) {
|
|
|
6778
6613
|
*/
|
|
6779
6614
|
function prompt(strings, ...values) {
|
|
6780
6615
|
if (values.length === 0) {
|
|
6781
|
-
return new PromptString(spaceTrim$
|
|
6616
|
+
return new PromptString(spaceTrim$1(strings.join('')));
|
|
6782
6617
|
}
|
|
6783
6618
|
const stringsWithHiddenParameters = strings.map((stringsItem) => ParameterEscaping.hideBrackets(stringsItem));
|
|
6784
6619
|
const parameterMetadata = values.map((value) => {
|
|
@@ -6819,7 +6654,7 @@ function prompt(strings, ...values) {
|
|
|
6819
6654
|
? `${result}${stringsItem}`
|
|
6820
6655
|
: `${result}${stringsItem}${ParameterSection.formatParameterPlaceholder(parameterName)}`;
|
|
6821
6656
|
}, '');
|
|
6822
|
-
pipelineString = spaceTrim$
|
|
6657
|
+
pipelineString = spaceTrim$1(pipelineString);
|
|
6823
6658
|
try {
|
|
6824
6659
|
pipelineString = templateParameters(pipelineString, parameters);
|
|
6825
6660
|
}
|
|
@@ -6828,7 +6663,7 @@ function prompt(strings, ...values) {
|
|
|
6828
6663
|
throw error;
|
|
6829
6664
|
}
|
|
6830
6665
|
console.error({ pipelineString, parameters, parameterNames: parameterNamesOrdered, error });
|
|
6831
|
-
throw new UnexpectedError(spaceTrim$
|
|
6666
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
6832
6667
|
Internal error in prompt template literal
|
|
6833
6668
|
|
|
6834
6669
|
${block(JSON.stringify({ strings, values }, null, 4))}}
|
|
@@ -6946,7 +6781,7 @@ const CountUtils = {
|
|
|
6946
6781
|
* @public exported from `@promptbook/utils`
|
|
6947
6782
|
*/
|
|
6948
6783
|
function computeHash(value) {
|
|
6949
|
-
return SHA256(hexEncoder.parse(spaceTrim$
|
|
6784
|
+
return SHA256(hexEncoder.parse(spaceTrim$1(valueToString(value)))).toString( /* hex */);
|
|
6950
6785
|
}
|
|
6951
6786
|
/**
|
|
6952
6787
|
* TODO: [🥬][🥬] Use this ACRY
|
|
@@ -9001,6 +8836,159 @@ function isValidPipelineUrl(url) {
|
|
|
9001
8836
|
* TODO: [🐠] Maybe more info why the URL is invalid
|
|
9002
8837
|
*/
|
|
9003
8838
|
|
|
8839
|
+
/**
|
|
8840
|
+
* Marker property stored inside serialized tool-execution envelopes.
|
|
8841
|
+
*
|
|
8842
|
+
* @private internal tool-execution transport
|
|
8843
|
+
*/
|
|
8844
|
+
const TOOL_EXECUTION_ENVELOPE_MARKER = '__promptbookToolExecutionEnvelope';
|
|
8845
|
+
/**
|
|
8846
|
+
* Creates one serialized tool-execution envelope.
|
|
8847
|
+
*
|
|
8848
|
+
* @private internal tool-execution transport
|
|
8849
|
+
*/
|
|
8850
|
+
function createToolExecutionEnvelope(options) {
|
|
8851
|
+
const envelope = {
|
|
8852
|
+
[TOOL_EXECUTION_ENVELOPE_MARKER]: true,
|
|
8853
|
+
assistantMessage: options.assistantMessage,
|
|
8854
|
+
toolResult: options.toolResult,
|
|
8855
|
+
};
|
|
8856
|
+
return JSON.stringify(envelope);
|
|
8857
|
+
}
|
|
8858
|
+
/**
|
|
8859
|
+
* Parses one serialized tool-execution envelope when present.
|
|
8860
|
+
*
|
|
8861
|
+
* @private internal tool-execution transport
|
|
8862
|
+
*/
|
|
8863
|
+
function parseToolExecutionEnvelope(rawValue) {
|
|
8864
|
+
if (typeof rawValue !== 'string') {
|
|
8865
|
+
return null;
|
|
8866
|
+
}
|
|
8867
|
+
try {
|
|
8868
|
+
const parsedValue = JSON.parse(rawValue);
|
|
8869
|
+
if (!parsedValue ||
|
|
8870
|
+
typeof parsedValue !== 'object' ||
|
|
8871
|
+
parsedValue[TOOL_EXECUTION_ENVELOPE_MARKER] !== true ||
|
|
8872
|
+
typeof parsedValue.assistantMessage !== 'string') {
|
|
8873
|
+
return null;
|
|
8874
|
+
}
|
|
8875
|
+
return {
|
|
8876
|
+
assistantMessage: parsedValue.assistantMessage,
|
|
8877
|
+
toolResult: parsedValue.toolResult,
|
|
8878
|
+
};
|
|
8879
|
+
}
|
|
8880
|
+
catch (_a) {
|
|
8881
|
+
return null;
|
|
8882
|
+
}
|
|
8883
|
+
}
|
|
8884
|
+
/**
|
|
8885
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
8886
|
+
*/
|
|
8887
|
+
|
|
8888
|
+
/**
|
|
8889
|
+
* Prompt parameter key used to pass hidden runtime context to tool execution.
|
|
8890
|
+
*
|
|
8891
|
+
* @private internal runtime wiring for commitment tools
|
|
8892
|
+
*/
|
|
8893
|
+
const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
|
|
8894
|
+
/**
|
|
8895
|
+
* Hidden argument key used to pass runtime context into individual tool calls.
|
|
8896
|
+
*
|
|
8897
|
+
* @private internal runtime wiring for commitment tools
|
|
8898
|
+
*/
|
|
8899
|
+
const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
|
|
8900
|
+
/**
|
|
8901
|
+
* Prompt parameter key used to pass a hidden tool-progress listener token into script execution.
|
|
8902
|
+
*
|
|
8903
|
+
* @private internal runtime wiring for commitment tools
|
|
8904
|
+
*/
|
|
8905
|
+
const TOOL_PROGRESS_TOKEN_PARAMETER = 'promptbookToolProgressToken';
|
|
8906
|
+
/**
|
|
8907
|
+
* Hidden argument key used to pass a tool-progress listener token into individual tool calls.
|
|
8908
|
+
*
|
|
8909
|
+
* @private internal runtime wiring for commitment tools
|
|
8910
|
+
*/
|
|
8911
|
+
const TOOL_PROGRESS_TOKEN_ARGUMENT = '__promptbookToolProgressToken';
|
|
8912
|
+
/**
|
|
8913
|
+
* Monotonic counter used for hidden progress-listener tokens.
|
|
8914
|
+
*
|
|
8915
|
+
* @private internal runtime wiring for commitment tools
|
|
8916
|
+
*/
|
|
8917
|
+
let toolCallProgressListenerCounter = 0;
|
|
8918
|
+
/**
|
|
8919
|
+
* Active tool-progress listeners keyed by hidden execution token.
|
|
8920
|
+
*
|
|
8921
|
+
* @private internal runtime wiring for commitment tools
|
|
8922
|
+
*/
|
|
8923
|
+
const toolCallProgressListeners = new Map();
|
|
8924
|
+
/**
|
|
8925
|
+
* Parses unknown runtime context payload into a normalized object.
|
|
8926
|
+
*
|
|
8927
|
+
* @private internal runtime wiring for commitment tools
|
|
8928
|
+
*/
|
|
8929
|
+
function parseToolRuntimeContext(rawValue) {
|
|
8930
|
+
if (!rawValue) {
|
|
8931
|
+
return null;
|
|
8932
|
+
}
|
|
8933
|
+
let parsed = rawValue;
|
|
8934
|
+
if (typeof rawValue === 'string') {
|
|
8935
|
+
try {
|
|
8936
|
+
parsed = JSON.parse(rawValue);
|
|
8937
|
+
}
|
|
8938
|
+
catch (_a) {
|
|
8939
|
+
return null;
|
|
8940
|
+
}
|
|
8941
|
+
}
|
|
8942
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
8943
|
+
return null;
|
|
8944
|
+
}
|
|
8945
|
+
return parsed;
|
|
8946
|
+
}
|
|
8947
|
+
/**
|
|
8948
|
+
* Reads runtime context attached to tool call arguments.
|
|
8949
|
+
*
|
|
8950
|
+
* @private internal runtime wiring for commitment tools
|
|
8951
|
+
*/
|
|
8952
|
+
function readToolRuntimeContextFromToolArgs(args) {
|
|
8953
|
+
return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
|
|
8954
|
+
}
|
|
8955
|
+
/**
|
|
8956
|
+
* Serializes runtime context for prompt parameters.
|
|
8957
|
+
*
|
|
8958
|
+
* @private internal runtime wiring for commitment tools
|
|
8959
|
+
*/
|
|
8960
|
+
function serializeToolRuntimeContext(context) {
|
|
8961
|
+
return JSON.stringify(context);
|
|
8962
|
+
}
|
|
8963
|
+
/**
|
|
8964
|
+
* Registers one in-memory listener that receives progress updates emitted by a running tool.
|
|
8965
|
+
*
|
|
8966
|
+
* The returned token is passed into script execution as a hidden argument so tool implementations
|
|
8967
|
+
* can stream progress without exposing extra parameters to the model.
|
|
8968
|
+
*
|
|
8969
|
+
* @param listener - Listener notified about tool progress.
|
|
8970
|
+
* @returns Hidden token used to route progress updates.
|
|
8971
|
+
* @private internal runtime wiring for commitment tools
|
|
8972
|
+
*/
|
|
8973
|
+
function registerToolCallProgressListener(listener) {
|
|
8974
|
+
toolCallProgressListenerCounter += 1;
|
|
8975
|
+
const token = `tool-progress:${Date.now()}:${toolCallProgressListenerCounter}`;
|
|
8976
|
+
toolCallProgressListeners.set(token, listener);
|
|
8977
|
+
return token;
|
|
8978
|
+
}
|
|
8979
|
+
/**
|
|
8980
|
+
* Unregisters one in-memory progress listener.
|
|
8981
|
+
*
|
|
8982
|
+
* @param token - Token previously created by `registerToolCallProgressListener`.
|
|
8983
|
+
* @private internal runtime wiring for commitment tools
|
|
8984
|
+
*/
|
|
8985
|
+
function unregisterToolCallProgressListener(token) {
|
|
8986
|
+
toolCallProgressListeners.delete(token);
|
|
8987
|
+
}
|
|
8988
|
+
/**
|
|
8989
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
8990
|
+
*/
|
|
8991
|
+
|
|
9004
8992
|
/**
|
|
9005
8993
|
* Function `addUsage` will add multiple usages into one
|
|
9006
8994
|
*
|
|
@@ -9055,53 +9043,6 @@ function addUsage(...usageItems) {
|
|
|
9055
9043
|
}, deepClone(ZERO_USAGE));
|
|
9056
9044
|
}
|
|
9057
9045
|
|
|
9058
|
-
/**
|
|
9059
|
-
* Maps Promptbook tools to OpenAI tools.
|
|
9060
|
-
*
|
|
9061
|
-
* @private
|
|
9062
|
-
*/
|
|
9063
|
-
function mapToolsToOpenAi(tools) {
|
|
9064
|
-
return tools.map((tool) => ({
|
|
9065
|
-
type: 'function',
|
|
9066
|
-
function: {
|
|
9067
|
-
name: tool.name,
|
|
9068
|
-
description: tool.description,
|
|
9069
|
-
parameters: tool.parameters,
|
|
9070
|
-
},
|
|
9071
|
-
}));
|
|
9072
|
-
}
|
|
9073
|
-
|
|
9074
|
-
/**
|
|
9075
|
-
* Builds a tool invocation script that injects hidden runtime context into tool args.
|
|
9076
|
-
*
|
|
9077
|
-
* @private utility of OpenAI tool execution wrappers
|
|
9078
|
-
*/
|
|
9079
|
-
function buildToolInvocationScript(options) {
|
|
9080
|
-
const { functionName, functionArgsExpression } = options;
|
|
9081
|
-
return `
|
|
9082
|
-
const args = ${functionArgsExpression};
|
|
9083
|
-
const runtimeContextRaw =
|
|
9084
|
-
typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
|
|
9085
|
-
? undefined
|
|
9086
|
-
: ${TOOL_RUNTIME_CONTEXT_PARAMETER};
|
|
9087
|
-
|
|
9088
|
-
if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
|
|
9089
|
-
args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
|
|
9090
|
-
}
|
|
9091
|
-
|
|
9092
|
-
const toolProgressTokenRaw =
|
|
9093
|
-
typeof ${TOOL_PROGRESS_TOKEN_PARAMETER} === 'undefined'
|
|
9094
|
-
? undefined
|
|
9095
|
-
: ${TOOL_PROGRESS_TOKEN_PARAMETER};
|
|
9096
|
-
|
|
9097
|
-
if (toolProgressTokenRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
|
|
9098
|
-
args.${TOOL_PROGRESS_TOKEN_ARGUMENT} = toolProgressTokenRaw;
|
|
9099
|
-
}
|
|
9100
|
-
|
|
9101
|
-
return await ${functionName}(args);
|
|
9102
|
-
`;
|
|
9103
|
-
}
|
|
9104
|
-
|
|
9105
9046
|
/**
|
|
9106
9047
|
* Parses an OpenAI error message to identify which parameter is unsupported
|
|
9107
9048
|
*
|
|
@@ -9158,6 +9099,53 @@ function isUnsupportedParameterError(error) {
|
|
|
9158
9099
|
errorMessage.includes('does not support'));
|
|
9159
9100
|
}
|
|
9160
9101
|
|
|
9102
|
+
/**
|
|
9103
|
+
* Builds a tool invocation script that injects hidden runtime context into tool args.
|
|
9104
|
+
*
|
|
9105
|
+
* @private utility of OpenAI tool execution wrappers
|
|
9106
|
+
*/
|
|
9107
|
+
function buildToolInvocationScript(options) {
|
|
9108
|
+
const { functionName, functionArgsExpression } = options;
|
|
9109
|
+
return `
|
|
9110
|
+
const args = ${functionArgsExpression};
|
|
9111
|
+
const runtimeContextRaw =
|
|
9112
|
+
typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
|
|
9113
|
+
? undefined
|
|
9114
|
+
: ${TOOL_RUNTIME_CONTEXT_PARAMETER};
|
|
9115
|
+
|
|
9116
|
+
if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
|
|
9117
|
+
args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
|
|
9118
|
+
}
|
|
9119
|
+
|
|
9120
|
+
const toolProgressTokenRaw =
|
|
9121
|
+
typeof ${TOOL_PROGRESS_TOKEN_PARAMETER} === 'undefined'
|
|
9122
|
+
? undefined
|
|
9123
|
+
: ${TOOL_PROGRESS_TOKEN_PARAMETER};
|
|
9124
|
+
|
|
9125
|
+
if (toolProgressTokenRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
|
|
9126
|
+
args.${TOOL_PROGRESS_TOKEN_ARGUMENT} = toolProgressTokenRaw;
|
|
9127
|
+
}
|
|
9128
|
+
|
|
9129
|
+
return await ${functionName}(args);
|
|
9130
|
+
`;
|
|
9131
|
+
}
|
|
9132
|
+
|
|
9133
|
+
/**
|
|
9134
|
+
* Maps Promptbook tools to OpenAI tools.
|
|
9135
|
+
*
|
|
9136
|
+
* @private
|
|
9137
|
+
*/
|
|
9138
|
+
function mapToolsToOpenAi(tools) {
|
|
9139
|
+
return tools.map((tool) => ({
|
|
9140
|
+
type: 'function',
|
|
9141
|
+
function: {
|
|
9142
|
+
name: tool.name,
|
|
9143
|
+
description: tool.description,
|
|
9144
|
+
parameters: tool.parameters,
|
|
9145
|
+
},
|
|
9146
|
+
}));
|
|
9147
|
+
}
|
|
9148
|
+
|
|
9161
9149
|
/**
|
|
9162
9150
|
* Provides access to the structured clone implementation when available.
|
|
9163
9151
|
*/
|
|
@@ -10124,7 +10112,7 @@ class OpenAiCompatibleExecutionTools {
|
|
|
10124
10112
|
// Note: Match exact or prefix for model families
|
|
10125
10113
|
const model = this.HARDCODED_MODELS.find(({ modelName }) => modelName === defaultModelName || modelName.startsWith(defaultModelName));
|
|
10126
10114
|
if (model === undefined) {
|
|
10127
|
-
throw new PipelineExecutionError(spaceTrim$
|
|
10115
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
10128
10116
|
Cannot find model in ${this.title} models with name "${defaultModelName}" which should be used as default.
|
|
10129
10117
|
|
|
10130
10118
|
Available models:
|
|
@@ -11999,7 +11987,7 @@ class OpenAiAssistantExecutionTools extends OpenAiVectorStoreHandler {
|
|
|
11999
11987
|
assertsError(error);
|
|
12000
11988
|
const serializedError = serializeError(error);
|
|
12001
11989
|
errors = [serializedError];
|
|
12002
|
-
functionResponse = spaceTrim$
|
|
11990
|
+
functionResponse = spaceTrim$1((block) => `
|
|
12003
11991
|
|
|
12004
11992
|
The invoked tool \`${functionName}\` failed with error:
|
|
12005
11993
|
|
|
@@ -13088,7 +13076,7 @@ function pipelineJsonToString(pipelineJson) {
|
|
|
13088
13076
|
pipelineString += '\n\n';
|
|
13089
13077
|
pipelineString += '```' + contentLanguage;
|
|
13090
13078
|
pipelineString += '\n';
|
|
13091
|
-
pipelineString += spaceTrim$
|
|
13079
|
+
pipelineString += spaceTrim$1(content);
|
|
13092
13080
|
// <- TODO: [main] !!3 Escape
|
|
13093
13081
|
// <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
|
|
13094
13082
|
pipelineString += '\n';
|
|
@@ -13988,14 +13976,14 @@ class MultipleLlmExecutionTools {
|
|
|
13988
13976
|
if (description === undefined) {
|
|
13989
13977
|
return headLine;
|
|
13990
13978
|
}
|
|
13991
|
-
return spaceTrim$
|
|
13979
|
+
return spaceTrim$1((block) => `
|
|
13992
13980
|
${headLine}
|
|
13993
13981
|
|
|
13994
13982
|
${ /* <- Note: Indenting the description: */block(description)}
|
|
13995
13983
|
`);
|
|
13996
13984
|
})
|
|
13997
13985
|
.join('\n\n');
|
|
13998
|
-
return spaceTrim$
|
|
13986
|
+
return spaceTrim$1((block) => `
|
|
13999
13987
|
Multiple LLM Providers:
|
|
14000
13988
|
|
|
14001
13989
|
${block(innerModelsTitlesAndDescriptions)}
|
|
@@ -14097,7 +14085,7 @@ class MultipleLlmExecutionTools {
|
|
|
14097
14085
|
// 1) OpenAI throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
14098
14086
|
// 2) AnthropicClaude throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
14099
14087
|
// 3) ...
|
|
14100
|
-
spaceTrim$
|
|
14088
|
+
spaceTrim$1((block) => `
|
|
14101
14089
|
All execution tools of ${this.title} failed:
|
|
14102
14090
|
|
|
14103
14091
|
${block(errors
|
|
@@ -14110,7 +14098,7 @@ class MultipleLlmExecutionTools {
|
|
|
14110
14098
|
throw new PipelineExecutionError(`You have not provided any \`LlmExecutionTools\` into ${this.title}`);
|
|
14111
14099
|
}
|
|
14112
14100
|
else {
|
|
14113
|
-
throw new PipelineExecutionError(spaceTrim$
|
|
14101
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
14114
14102
|
You have not provided any \`LlmExecutionTools\` that support model variant "${prompt.modelRequirements.modelVariant}" into ${this.title}
|
|
14115
14103
|
|
|
14116
14104
|
Available \`LlmExecutionTools\`:
|
|
@@ -14147,7 +14135,7 @@ class MultipleLlmExecutionTools {
|
|
|
14147
14135
|
*/
|
|
14148
14136
|
function joinLlmExecutionTools(title, ...llmExecutionTools) {
|
|
14149
14137
|
if (llmExecutionTools.length === 0) {
|
|
14150
|
-
const warningMessage = spaceTrim$
|
|
14138
|
+
const warningMessage = spaceTrim$1(`
|
|
14151
14139
|
You have not provided any \`LlmExecutionTools\`
|
|
14152
14140
|
This means that you won't be able to execute any prompts that require large language models like GPT-4 or Anthropic's Claude.
|
|
14153
14141
|
|
|
@@ -14319,14 +14307,14 @@ function $registeredScrapersMessage(availableScrapers) {
|
|
|
14319
14307
|
return { ...metadata, isMetadataAviailable, isInstalled, isAvailableInTools };
|
|
14320
14308
|
});
|
|
14321
14309
|
if (metadata.length === 0) {
|
|
14322
|
-
return spaceTrim$
|
|
14310
|
+
return spaceTrim$1(`
|
|
14323
14311
|
**No scrapers are available**
|
|
14324
14312
|
|
|
14325
14313
|
This is a unexpected behavior, you are probably using some broken version of Promptbook
|
|
14326
14314
|
At least there should be available the metadata of the scrapers
|
|
14327
14315
|
`);
|
|
14328
14316
|
}
|
|
14329
|
-
return spaceTrim$
|
|
14317
|
+
return spaceTrim$1((block) => `
|
|
14330
14318
|
Available scrapers are:
|
|
14331
14319
|
${block(metadata
|
|
14332
14320
|
.map(({ packageName, className, isMetadataAviailable, isInstalled, mimeTypes, isAvailableInBrowser, isAvailableInTools, }, i) => {
|
|
@@ -14427,7 +14415,7 @@ const promptbookFetch = async (urlOrRequest, init) => {
|
|
|
14427
14415
|
else if (urlOrRequest instanceof Request) {
|
|
14428
14416
|
url = urlOrRequest.url;
|
|
14429
14417
|
}
|
|
14430
|
-
throw new PromptbookFetchError(spaceTrim$
|
|
14418
|
+
throw new PromptbookFetchError(spaceTrim$1((block) => `
|
|
14431
14419
|
Can not fetch "${url}"
|
|
14432
14420
|
|
|
14433
14421
|
Fetch error:
|
|
@@ -14587,7 +14575,7 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
|
|
|
14587
14575
|
const fileExtension = getFileExtension(filename);
|
|
14588
14576
|
const mimeType = extensionToMimeType(fileExtension || '');
|
|
14589
14577
|
if (!(await isFileExisting(filename, tools.fs))) {
|
|
14590
|
-
throw new NotFoundError(spaceTrim$
|
|
14578
|
+
throw new NotFoundError(spaceTrim$1((block) => `
|
|
14591
14579
|
Can not make source handler for file which does not exist:
|
|
14592
14580
|
|
|
14593
14581
|
File:
|
|
@@ -14680,7 +14668,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
14680
14668
|
// <- TODO: [🪓] Here should be no need for spreading new array, just `partialPieces = partialPiecesUnchecked`
|
|
14681
14669
|
break;
|
|
14682
14670
|
}
|
|
14683
|
-
console.warn(spaceTrim$
|
|
14671
|
+
console.warn(spaceTrim$1((block) => `
|
|
14684
14672
|
Cannot scrape knowledge from source despite the scraper \`${scraper.metadata.className}\` supports the mime type "${sourceHandler.mimeType}".
|
|
14685
14673
|
|
|
14686
14674
|
The source:
|
|
@@ -14696,7 +14684,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
14696
14684
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
14697
14685
|
}
|
|
14698
14686
|
if (partialPieces === null) {
|
|
14699
|
-
throw new KnowledgeScrapeError(spaceTrim$
|
|
14687
|
+
throw new KnowledgeScrapeError(spaceTrim$1((block) => `
|
|
14700
14688
|
Cannot scrape knowledge
|
|
14701
14689
|
|
|
14702
14690
|
The source:
|
|
@@ -15133,7 +15121,7 @@ const CsvFormatParser = {
|
|
|
15133
15121
|
const { value, outputParameterName, settings, mapCallback, onProgress } = options;
|
|
15134
15122
|
const csv = csvParse(value, settings);
|
|
15135
15123
|
if (csv.errors.length !== 0) {
|
|
15136
|
-
throw new CsvFormatError(spaceTrim$
|
|
15124
|
+
throw new CsvFormatError(spaceTrim$1((block) => `
|
|
15137
15125
|
CSV parsing error
|
|
15138
15126
|
|
|
15139
15127
|
Error(s) from CSV parsing:
|
|
@@ -15178,7 +15166,7 @@ const CsvFormatParser = {
|
|
|
15178
15166
|
const { value, settings, mapCallback, onProgress } = options;
|
|
15179
15167
|
const csv = csvParse(value, settings);
|
|
15180
15168
|
if (csv.errors.length !== 0) {
|
|
15181
|
-
throw new CsvFormatError(spaceTrim$
|
|
15169
|
+
throw new CsvFormatError(spaceTrim$1((block) => `
|
|
15182
15170
|
CSV parsing error
|
|
15183
15171
|
|
|
15184
15172
|
Error(s) from CSV parsing:
|
|
@@ -15364,7 +15352,7 @@ function mapAvailableToExpectedParameters(options) {
|
|
|
15364
15352
|
}
|
|
15365
15353
|
// Phase 2️⃣: Non-matching mapping
|
|
15366
15354
|
if (expectedParameterNames.size !== availableParametersNames.size) {
|
|
15367
|
-
throw new PipelineExecutionError(spaceTrim$
|
|
15355
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
15368
15356
|
Can not map available parameters to expected parameters
|
|
15369
15357
|
|
|
15370
15358
|
Mapped parameters:
|
|
@@ -15937,7 +15925,7 @@ async function executeFormatSubvalues(options) {
|
|
|
15937
15925
|
return /* not await */ executeAttempts({ ...options, logLlmCall });
|
|
15938
15926
|
}
|
|
15939
15927
|
if (jokerParameterNames.length !== 0) {
|
|
15940
|
-
throw new UnexpectedError(spaceTrim$
|
|
15928
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
15941
15929
|
JOKER parameters are not supported together with FOREACH command
|
|
15942
15930
|
|
|
15943
15931
|
[🧞♀️] This should be prevented in \`validatePipeline\`
|
|
@@ -15950,7 +15938,7 @@ async function executeFormatSubvalues(options) {
|
|
|
15950
15938
|
if (formatDefinition === undefined) {
|
|
15951
15939
|
throw new UnexpectedError(
|
|
15952
15940
|
// <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
|
|
15953
|
-
spaceTrim$
|
|
15941
|
+
spaceTrim$1((block) => `
|
|
15954
15942
|
Unsupported format "${task.foreach.formatName}"
|
|
15955
15943
|
|
|
15956
15944
|
Available formats:
|
|
@@ -15967,7 +15955,7 @@ async function executeFormatSubvalues(options) {
|
|
|
15967
15955
|
if (subvalueParser === undefined) {
|
|
15968
15956
|
throw new UnexpectedError(
|
|
15969
15957
|
// <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
|
|
15970
|
-
spaceTrim$
|
|
15958
|
+
spaceTrim$1((block) => `
|
|
15971
15959
|
Unsupported subformat name "${task.foreach.subformatName}" for format "${task.foreach.formatName}"
|
|
15972
15960
|
|
|
15973
15961
|
Available subformat names for format "${formatDefinition.formatName}":
|
|
@@ -16007,7 +15995,7 @@ async function executeFormatSubvalues(options) {
|
|
|
16007
15995
|
if (!(error instanceof PipelineExecutionError)) {
|
|
16008
15996
|
throw error;
|
|
16009
15997
|
}
|
|
16010
|
-
const highLevelError = new PipelineExecutionError(spaceTrim$
|
|
15998
|
+
const highLevelError = new PipelineExecutionError(spaceTrim$1((block) => `
|
|
16011
15999
|
${error.message}
|
|
16012
16000
|
|
|
16013
16001
|
This is error in FOREACH command when mapping ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
|
|
@@ -16031,7 +16019,7 @@ async function executeFormatSubvalues(options) {
|
|
|
16031
16019
|
...options,
|
|
16032
16020
|
priority: priority + index,
|
|
16033
16021
|
parameters: allSubparameters,
|
|
16034
|
-
pipelineIdentification: spaceTrim$
|
|
16022
|
+
pipelineIdentification: spaceTrim$1((block) => `
|
|
16035
16023
|
${block(pipelineIdentification)}
|
|
16036
16024
|
Subparameter index: ${index}
|
|
16037
16025
|
`),
|
|
@@ -16040,7 +16028,7 @@ async function executeFormatSubvalues(options) {
|
|
|
16040
16028
|
}
|
|
16041
16029
|
catch (error) {
|
|
16042
16030
|
if (length > BIG_DATASET_TRESHOLD) {
|
|
16043
|
-
console.error(spaceTrim$
|
|
16031
|
+
console.error(spaceTrim$1((block) => `
|
|
16044
16032
|
${error.message}
|
|
16045
16033
|
|
|
16046
16034
|
This is error in FOREACH command when processing ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
|
|
@@ -16912,8 +16900,8 @@ class MarkdownScraper {
|
|
|
16912
16900
|
knowledgeTextPieces.map(async (knowledgeTextPiece, i) => {
|
|
16913
16901
|
// Note: These are just default values, they will be overwritten by the actual values:
|
|
16914
16902
|
let name = `piece-${i}`;
|
|
16915
|
-
let title = spaceTrim$
|
|
16916
|
-
const knowledgePieceContent = spaceTrim$
|
|
16903
|
+
let title = spaceTrim$1(knowledgeTextPiece.substring(0, 100));
|
|
16904
|
+
const knowledgePieceContent = spaceTrim$1(knowledgeTextPiece);
|
|
16917
16905
|
let keywords = [];
|
|
16918
16906
|
const index = [];
|
|
16919
16907
|
/*
|
|
@@ -16926,7 +16914,7 @@ class MarkdownScraper {
|
|
|
16926
16914
|
isCrashedOnError: true,
|
|
16927
16915
|
});
|
|
16928
16916
|
const { title: titleRaw = 'Untitled' } = titleResult.outputParameters;
|
|
16929
|
-
title = spaceTrim$
|
|
16917
|
+
title = spaceTrim$1(titleRaw) /* <- TODO: Maybe do in pipeline */;
|
|
16930
16918
|
name = titleToName(title);
|
|
16931
16919
|
// --- Keywords
|
|
16932
16920
|
const keywordsResult = await prepareKeywordsExecutor({ knowledgePieceContent }).asPromise({
|
|
@@ -17081,7 +17069,7 @@ class BoilerplateScraper {
|
|
|
17081
17069
|
await $execCommand(command);
|
|
17082
17070
|
// Note: [0]
|
|
17083
17071
|
if (!(await isFileExisting(cacheFilehandler.filename, this.tools.fs))) {
|
|
17084
|
-
throw new UnexpectedError(spaceTrim$
|
|
17072
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
17085
17073
|
File that was supposed to be created by Pandoc does not exist for unknown reason
|
|
17086
17074
|
|
|
17087
17075
|
Expected file:
|
|
@@ -17245,7 +17233,7 @@ class DocumentScraper {
|
|
|
17245
17233
|
await $execCommand(command);
|
|
17246
17234
|
// Note: [0]
|
|
17247
17235
|
if (!(await isFileExisting(cacheFilehandler.filename, this.tools.fs))) {
|
|
17248
|
-
throw new UnexpectedError(spaceTrim$
|
|
17236
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
17249
17237
|
File that was supposed to be created by Pandoc does not exist for unknown reason
|
|
17250
17238
|
|
|
17251
17239
|
Expected file:
|
|
@@ -17396,7 +17384,7 @@ class LegacyDocumentScraper {
|
|
|
17396
17384
|
await $execCommand(command);
|
|
17397
17385
|
const files = await readdir(documentSourceOutdirPathForLibreOffice);
|
|
17398
17386
|
if (files.length !== 1) {
|
|
17399
|
-
throw new UnexpectedError(spaceTrim$
|
|
17387
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
17400
17388
|
Expected exactly 1 file in the LibreOffice output directory, got ${files.length}
|
|
17401
17389
|
|
|
17402
17390
|
The temporary folder:
|
|
@@ -17410,7 +17398,7 @@ class LegacyDocumentScraper {
|
|
|
17410
17398
|
await rename(join(documentSourceOutdirPathForLibreOffice, file), cacheFilehandler.filename);
|
|
17411
17399
|
await rmdir(documentSourceOutdirPathForLibreOffice);
|
|
17412
17400
|
if (!(await isFileExisting(cacheFilehandler.filename, this.tools.fs))) {
|
|
17413
|
-
throw new UnexpectedError(spaceTrim$
|
|
17401
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
17414
17402
|
File that was supposed to be created by LibreOffice does not exist for unknown reason
|
|
17415
17403
|
|
|
17416
17404
|
Expected file:
|
|
@@ -27486,9 +27474,9 @@ function createTimeoutSystemMessage(extraInstructions) {
|
|
|
27486
27474
|
return spaceTrim$1((block) => `
|
|
27487
27475
|
Timeout scheduling:
|
|
27488
27476
|
- Use "set_timeout" to wake this same chat thread in the future.
|
|
27489
|
-
-
|
|
27477
|
+
- Use "list_timeouts" to review timeouts across all chats for the same user+agent scope.
|
|
27478
|
+
- "cancel_timeout" accepts a timeout id from any chat in this same user+agent scope.
|
|
27490
27479
|
- When one timeout elapses, you will receive a new user-like message that explicitly says it is a timeout wake-up and includes the \`timeoutId\`.
|
|
27491
|
-
- Use "cancel_timeout" when a previously scheduled timeout is no longer relevant.
|
|
27492
27480
|
- Do not claim a timer was set or cancelled unless the tool confirms it.
|
|
27493
27481
|
${block(extraInstructions)}
|
|
27494
27482
|
`);
|
|
@@ -27500,13 +27488,6 @@ function createTimeoutSystemMessage(extraInstructions) {
|
|
|
27500
27488
|
* @private internal utility of USE TIMEOUT
|
|
27501
27489
|
*/
|
|
27502
27490
|
function createDisabledTimeoutResult(action, message) {
|
|
27503
|
-
if (action === 'set') {
|
|
27504
|
-
return {
|
|
27505
|
-
action,
|
|
27506
|
-
status: 'disabled',
|
|
27507
|
-
message,
|
|
27508
|
-
};
|
|
27509
|
-
}
|
|
27510
27491
|
return {
|
|
27511
27492
|
action,
|
|
27512
27493
|
status: 'disabled',
|
|
@@ -27533,6 +27514,18 @@ function getTimeoutToolRuntimeAdapterOrDisabledResult(action, runtimeContext) {
|
|
|
27533
27514
|
}
|
|
27534
27515
|
}
|
|
27535
27516
|
|
|
27517
|
+
/**
|
|
27518
|
+
* Default number of rows returned by `list_timeouts`.
|
|
27519
|
+
*
|
|
27520
|
+
* @private internal USE TIMEOUT constant
|
|
27521
|
+
*/
|
|
27522
|
+
const DEFAULT_LIST_TIMEOUTS_LIMIT = 20;
|
|
27523
|
+
/**
|
|
27524
|
+
* Hard cap for `list_timeouts` page size.
|
|
27525
|
+
*
|
|
27526
|
+
* @private internal USE TIMEOUT constant
|
|
27527
|
+
*/
|
|
27528
|
+
const MAX_LIST_TIMEOUTS_LIMIT = 100;
|
|
27536
27529
|
/**
|
|
27537
27530
|
* Parses and validates `USE TIMEOUT` tool arguments.
|
|
27538
27531
|
*
|
|
@@ -27567,6 +27560,31 @@ const parseTimeoutToolArgs = {
|
|
|
27567
27560
|
}
|
|
27568
27561
|
return { timeoutId };
|
|
27569
27562
|
},
|
|
27563
|
+
/**
|
|
27564
|
+
* Parses `list_timeouts` input.
|
|
27565
|
+
*/
|
|
27566
|
+
list(args) {
|
|
27567
|
+
if (args.includeFinished !== undefined && typeof args.includeFinished !== 'boolean') {
|
|
27568
|
+
throw new PipelineExecutionError(spaceTrim$1(`
|
|
27569
|
+
Timeout \`includeFinished\` must be a boolean when provided.
|
|
27570
|
+
`));
|
|
27571
|
+
}
|
|
27572
|
+
const parsedLimit = args.limit === undefined ? DEFAULT_LIST_TIMEOUTS_LIMIT : Math.floor(Number(args.limit));
|
|
27573
|
+
if (!Number.isFinite(parsedLimit) || parsedLimit <= 0) {
|
|
27574
|
+
throw new PipelineExecutionError(spaceTrim$1(`
|
|
27575
|
+
Timeout \`limit\` must be a positive number.
|
|
27576
|
+
`));
|
|
27577
|
+
}
|
|
27578
|
+
if (parsedLimit > MAX_LIST_TIMEOUTS_LIMIT) {
|
|
27579
|
+
throw new PipelineExecutionError(spaceTrim$1(`
|
|
27580
|
+
Timeout \`limit\` must be at most \`${MAX_LIST_TIMEOUTS_LIMIT}\`.
|
|
27581
|
+
`));
|
|
27582
|
+
}
|
|
27583
|
+
return {
|
|
27584
|
+
includeFinished: args.includeFinished === true,
|
|
27585
|
+
limit: parsedLimit,
|
|
27586
|
+
};
|
|
27587
|
+
},
|
|
27570
27588
|
};
|
|
27571
27589
|
|
|
27572
27590
|
/**
|
|
@@ -27577,6 +27595,7 @@ const parseTimeoutToolArgs = {
|
|
|
27577
27595
|
const TimeoutToolNames = {
|
|
27578
27596
|
set: 'set_timeout',
|
|
27579
27597
|
cancel: 'cancel_timeout',
|
|
27598
|
+
list: 'list_timeouts',
|
|
27580
27599
|
};
|
|
27581
27600
|
|
|
27582
27601
|
/**
|
|
@@ -27676,6 +27695,35 @@ function createTimeoutToolFunctions() {
|
|
|
27676
27695
|
return JSON.stringify(result);
|
|
27677
27696
|
}
|
|
27678
27697
|
},
|
|
27698
|
+
async [TimeoutToolNames.list](args) {
|
|
27699
|
+
const runtimeContext = resolveTimeoutRuntimeContext(args);
|
|
27700
|
+
const { adapter, disabledResult } = getTimeoutToolRuntimeAdapterOrDisabledResult('list', runtimeContext);
|
|
27701
|
+
if (!adapter || disabledResult) {
|
|
27702
|
+
return JSON.stringify(disabledResult);
|
|
27703
|
+
}
|
|
27704
|
+
try {
|
|
27705
|
+
const parsedArgs = parseTimeoutToolArgs.list(args);
|
|
27706
|
+
const listedTimeouts = await adapter.listTimeouts(parsedArgs, runtimeContext);
|
|
27707
|
+
const result = {
|
|
27708
|
+
action: 'list',
|
|
27709
|
+
status: 'listed',
|
|
27710
|
+
items: listedTimeouts.items,
|
|
27711
|
+
total: listedTimeouts.total,
|
|
27712
|
+
};
|
|
27713
|
+
return createToolExecutionEnvelope({
|
|
27714
|
+
assistantMessage: listedTimeouts.total === 1 ? 'Found 1 timeout.' : `Found ${listedTimeouts.total} timeouts.`,
|
|
27715
|
+
toolResult: result,
|
|
27716
|
+
});
|
|
27717
|
+
}
|
|
27718
|
+
catch (error) {
|
|
27719
|
+
const result = {
|
|
27720
|
+
action: 'list',
|
|
27721
|
+
status: 'error',
|
|
27722
|
+
message: error instanceof Error ? error.message : String(error),
|
|
27723
|
+
};
|
|
27724
|
+
return JSON.stringify(result);
|
|
27725
|
+
}
|
|
27726
|
+
},
|
|
27679
27727
|
};
|
|
27680
27728
|
}
|
|
27681
27729
|
|
|
@@ -27709,26 +27757,45 @@ function createTimeoutTools(existingTools = []) {
|
|
|
27709
27757
|
if (!tools.some((tool) => tool.name === TimeoutToolNames.cancel)) {
|
|
27710
27758
|
tools.push({
|
|
27711
27759
|
name: TimeoutToolNames.cancel,
|
|
27712
|
-
description: 'Cancel one previously scheduled timeout
|
|
27760
|
+
description: 'Cancel one previously scheduled timeout within the same user+agent scope, even if it was set in another chat.',
|
|
27713
27761
|
parameters: {
|
|
27714
27762
|
type: 'object',
|
|
27715
27763
|
properties: {
|
|
27716
27764
|
timeoutId: {
|
|
27717
27765
|
type: 'string',
|
|
27718
|
-
description: 'Identifier returned earlier by `set_timeout`.',
|
|
27766
|
+
description: 'Identifier returned earlier by `set_timeout` or `list_timeouts`.',
|
|
27719
27767
|
},
|
|
27720
27768
|
},
|
|
27721
27769
|
required: ['timeoutId'],
|
|
27722
27770
|
},
|
|
27723
27771
|
});
|
|
27724
27772
|
}
|
|
27773
|
+
if (!tools.some((tool) => tool.name === TimeoutToolNames.list)) {
|
|
27774
|
+
tools.push({
|
|
27775
|
+
name: TimeoutToolNames.list,
|
|
27776
|
+
description: 'List scheduled timeouts across all chats for this same user+agent scope so they can be reviewed or cancelled.',
|
|
27777
|
+
parameters: {
|
|
27778
|
+
type: 'object',
|
|
27779
|
+
properties: {
|
|
27780
|
+
includeFinished: {
|
|
27781
|
+
type: 'boolean',
|
|
27782
|
+
description: 'When true, include completed, failed, and cancelled rows in addition to active timeouts.',
|
|
27783
|
+
},
|
|
27784
|
+
limit: {
|
|
27785
|
+
type: 'number',
|
|
27786
|
+
description: 'Maximum number of rows to return (default 20, max 100).',
|
|
27787
|
+
},
|
|
27788
|
+
},
|
|
27789
|
+
},
|
|
27790
|
+
});
|
|
27791
|
+
}
|
|
27725
27792
|
return tools;
|
|
27726
27793
|
}
|
|
27727
27794
|
|
|
27728
27795
|
/**
|
|
27729
27796
|
* `USE TIMEOUT` commitment definition.
|
|
27730
27797
|
*
|
|
27731
|
-
* The `USE TIMEOUT` commitment enables
|
|
27798
|
+
* The `USE TIMEOUT` commitment enables timeout wake-ups and scoped timeout management.
|
|
27732
27799
|
*
|
|
27733
27800
|
* @private [🪔] Maybe export the commitments through some package
|
|
27734
27801
|
*/
|
|
@@ -27743,7 +27810,7 @@ class UseTimeoutCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
27743
27810
|
* Short one-line description of `USE TIMEOUT`.
|
|
27744
27811
|
*/
|
|
27745
27812
|
get description() {
|
|
27746
|
-
return 'Enable
|
|
27813
|
+
return 'Enable timeout wake-ups plus scoped timeout listing/cancellation across chats.';
|
|
27747
27814
|
}
|
|
27748
27815
|
/**
|
|
27749
27816
|
* Icon for this commitment.
|
|
@@ -27758,14 +27825,15 @@ class UseTimeoutCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
27758
27825
|
return spaceTrim$1(`
|
|
27759
27826
|
# USE TIMEOUT
|
|
27760
27827
|
|
|
27761
|
-
Enables
|
|
27828
|
+
Enables timeout wake-ups and timeout management for the same user+agent scope.
|
|
27762
27829
|
|
|
27763
27830
|
## Key aspects
|
|
27764
27831
|
|
|
27765
27832
|
- The agent uses \`set_timeout\` to schedule a future wake-up in the same chat thread.
|
|
27766
27833
|
- The tool returns immediately while the timeout is stored and executed by the runtime later.
|
|
27767
27834
|
- The wake-up arrives as a new user-like timeout message in the same conversation.
|
|
27768
|
-
- The agent can
|
|
27835
|
+
- The agent can inspect known timeouts via \`list_timeouts\`.
|
|
27836
|
+
- The agent can cancel an existing timeout by \`timeoutId\` via \`cancel_timeout\`, including timeouts created in another chat.
|
|
27769
27837
|
- Commitment content is treated as optional timeout policy instructions.
|
|
27770
27838
|
|
|
27771
27839
|
## Examples
|
|
@@ -27794,6 +27862,7 @@ class UseTimeoutCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
27794
27862
|
return {
|
|
27795
27863
|
[TimeoutToolNames.set]: 'Set timer',
|
|
27796
27864
|
[TimeoutToolNames.cancel]: 'Cancel timer',
|
|
27865
|
+
[TimeoutToolNames.list]: 'List timers',
|
|
27797
27866
|
};
|
|
27798
27867
|
}
|
|
27799
27868
|
/**
|
|
@@ -29206,7 +29275,7 @@ function computeAgentHash(agentSource) {
|
|
|
29206
29275
|
* @public exported from `@promptbook/core`
|
|
29207
29276
|
*/
|
|
29208
29277
|
function normalizeAgentName(rawAgentName) {
|
|
29209
|
-
return titleToName(spaceTrim$
|
|
29278
|
+
return titleToName(spaceTrim$1(rawAgentName));
|
|
29210
29279
|
}
|
|
29211
29280
|
|
|
29212
29281
|
/**
|
|
@@ -29381,7 +29450,7 @@ function parseAgentSource(agentSource) {
|
|
|
29381
29450
|
continue;
|
|
29382
29451
|
}
|
|
29383
29452
|
if (commitment.type === 'FROM') {
|
|
29384
|
-
const content = spaceTrim$
|
|
29453
|
+
const content = spaceTrim$1(commitment.content).split(/\r?\n/)[0] || '';
|
|
29385
29454
|
if (content === 'Adam' || content === '' /* <- Note: Adam is implicit */) {
|
|
29386
29455
|
continue;
|
|
29387
29456
|
}
|
|
@@ -29404,7 +29473,7 @@ function parseAgentSource(agentSource) {
|
|
|
29404
29473
|
continue;
|
|
29405
29474
|
}
|
|
29406
29475
|
if (commitment.type === 'IMPORT') {
|
|
29407
|
-
const content = spaceTrim$
|
|
29476
|
+
const content = spaceTrim$1(commitment.content).split(/\r?\n/)[0] || '';
|
|
29408
29477
|
let label = content;
|
|
29409
29478
|
let iconName = 'ExternalLink'; // Import remote
|
|
29410
29479
|
try {
|
|
@@ -29442,7 +29511,7 @@ function parseAgentSource(agentSource) {
|
|
|
29442
29511
|
continue;
|
|
29443
29512
|
}
|
|
29444
29513
|
if (commitment.type === 'KNOWLEDGE') {
|
|
29445
|
-
const content = spaceTrim$
|
|
29514
|
+
const content = spaceTrim$1(commitment.content);
|
|
29446
29515
|
const extractedUrls = extractUrlsFromText(content);
|
|
29447
29516
|
let label = content;
|
|
29448
29517
|
let iconName = 'Book';
|
|
@@ -29501,7 +29570,7 @@ function parseAgentSource(agentSource) {
|
|
|
29501
29570
|
continue;
|
|
29502
29571
|
}
|
|
29503
29572
|
if (commitment.type === 'META LINK') {
|
|
29504
|
-
const linkValue = spaceTrim$
|
|
29573
|
+
const linkValue = spaceTrim$1(commitment.content);
|
|
29505
29574
|
links.push(linkValue);
|
|
29506
29575
|
meta.link = linkValue;
|
|
29507
29576
|
continue;
|
|
@@ -29511,11 +29580,11 @@ function parseAgentSource(agentSource) {
|
|
|
29511
29580
|
continue;
|
|
29512
29581
|
}
|
|
29513
29582
|
if (commitment.type === 'META IMAGE') {
|
|
29514
|
-
meta.image = spaceTrim$
|
|
29583
|
+
meta.image = spaceTrim$1(commitment.content);
|
|
29515
29584
|
continue;
|
|
29516
29585
|
}
|
|
29517
29586
|
if (commitment.type === 'META DESCRIPTION') {
|
|
29518
|
-
meta.description = spaceTrim$
|
|
29587
|
+
meta.description = spaceTrim$1(commitment.content);
|
|
29519
29588
|
continue;
|
|
29520
29589
|
}
|
|
29521
29590
|
if (commitment.type === 'META DISCLAIMER') {
|
|
@@ -29523,7 +29592,7 @@ function parseAgentSource(agentSource) {
|
|
|
29523
29592
|
continue;
|
|
29524
29593
|
}
|
|
29525
29594
|
if (commitment.type === 'META INPUT PLACEHOLDER') {
|
|
29526
|
-
meta.inputPlaceholder = spaceTrim$
|
|
29595
|
+
meta.inputPlaceholder = spaceTrim$1(commitment.content);
|
|
29527
29596
|
continue;
|
|
29528
29597
|
}
|
|
29529
29598
|
if (commitment.type === 'MESSAGE SUFFIX') {
|
|
@@ -29539,7 +29608,7 @@ function parseAgentSource(agentSource) {
|
|
|
29539
29608
|
continue;
|
|
29540
29609
|
}
|
|
29541
29610
|
if (commitment.type === 'META VOICE') {
|
|
29542
|
-
meta.voice = spaceTrim$
|
|
29611
|
+
meta.voice = spaceTrim$1(commitment.content);
|
|
29543
29612
|
continue;
|
|
29544
29613
|
}
|
|
29545
29614
|
if (commitment.type !== 'META') {
|
|
@@ -29548,10 +29617,10 @@ function parseAgentSource(agentSource) {
|
|
|
29548
29617
|
// Parse META commitments - format is "META TYPE content"
|
|
29549
29618
|
const metaTypeRaw = commitment.content.split(' ')[0] || 'NONE';
|
|
29550
29619
|
if (metaTypeRaw === 'LINK') {
|
|
29551
|
-
links.push(spaceTrim$
|
|
29620
|
+
links.push(spaceTrim$1(commitment.content.substring(metaTypeRaw.length)));
|
|
29552
29621
|
}
|
|
29553
29622
|
const metaType = normalizeTo_camelCase(metaTypeRaw);
|
|
29554
|
-
meta[metaType] = spaceTrim$
|
|
29623
|
+
meta[metaType] = spaceTrim$1(commitment.content.substring(metaTypeRaw.length));
|
|
29555
29624
|
}
|
|
29556
29625
|
// Generate fullname fallback if no meta fullname specified
|
|
29557
29626
|
if (!meta.fullname) {
|
|
@@ -29582,7 +29651,7 @@ function parseAgentSource(agentSource) {
|
|
|
29582
29651
|
* @returns The content with normalized separators
|
|
29583
29652
|
*/
|
|
29584
29653
|
function normalizeSeparator(content) {
|
|
29585
|
-
const trimmed = spaceTrim$
|
|
29654
|
+
const trimmed = spaceTrim$1(content);
|
|
29586
29655
|
if (trimmed.includes(',')) {
|
|
29587
29656
|
return trimmed;
|
|
29588
29657
|
}
|
|
@@ -29595,7 +29664,7 @@ function normalizeSeparator(content) {
|
|
|
29595
29664
|
* @returns Normalized domain or a trimmed fallback.
|
|
29596
29665
|
*/
|
|
29597
29666
|
function normalizeMetaDomain(content) {
|
|
29598
|
-
const trimmed = spaceTrim$
|
|
29667
|
+
const trimmed = spaceTrim$1(content);
|
|
29599
29668
|
return normalizeDomainForMatching(trimmed) || trimmed.toLowerCase();
|
|
29600
29669
|
}
|
|
29601
29670
|
/**
|
|
@@ -29743,7 +29812,7 @@ const OpenAiSdkTranspiler = {
|
|
|
29743
29812
|
}
|
|
29744
29813
|
const KNOWLEDGE_THRESHOLD = 1000;
|
|
29745
29814
|
if (directKnowledge.join('\n').length > KNOWLEDGE_THRESHOLD || knowledgeSources.length > 0) {
|
|
29746
|
-
return spaceTrim$
|
|
29815
|
+
return spaceTrim$1((block) => `
|
|
29747
29816
|
#!/usr/bin/env node
|
|
29748
29817
|
|
|
29749
29818
|
import * as dotenv from 'dotenv';
|
|
@@ -29818,7 +29887,7 @@ const OpenAiSdkTranspiler = {
|
|
|
29818
29887
|
|
|
29819
29888
|
if (context) {
|
|
29820
29889
|
question = spaceTrim(\`
|
|
29821
|
-
${block(spaceTrim$
|
|
29890
|
+
${block(spaceTrim$1(`
|
|
29822
29891
|
Here is some additional context to help you answer the question:
|
|
29823
29892
|
\${context}
|
|
29824
29893
|
|
|
@@ -29899,7 +29968,7 @@ const OpenAiSdkTranspiler = {
|
|
|
29899
29968
|
})();
|
|
29900
29969
|
`);
|
|
29901
29970
|
}
|
|
29902
|
-
const source = spaceTrim$
|
|
29971
|
+
const source = spaceTrim$1((block) => `
|
|
29903
29972
|
|
|
29904
29973
|
#!/usr/bin/env node
|
|
29905
29974
|
|
|
@@ -30176,901 +30245,301 @@ async function fetchUrlContent(url) {
|
|
|
30176
30245
|
*/
|
|
30177
30246
|
|
|
30178
30247
|
/**
|
|
30179
|
-
*
|
|
30248
|
+
* Cached implementation of `run_browser` when it can be resolved.
|
|
30180
30249
|
*
|
|
30181
|
-
*
|
|
30182
|
-
*/
|
|
30183
|
-
const RUN_BROWSER_ARTIFACT_PUBLIC_DIRECTORY = '.playwright-cli';
|
|
30184
|
-
/**
|
|
30185
|
-
* Runtime environment variable that overrides local artifact storage directory.
|
|
30186
|
-
*/
|
|
30187
|
-
const RUN_BROWSER_ARTIFACT_STORAGE_DIRECTORY_ENV = 'RUN_BROWSER_ARTIFACT_STORAGE_DIRECTORY';
|
|
30188
|
-
/**
|
|
30189
|
-
* Default writable directory for `run_browser` screenshot/video artifacts.
|
|
30250
|
+
* @private internal utility for USE BROWSER commitment
|
|
30190
30251
|
*/
|
|
30191
|
-
|
|
30252
|
+
let cachedRunBrowserTool = null;
|
|
30192
30253
|
/**
|
|
30193
|
-
*
|
|
30254
|
+
* Cached loading error to avoid repeating expensive resolution attempts.
|
|
30255
|
+
*
|
|
30256
|
+
* @private internal utility for USE BROWSER commitment
|
|
30194
30257
|
*/
|
|
30195
|
-
|
|
30196
|
-
return pathname.split('\\').join('/');
|
|
30197
|
-
}
|
|
30258
|
+
let cachedRunBrowserToolError = null;
|
|
30198
30259
|
/**
|
|
30199
|
-
*
|
|
30260
|
+
* Attempts to load the server-side `run_browser` tool lazily.
|
|
30261
|
+
*
|
|
30262
|
+
* @returns Loaded `run_browser` implementation
|
|
30263
|
+
* @private internal utility for USE BROWSER commitment
|
|
30200
30264
|
*/
|
|
30201
|
-
function
|
|
30202
|
-
|
|
30203
|
-
|
|
30204
|
-
return configuredStorageDirectory.trim();
|
|
30265
|
+
function loadRunBrowserToolForNode() {
|
|
30266
|
+
if (cachedRunBrowserTool !== null) {
|
|
30267
|
+
return cachedRunBrowserTool;
|
|
30205
30268
|
}
|
|
30206
|
-
|
|
30207
|
-
|
|
30208
|
-
|
|
30209
|
-
|
|
30210
|
-
|
|
30211
|
-
|
|
30212
|
-
|
|
30213
|
-
|
|
30214
|
-
|
|
30215
|
-
|
|
30216
|
-
|
|
30217
|
-
|
|
30218
|
-
|
|
30219
|
-
|
|
30220
|
-
|
|
30221
|
-
|
|
30222
|
-
* Error code used for remote-browser infrastructure outages.
|
|
30223
|
-
*/
|
|
30224
|
-
const REMOTE_BROWSER_UNAVAILABLE_ERROR_CODE = 'REMOTE_BROWSER_UNAVAILABLE';
|
|
30225
|
-
/**
|
|
30226
|
-
* Error thrown when a remote Playwright browser cannot be reached.
|
|
30227
|
-
*/
|
|
30228
|
-
class RemoteBrowserUnavailableError extends KnowledgeScrapeError {
|
|
30229
|
-
constructor(options) {
|
|
30230
|
-
var _a;
|
|
30231
|
-
super(options.message);
|
|
30232
|
-
this.code = REMOTE_BROWSER_UNAVAILABLE_ERROR_CODE;
|
|
30233
|
-
this.isRetryable = true;
|
|
30234
|
-
this.debug = options.debug;
|
|
30235
|
-
this.suggestedNextSteps =
|
|
30236
|
-
(_a = options.suggestedNextSteps) !== null && _a !== void 0 ? _a : [
|
|
30237
|
-
'Verify remote browser infrastructure is running and reachable from Agents Server.',
|
|
30238
|
-
'Check firewall and DNS routing for the remote browser host and port.',
|
|
30239
|
-
'Retry later or continue with non-graphical fallback scraping.',
|
|
30240
|
-
];
|
|
30241
|
-
this.cause = options.cause;
|
|
30242
|
-
Object.setPrototypeOf(this, RemoteBrowserUnavailableError.prototype);
|
|
30269
|
+
if (cachedRunBrowserToolError !== null) {
|
|
30270
|
+
throw cachedRunBrowserToolError;
|
|
30271
|
+
}
|
|
30272
|
+
try {
|
|
30273
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
30274
|
+
const runBrowserModule = require('../../../apps/agents-server/src/tools/run_browser');
|
|
30275
|
+
if (typeof runBrowserModule.run_browser !== 'function') {
|
|
30276
|
+
throw new Error('run_browser value is not a function but ' + typeof runBrowserModule.run_browser);
|
|
30277
|
+
}
|
|
30278
|
+
cachedRunBrowserTool = runBrowserModule.run_browser;
|
|
30279
|
+
return cachedRunBrowserTool;
|
|
30280
|
+
}
|
|
30281
|
+
catch (error) {
|
|
30282
|
+
assertsError(error);
|
|
30283
|
+
cachedRunBrowserToolError = error;
|
|
30284
|
+
throw error;
|
|
30243
30285
|
}
|
|
30244
30286
|
}
|
|
30245
30287
|
/**
|
|
30246
|
-
*
|
|
30288
|
+
* Resolves the server-side implementation of the `run_browser` tool for Node.js environments.
|
|
30289
|
+
*
|
|
30290
|
+
* This uses fully lazy resolution to keep CLI startup independent from optional browser tooling.
|
|
30291
|
+
* When the server tool cannot be resolved, the fallback implementation throws a helpful error.
|
|
30292
|
+
*
|
|
30293
|
+
* @private internal utility for USE BROWSER commitment
|
|
30247
30294
|
*/
|
|
30248
|
-
function
|
|
30249
|
-
return
|
|
30295
|
+
function resolveRunBrowserToolForNode() {
|
|
30296
|
+
return async (args) => {
|
|
30297
|
+
try {
|
|
30298
|
+
const runBrowserTool = loadRunBrowserToolForNode();
|
|
30299
|
+
return await runBrowserTool(args);
|
|
30300
|
+
}
|
|
30301
|
+
catch (error) {
|
|
30302
|
+
assertsError(error);
|
|
30303
|
+
throw new EnvironmentMismatchError(spaceTrim$1((block) => `
|
|
30304
|
+
\`run_browser\` tool is not available in this environment.
|
|
30305
|
+
This commitment requires the Agents Server browser runtime with Playwright CLI.
|
|
30306
|
+
|
|
30307
|
+
${error.name}:
|
|
30308
|
+
${block(error.message)}
|
|
30309
|
+
`));
|
|
30310
|
+
}
|
|
30311
|
+
};
|
|
30250
30312
|
}
|
|
30313
|
+
|
|
30251
30314
|
/**
|
|
30252
|
-
*
|
|
30315
|
+
* Resolves the server-side implementation of the send_email tool for Node.js environments.
|
|
30316
|
+
*
|
|
30317
|
+
* This uses a lazy require so the core package can still load even if the Agents Server
|
|
30318
|
+
* module is unavailable. When the server tool cannot be resolved, a fallback implementation
|
|
30319
|
+
* throws a helpful error message.
|
|
30320
|
+
*
|
|
30321
|
+
* @private internal utility for USE EMAIL commitment
|
|
30253
30322
|
*/
|
|
30254
|
-
function
|
|
30255
|
-
var _a, _b;
|
|
30323
|
+
function resolveSendEmailToolForNode() {
|
|
30256
30324
|
try {
|
|
30257
|
-
|
|
30258
|
-
|
|
30259
|
-
|
|
30260
|
-
|
|
30261
|
-
|
|
30262
|
-
|
|
30325
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
30326
|
+
const { send_email } = require('../../../apps/agents-server/src/tools/send_email');
|
|
30327
|
+
if (typeof send_email !== 'function') {
|
|
30328
|
+
throw new Error('send_email value is not a function but ' + typeof send_email);
|
|
30329
|
+
}
|
|
30330
|
+
return send_email;
|
|
30263
30331
|
}
|
|
30264
|
-
catch (
|
|
30265
|
-
const
|
|
30266
|
-
|
|
30267
|
-
|
|
30268
|
-
return {
|
|
30269
|
-
|
|
30270
|
-
|
|
30271
|
-
|
|
30332
|
+
catch (error) {
|
|
30333
|
+
const normalizedError = error instanceof Error
|
|
30334
|
+
? error
|
|
30335
|
+
: new Error(typeof error === 'string' ? error : JSON.stringify(error !== null && error !== void 0 ? error : 'Unknown error'));
|
|
30336
|
+
return async () => {
|
|
30337
|
+
throw new EnvironmentMismatchError(spaceTrim$1((block) => `
|
|
30338
|
+
\`send_email\` tool is not available in this environment.
|
|
30339
|
+
This commitment requires Agents Server runtime with wallet-backed SMTP sending.
|
|
30340
|
+
|
|
30341
|
+
${normalizedError.name}:
|
|
30342
|
+
${block(normalizedError.message)}
|
|
30343
|
+
`));
|
|
30272
30344
|
};
|
|
30273
30345
|
}
|
|
30274
30346
|
}
|
|
30347
|
+
|
|
30275
30348
|
/**
|
|
30276
|
-
*
|
|
30349
|
+
* Resolves the server-side `spawn_agent` tool for Node.js runtimes.
|
|
30350
|
+
*
|
|
30351
|
+
* Uses lazy require so core package can load outside Agents Server.
|
|
30352
|
+
*
|
|
30353
|
+
* @private internal utility for USE SPAWN commitment
|
|
30277
30354
|
*/
|
|
30278
|
-
function
|
|
30279
|
-
|
|
30280
|
-
|
|
30281
|
-
const
|
|
30282
|
-
if (typeof
|
|
30283
|
-
|
|
30355
|
+
function resolveSpawnAgentToolForNode() {
|
|
30356
|
+
try {
|
|
30357
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
30358
|
+
const { spawn_agent } = require('../../../apps/agents-server/src/tools/spawn_agent');
|
|
30359
|
+
if (typeof spawn_agent !== 'function') {
|
|
30360
|
+
throw new Error('spawn_agent value is not a function but ' + typeof spawn_agent);
|
|
30284
30361
|
}
|
|
30362
|
+
return spawn_agent;
|
|
30285
30363
|
}
|
|
30286
|
-
|
|
30287
|
-
|
|
30288
|
-
|
|
30289
|
-
|
|
30290
|
-
|
|
30291
|
-
|
|
30292
|
-
|
|
30293
|
-
|
|
30294
|
-
|
|
30295
|
-
|
|
30296
|
-
|
|
30364
|
+
catch (error) {
|
|
30365
|
+
const normalizedError = error instanceof Error
|
|
30366
|
+
? error
|
|
30367
|
+
: new Error(typeof error === 'string' ? error : JSON.stringify(error !== null && error !== void 0 ? error : 'Unknown error'));
|
|
30368
|
+
return async () => {
|
|
30369
|
+
throw new EnvironmentMismatchError(spaceTrim$1((block) => `
|
|
30370
|
+
\`spawn_agent\` tool is not available in this environment.
|
|
30371
|
+
This commitment requires Agents Server runtime with agent persistence enabled.
|
|
30372
|
+
|
|
30373
|
+
${normalizedError.name}:
|
|
30374
|
+
${block(normalizedError.message)}
|
|
30375
|
+
`));
|
|
30376
|
+
};
|
|
30297
30377
|
}
|
|
30298
|
-
const message = getErrorMessage(error).toLowerCase();
|
|
30299
|
-
const isWebSocketFailure = message.includes('websocket') ||
|
|
30300
|
-
message.includes('<ws error>') ||
|
|
30301
|
-
message.includes('ws connect error') ||
|
|
30302
|
-
message.includes('socket hang up');
|
|
30303
|
-
const hasHandshakeFailure = message.includes('unexpected server response') ||
|
|
30304
|
-
message.includes('handshake') ||
|
|
30305
|
-
message.includes('code=1006') ||
|
|
30306
|
-
message.includes('disconnected');
|
|
30307
|
-
return isWebSocketFailure && hasHandshakeFailure;
|
|
30308
|
-
}
|
|
30309
|
-
/**
|
|
30310
|
-
* Converts unknown thrown values into safe string messages.
|
|
30311
|
-
*/
|
|
30312
|
-
function getErrorMessage(error) {
|
|
30313
|
-
return error instanceof Error ? error.message : String(error);
|
|
30314
|
-
}
|
|
30315
|
-
/**
|
|
30316
|
-
* Converts unknown errors into stack payloads that are safe to render in debug mode.
|
|
30317
|
-
*/
|
|
30318
|
-
function getErrorStack(error) {
|
|
30319
|
-
return error instanceof Error && error.stack ? error.stack : null;
|
|
30320
30378
|
}
|
|
30321
30379
|
|
|
30322
30380
|
/**
|
|
30323
|
-
*
|
|
30324
|
-
|
|
30325
|
-
|
|
30326
|
-
|
|
30327
|
-
* Creates one filesystem-safe optional filename suffix for a snapshot.
|
|
30381
|
+
* Collects tool functions from all commitment definitions.
|
|
30382
|
+
*
|
|
30383
|
+
* @returns Map of tool function implementations.
|
|
30384
|
+
* @private internal helper for commitment tool registry
|
|
30328
30385
|
*/
|
|
30329
|
-
function
|
|
30330
|
-
|
|
30331
|
-
|
|
30386
|
+
function collectCommitmentToolFunctions() {
|
|
30387
|
+
const allToolFunctions = {};
|
|
30388
|
+
for (const commitmentDefinition of getAllCommitmentDefinitions()) {
|
|
30389
|
+
const toolFunctions = commitmentDefinition.getToolFunctions();
|
|
30390
|
+
for (const [funcName, funcImpl] of Object.entries(toolFunctions)) {
|
|
30391
|
+
if (allToolFunctions[funcName] !== undefined &&
|
|
30392
|
+
just(false) /* <- Note: [??] How to deal with commitment aliases */) {
|
|
30393
|
+
throw new UnexpectedError(`Duplicate tool function name detected: \`${funcName}\` provided by commitment \`${commitmentDefinition.type}\``);
|
|
30394
|
+
}
|
|
30395
|
+
allToolFunctions[funcName] = funcImpl;
|
|
30396
|
+
}
|
|
30332
30397
|
}
|
|
30333
|
-
|
|
30334
|
-
.trim()
|
|
30335
|
-
.toLowerCase()
|
|
30336
|
-
.replace(/\s+/g, '-')
|
|
30337
|
-
.replace(SNAPSHOT_FILE_SUFFIX_UNSAFE_CHARACTER_PATTERN, '-')
|
|
30338
|
-
.replace(/-+/g, '-')
|
|
30339
|
-
.replace(/^-|-$/g, '');
|
|
30340
|
-
return normalized;
|
|
30341
|
-
}
|
|
30342
|
-
/**
|
|
30343
|
-
* Resolves snapshot filename for one session and optional stage suffix.
|
|
30344
|
-
*/
|
|
30345
|
-
function resolveSnapshotFilename(sessionId, fileSuffix) {
|
|
30346
|
-
const safeSuffix = createSnapshotFileSuffix(fileSuffix);
|
|
30347
|
-
return safeSuffix ? `${sessionId}-${safeSuffix}.png` : `${sessionId}.png`;
|
|
30398
|
+
return allToolFunctions;
|
|
30348
30399
|
}
|
|
30349
30400
|
/**
|
|
30350
|
-
* Creates
|
|
30401
|
+
* Creates a proxy that resolves tool functions on demand.
|
|
30402
|
+
*
|
|
30403
|
+
* @param getFunctions - Provider of current tool functions.
|
|
30404
|
+
* @returns Proxy exposing tool functions as properties.
|
|
30405
|
+
* @private internal helper for commitment tool registry
|
|
30351
30406
|
*/
|
|
30352
|
-
function
|
|
30353
|
-
|
|
30354
|
-
|
|
30355
|
-
|
|
30356
|
-
|
|
30357
|
-
|
|
30358
|
-
|
|
30359
|
-
return
|
|
30360
|
-
|
|
30361
|
-
|
|
30362
|
-
|
|
30363
|
-
|
|
30364
|
-
|
|
30407
|
+
function createToolFunctionsProxy(getFunctions) {
|
|
30408
|
+
const resolveFunctions = () => getFunctions();
|
|
30409
|
+
return new Proxy({}, {
|
|
30410
|
+
get(_target, prop) {
|
|
30411
|
+
if (typeof prop !== 'string') {
|
|
30412
|
+
return undefined;
|
|
30413
|
+
}
|
|
30414
|
+
return resolveFunctions()[prop];
|
|
30415
|
+
},
|
|
30416
|
+
has(_target, prop) {
|
|
30417
|
+
if (typeof prop !== 'string') {
|
|
30418
|
+
return false;
|
|
30419
|
+
}
|
|
30420
|
+
return prop in resolveFunctions();
|
|
30421
|
+
},
|
|
30422
|
+
ownKeys() {
|
|
30423
|
+
return Object.keys(resolveFunctions());
|
|
30424
|
+
},
|
|
30425
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
30426
|
+
if (typeof prop !== 'string') {
|
|
30427
|
+
return undefined;
|
|
30428
|
+
}
|
|
30429
|
+
const value = resolveFunctions()[prop];
|
|
30430
|
+
if (value === undefined) {
|
|
30431
|
+
return undefined;
|
|
30432
|
+
}
|
|
30433
|
+
return {
|
|
30434
|
+
enumerable: true,
|
|
30435
|
+
configurable: true,
|
|
30436
|
+
writable: false,
|
|
30437
|
+
value,
|
|
30438
|
+
};
|
|
30439
|
+
},
|
|
30440
|
+
});
|
|
30365
30441
|
}
|
|
30366
30442
|
/**
|
|
30367
|
-
*
|
|
30368
|
-
*
|
|
30369
|
-
* @private function of `run_browser`
|
|
30443
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
30370
30444
|
*/
|
|
30371
|
-
|
|
30445
|
+
|
|
30446
|
+
const nodeToolFunctions = {
|
|
30372
30447
|
/**
|
|
30373
|
-
*
|
|
30448
|
+
* @@@
|
|
30449
|
+
*
|
|
30450
|
+
* Note: [??] This function has implementation both for browser and node, this is the full one for node
|
|
30374
30451
|
*/
|
|
30375
|
-
async
|
|
30376
|
-
|
|
30377
|
-
const
|
|
30378
|
-
|
|
30379
|
-
try {
|
|
30380
|
-
await mkdir(snapshotDirectoryPath, { recursive: true });
|
|
30381
|
-
try {
|
|
30382
|
-
await page.screenshot({ path: snapshotPath, fullPage: true });
|
|
30383
|
-
}
|
|
30384
|
-
catch (error) {
|
|
30385
|
-
console.warn('[run_browser] Full-page snapshot failed, retrying viewport-only screenshot', {
|
|
30386
|
-
sessionId,
|
|
30387
|
-
snapshotFilename,
|
|
30388
|
-
error: getErrorMessage(error),
|
|
30389
|
-
});
|
|
30390
|
-
await page.screenshot({ path: snapshotPath, fullPage: false });
|
|
30391
|
-
}
|
|
30392
|
-
return resolveRunBrowserArtifactPublicPath(snapshotFilename);
|
|
30393
|
-
}
|
|
30394
|
-
catch (error) {
|
|
30395
|
-
console.error('[run_browser] Failed to capture snapshot', {
|
|
30396
|
-
sessionId,
|
|
30397
|
-
snapshotFilename,
|
|
30398
|
-
error: getErrorMessage(error),
|
|
30399
|
-
});
|
|
30400
|
-
return null;
|
|
30401
|
-
}
|
|
30452
|
+
async fetch_url_content(args) {
|
|
30453
|
+
console.log('!!!! [Tool] fetch_url_content called', { args });
|
|
30454
|
+
const { url } = args;
|
|
30455
|
+
return await fetchUrlContent(url);
|
|
30402
30456
|
},
|
|
30403
30457
|
/**
|
|
30404
|
-
*
|
|
30458
|
+
* @@@
|
|
30459
|
+
*
|
|
30460
|
+
* Note: [??] This function has implementation both for browser and node, this is the server one for node
|
|
30405
30461
|
*/
|
|
30406
|
-
|
|
30407
|
-
try {
|
|
30408
|
-
return await page.title();
|
|
30409
|
-
}
|
|
30410
|
-
catch (_a) {
|
|
30411
|
-
return null;
|
|
30412
|
-
}
|
|
30413
|
-
},
|
|
30462
|
+
run_browser: resolveRunBrowserToolForNode(),
|
|
30414
30463
|
/**
|
|
30415
|
-
*
|
|
30464
|
+
* @@@
|
|
30465
|
+
*
|
|
30466
|
+
* Note: [??] This function has implementation both for browser and node, this is the server one for node
|
|
30416
30467
|
*/
|
|
30417
|
-
|
|
30418
|
-
if (!page) {
|
|
30419
|
-
return;
|
|
30420
|
-
}
|
|
30421
|
-
try {
|
|
30422
|
-
await page.close();
|
|
30423
|
-
}
|
|
30424
|
-
catch (error) {
|
|
30425
|
-
console.error('[run_browser] Failed to cleanup browser page', {
|
|
30426
|
-
sessionId,
|
|
30427
|
-
error: getErrorMessage(error),
|
|
30428
|
-
});
|
|
30429
|
-
}
|
|
30430
|
-
},
|
|
30468
|
+
send_email: resolveSendEmailToolForNode(),
|
|
30431
30469
|
/**
|
|
30432
|
-
*
|
|
30470
|
+
* @@@
|
|
30471
|
+
*
|
|
30472
|
+
* Note: [??] This function has implementation both for browser and node, this is the server one for node
|
|
30433
30473
|
*/
|
|
30434
|
-
|
|
30435
|
-
|
|
30436
|
-
const path = await this.captureSnapshot(page, sessionId, fileSuffix);
|
|
30437
|
-
if (!path) {
|
|
30438
|
-
return null;
|
|
30439
|
-
}
|
|
30440
|
-
const actionSummary = action ? formatActionSummary(action) : undefined;
|
|
30441
|
-
return {
|
|
30442
|
-
kind: 'screenshot',
|
|
30443
|
-
label,
|
|
30444
|
-
path,
|
|
30445
|
-
capturedAt: new Date().toISOString(),
|
|
30446
|
-
url: page.url(),
|
|
30447
|
-
title: await this.getPageTitle(page),
|
|
30448
|
-
actionIndex,
|
|
30449
|
-
actionSummary,
|
|
30450
|
-
};
|
|
30451
|
-
},
|
|
30452
|
-
};
|
|
30453
|
-
|
|
30454
|
-
/**
|
|
30455
|
-
* Shared constants used by the `run_browser` tool.
|
|
30456
|
-
*
|
|
30457
|
-
* @private internal constants of `run_browser`
|
|
30458
|
-
*/
|
|
30459
|
-
const runBrowserConstants = {
|
|
30460
|
-
sessionPrefix: 'agents-server-run-browser',
|
|
30461
|
-
snapshotDirectory: '.playwright-cli',
|
|
30462
|
-
resultSchema: 'promptbook/run-browser@1',
|
|
30463
|
-
defaultWaitMs: 1000,
|
|
30464
|
-
maxWaitMs: 60000,
|
|
30465
|
-
defaultScrollPixels: 800,
|
|
30466
|
-
defaultNavigationTimeoutMs: 20000,
|
|
30467
|
-
defaultActionTimeoutMs: 15000,
|
|
30468
|
-
fallbackDynamicContentWarning: 'Remote browser is unavailable. Fallback scraping was used and dynamic content may be missing.',
|
|
30469
|
-
validationErrorCode: 'RUN_BROWSER_VALIDATION_ERROR',
|
|
30470
|
-
navigationFailedErrorCode: 'RUN_BROWSER_NAVIGATION_FAILED',
|
|
30471
|
-
actionFailedErrorCode: 'RUN_BROWSER_ACTION_FAILED',
|
|
30472
|
-
cancelledErrorCode: 'RUN_BROWSER_CANCELLED',
|
|
30473
|
-
unknownErrorCode: 'RUN_BROWSER_UNKNOWN_ERROR',
|
|
30474
|
+
spawn_agent: resolveSpawnAgentToolForNode(),
|
|
30475
|
+
// TODO: !!!! Unhardcode, make proper server function register from definitions
|
|
30474
30476
|
};
|
|
30475
|
-
|
|
30476
|
-
|
|
30477
|
-
...
|
|
30478
|
-
|
|
30479
|
-
// @see https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#exposing-environment-variables-to-the-browser
|
|
30480
|
-
NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL,
|
|
30481
|
-
NEXT_PUBLIC_VERCEL_ENV: process.env.NEXT_PUBLIC_VERCEL_ENV,
|
|
30482
|
-
NEXT_PUBLIC_VERCEL_TARGET_ENV: process.env.NEXT_PUBLIC_VERCEL_TARGET_ENV,
|
|
30483
|
-
NEXT_PUBLIC_VERCEL_URL: process.env.NEXT_PUBLIC_VERCEL_URL,
|
|
30484
|
-
NEXT_PUBLIC_VERCEL_BRANCH_URL: process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL,
|
|
30485
|
-
NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL: process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL,
|
|
30486
|
-
NEXT_PUBLIC_VERCEL_GIT_PROVIDER: process.env.NEXT_PUBLIC_VERCEL_GIT_PROVIDER,
|
|
30487
|
-
NEXT_PUBLIC_VERCEL_GIT_REPO_OWNER: process.env.NEXT_PUBLIC_VERCEL_GIT_REPO_OWNER,
|
|
30488
|
-
NEXT_PUBLIC_VERCEL_GIT_REPO_SLUG: process.env.NEXT_PUBLIC_VERCEL_GIT_REPO_SLUG,
|
|
30489
|
-
NEXT_PUBLIC_VERCEL_GIT_REPO_ID: process.env.NEXT_PUBLIC_VERCEL_GIT_REPO_ID,
|
|
30490
|
-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,
|
|
30491
|
-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE,
|
|
30492
|
-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF,
|
|
30493
|
-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME,
|
|
30494
|
-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_LOGIN: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_LOGIN,
|
|
30495
|
-
NEXT_PUBLIC_VERCEL_GIT_PREVIOUS_SHA: process.env.NEXT_PUBLIC_VERCEL_GIT_PREVIOUS_SHA,
|
|
30496
|
-
NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID: process.env.NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID,
|
|
30497
|
-
});
|
|
30477
|
+
const nodeToolFunctionsProxy = createToolFunctionsProxy(() => ({
|
|
30478
|
+
...collectCommitmentToolFunctions(),
|
|
30479
|
+
...nodeToolFunctions,
|
|
30480
|
+
}));
|
|
30498
30481
|
/**
|
|
30499
|
-
*
|
|
30482
|
+
* Gets all function implementations provided by all commitments
|
|
30500
30483
|
*
|
|
30501
|
-
* Note:
|
|
30502
|
-
*
|
|
30503
|
-
|
|
30504
|
-
config.get('NEXT_PUBLIC_SITE_URL').url().value;
|
|
30505
|
-
/**
|
|
30506
|
-
* [♐️] Vercel environment: "development" | "preview" | "production"
|
|
30507
|
-
*/
|
|
30508
|
-
config.get('NEXT_PUBLIC_VERCEL_ENV').value;
|
|
30509
|
-
/**
|
|
30510
|
-
* [♐️] Target environment – can be system or custom
|
|
30511
|
-
*/
|
|
30512
|
-
config.get('NEXT_PUBLIC_VERCEL_TARGET_ENV').value;
|
|
30513
|
-
/**
|
|
30514
|
-
* [♐️] Deployment URL (without https://), e.g. "my-app-abc123.vercel.app"
|
|
30515
|
-
*/
|
|
30516
|
-
config.get('NEXT_PUBLIC_VERCEL_URL').value;
|
|
30517
|
-
/**
|
|
30518
|
-
* [♐️] Branch URL (without https://), only for branch deployments
|
|
30519
|
-
*/
|
|
30520
|
-
config.get('NEXT_PUBLIC_VERCEL_BRANCH_URL').value;
|
|
30521
|
-
/**
|
|
30522
|
-
* [♐️] Production domain of the project
|
|
30523
|
-
*/
|
|
30524
|
-
config.get('NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL').value;
|
|
30525
|
-
/**
|
|
30526
|
-
* [♐️] Git provider (github | gitlab | bitbucket)
|
|
30527
|
-
*/
|
|
30528
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_PROVIDER').value;
|
|
30529
|
-
/**
|
|
30530
|
-
* [♐️] Repository owner (e.g. "hejny")
|
|
30531
|
-
*/
|
|
30532
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_REPO_OWNER').value;
|
|
30533
|
-
/**
|
|
30534
|
-
* [♐️] Repository slug (e.g. "my-project")
|
|
30535
|
-
*/
|
|
30536
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_REPO_SLUG').value;
|
|
30537
|
-
/**
|
|
30538
|
-
* [♐️] Repository internal ID
|
|
30539
|
-
*/
|
|
30540
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_REPO_ID').value;
|
|
30541
|
-
/**
|
|
30542
|
-
* [♐️] Git commit SHA (short or long)
|
|
30543
|
-
*/
|
|
30544
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA').value;
|
|
30545
|
-
/**
|
|
30546
|
-
* [♐️] Commit message used for this deployment
|
|
30547
|
-
*/
|
|
30548
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE').value;
|
|
30549
|
-
/**
|
|
30550
|
-
* [♐️] Branch name (ref), e.g. "main"
|
|
30551
|
-
*/
|
|
30552
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF').value;
|
|
30553
|
-
/**
|
|
30554
|
-
* Author name of the commit
|
|
30555
|
-
*/
|
|
30556
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME').value;
|
|
30557
|
-
/**
|
|
30558
|
-
* [♐️] Author login/username
|
|
30559
|
-
*/
|
|
30560
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_LOGIN').value;
|
|
30561
|
-
/**
|
|
30562
|
-
* [♐️] Previous deployment commit SHA (if exists)
|
|
30563
|
-
*/
|
|
30564
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_PREVIOUS_SHA').value;
|
|
30565
|
-
/**
|
|
30566
|
-
* [♐️] Pull Request ID for PR-based deployments
|
|
30484
|
+
* Note: This function is intended for server use, there is also equivalent `getAllCommitmentsToolFunctionsForBrowser` for browser use
|
|
30485
|
+
*
|
|
30486
|
+
* @public exported from `@promptbook/node`
|
|
30567
30487
|
*/
|
|
30568
|
-
|
|
30488
|
+
function getAllCommitmentsToolFunctionsForNode() {
|
|
30489
|
+
if (!$isRunningInNode()) {
|
|
30490
|
+
throw new EnvironmentMismatchError(spaceTrim(`
|
|
30491
|
+
Function getAllCommitmentsToolFunctionsForNode should be run in Node.js environment.
|
|
30492
|
+
|
|
30493
|
+
- In browser use getAllCommitmentsToolFunctionsForBrowser instead.
|
|
30494
|
+
- This function can include server-only tools which cannot run in browser environment.
|
|
30495
|
+
|
|
30496
|
+
`));
|
|
30497
|
+
}
|
|
30498
|
+
return nodeToolFunctionsProxy;
|
|
30499
|
+
}
|
|
30569
30500
|
/**
|
|
30570
|
-
*
|
|
30571
|
-
*
|
|
30572
|
-
* This remains the fallback/default prefix used before `_Server` contains records
|
|
30573
|
-
* or for local development requests.
|
|
30501
|
+
* Note: [??] Code in this file should never be never released in packages that could be imported into browser environment
|
|
30502
|
+
* TODO: [??] Unite `xxxForServer` and `xxxForNode` naming
|
|
30574
30503
|
*/
|
|
30575
|
-
|
|
30504
|
+
|
|
30576
30505
|
/**
|
|
30577
|
-
*
|
|
30506
|
+
* Attempts to locate the specified application on a Linux system using the 'which' command.
|
|
30507
|
+
* Returns the path to the executable if found, or null otherwise.
|
|
30578
30508
|
*
|
|
30579
|
-
*
|
|
30580
|
-
* This is useful for environments like Vercel where running a full browser locally is not possible.
|
|
30581
|
-
* Leave empty to use local browser mode.
|
|
30509
|
+
* @private within the repository
|
|
30582
30510
|
*/
|
|
30583
|
-
|
|
30511
|
+
async function locateAppOnLinux({ linuxWhich, }) {
|
|
30512
|
+
try {
|
|
30513
|
+
const result = await $execCommand({ crashOnError: true, command: `which ${linuxWhich}` });
|
|
30514
|
+
return result.trim();
|
|
30515
|
+
}
|
|
30516
|
+
catch (error) {
|
|
30517
|
+
assertsError(error);
|
|
30518
|
+
return null;
|
|
30519
|
+
}
|
|
30520
|
+
}
|
|
30584
30521
|
/**
|
|
30585
|
-
*
|
|
30586
|
-
*
|
|
30587
|
-
* When set, browser automation will connect to this remote server instead of launching a local browser.
|
|
30588
|
-
* This is useful for environments like Vercel where running a full browser locally is not possible.
|
|
30589
|
-
* Leave empty to use local browser mode.
|
|
30522
|
+
* TODO: [🧠][♿] Maybe export through `@promptbook/node`
|
|
30523
|
+
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
30590
30524
|
*/
|
|
30591
|
-
const REMOTE_BROWSER_URL = typeof rawRemoteBrowserUrl === 'string' ? rawRemoteBrowserUrl : '';
|
|
30592
30525
|
|
|
30593
30526
|
/**
|
|
30594
|
-
*
|
|
30527
|
+
* Checks if the file is executable
|
|
30528
|
+
*
|
|
30529
|
+
* @private within the repository
|
|
30595
30530
|
*/
|
|
30596
|
-
function
|
|
30597
|
-
|
|
30598
|
-
|
|
30599
|
-
return
|
|
30531
|
+
async function isExecutable(path, fs) {
|
|
30532
|
+
try {
|
|
30533
|
+
await fs.access(path, fs.constants.X_OK);
|
|
30534
|
+
return true;
|
|
30600
30535
|
}
|
|
30601
|
-
|
|
30602
|
-
|
|
30603
|
-
return defaultValue;
|
|
30536
|
+
catch (error) {
|
|
30537
|
+
return false;
|
|
30604
30538
|
}
|
|
30605
|
-
return parsed;
|
|
30606
30539
|
}
|
|
30607
30540
|
/**
|
|
30608
|
-
*
|
|
30609
|
-
*
|
|
30610
|
-
* @private function of `run_browser`
|
|
30611
|
-
*/
|
|
30612
|
-
const runBrowserRuntime = {
|
|
30613
|
-
/**
|
|
30614
|
-
* Creates a dedicated session id for one tool invocation.
|
|
30615
|
-
*/
|
|
30616
|
-
createRunBrowserSessionId() {
|
|
30617
|
-
return `${runBrowserConstants.sessionPrefix}-${randomUUID()}`;
|
|
30618
|
-
},
|
|
30619
|
-
/**
|
|
30620
|
-
* Determines whether the browser tool is running in local or remote mode.
|
|
30621
|
-
*/
|
|
30622
|
-
resolveExecutionMode() {
|
|
30623
|
-
return REMOTE_BROWSER_URL && REMOTE_BROWSER_URL.trim().length > 0 ? 'remote' : 'local';
|
|
30624
|
-
},
|
|
30625
|
-
/**
|
|
30626
|
-
* Converts the execution mode into a human-readable label.
|
|
30627
|
-
*/
|
|
30628
|
-
formatExecutionMode(mode) {
|
|
30629
|
-
return mode === 'remote' ? 'remote-browser' : 'local-browser';
|
|
30630
|
-
},
|
|
30631
|
-
/**
|
|
30632
|
-
* Resolves timeout configuration from env defaults and optional call overrides.
|
|
30633
|
-
*/
|
|
30634
|
-
resolveTimeoutConfiguration(overrides) {
|
|
30635
|
-
const envNavigationTimeoutMs = resolvePositiveIntFromEnv$1('RUN_BROWSER_NAVIGATION_TIMEOUT_MS', runBrowserConstants.defaultNavigationTimeoutMs);
|
|
30636
|
-
const envActionTimeoutMs = resolvePositiveIntFromEnv$1('RUN_BROWSER_ACTION_TIMEOUT_MS', runBrowserConstants.defaultActionTimeoutMs);
|
|
30637
|
-
const navigationTimeoutMs = (overrides === null || overrides === void 0 ? void 0 : overrides.navigationMs) && Number.isFinite(overrides.navigationMs) && overrides.navigationMs > 0
|
|
30638
|
-
? Math.floor(overrides.navigationMs)
|
|
30639
|
-
: envNavigationTimeoutMs;
|
|
30640
|
-
const actionTimeoutMs = (overrides === null || overrides === void 0 ? void 0 : overrides.actionMs) && Number.isFinite(overrides.actionMs) && overrides.actionMs > 0
|
|
30641
|
-
? Math.floor(overrides.actionMs)
|
|
30642
|
-
: envActionTimeoutMs;
|
|
30643
|
-
return {
|
|
30644
|
-
navigationTimeoutMs,
|
|
30645
|
-
actionTimeoutMs,
|
|
30646
|
-
};
|
|
30647
|
-
},
|
|
30648
|
-
};
|
|
30649
|
-
|
|
30650
|
-
/**
|
|
30651
|
-
* Error classification and cancellation helpers used by `run_browser`.
|
|
30652
|
-
*
|
|
30653
|
-
* @private function of `run_browser`
|
|
30654
|
-
*/
|
|
30655
|
-
const runBrowserErrorHandling = {
|
|
30656
|
-
/**
|
|
30657
|
-
* Creates one tagged ParseError used for deterministic input validation failures.
|
|
30658
|
-
*/
|
|
30659
|
-
createRunBrowserValidationError(options) {
|
|
30660
|
-
const error = new ParseError(options.message);
|
|
30661
|
-
error.name = 'RunBrowserValidationError';
|
|
30662
|
-
error.runBrowserCode = runBrowserConstants.validationErrorCode;
|
|
30663
|
-
error.isRetryable = false;
|
|
30664
|
-
error.suggestedNextSteps = [
|
|
30665
|
-
'Fix the action payload to match the run_browser schema.',
|
|
30666
|
-
'Check selectors and required action fields before retrying.',
|
|
30667
|
-
];
|
|
30668
|
-
error.debug = options.debug;
|
|
30669
|
-
return error;
|
|
30670
|
-
},
|
|
30671
|
-
/**
|
|
30672
|
-
* Creates one tagged KnowledgeScrapeError used for navigation failures.
|
|
30673
|
-
*/
|
|
30674
|
-
createRunBrowserNavigationError(options) {
|
|
30675
|
-
const error = new KnowledgeScrapeError(options.message);
|
|
30676
|
-
error.name = 'RunBrowserNavigationError';
|
|
30677
|
-
error.runBrowserCode = runBrowserConstants.navigationFailedErrorCode;
|
|
30678
|
-
error.isRetryable = false;
|
|
30679
|
-
error.suggestedNextSteps = [
|
|
30680
|
-
'Verify the URL is reachable and not blocked.',
|
|
30681
|
-
'Retry with a simpler action sequence.',
|
|
30682
|
-
];
|
|
30683
|
-
error.debug = options.debug;
|
|
30684
|
-
error.cause = options.cause;
|
|
30685
|
-
return error;
|
|
30686
|
-
},
|
|
30687
|
-
/**
|
|
30688
|
-
* Creates one tagged KnowledgeScrapeError used for action failures.
|
|
30689
|
-
*/
|
|
30690
|
-
createRunBrowserActionError(options) {
|
|
30691
|
-
const error = new KnowledgeScrapeError(options.message);
|
|
30692
|
-
error.name = 'RunBrowserActionError';
|
|
30693
|
-
error.runBrowserCode = runBrowserConstants.actionFailedErrorCode;
|
|
30694
|
-
error.isRetryable = false;
|
|
30695
|
-
error.suggestedNextSteps = [
|
|
30696
|
-
'Verify selectors and action values.',
|
|
30697
|
-
'Reduce the action sequence to isolate the failing step.',
|
|
30698
|
-
];
|
|
30699
|
-
error.debug = options.debug;
|
|
30700
|
-
error.cause = options.cause;
|
|
30701
|
-
return error;
|
|
30702
|
-
},
|
|
30703
|
-
/**
|
|
30704
|
-
* Creates one tagged KnowledgeScrapeError used for cancellation.
|
|
30705
|
-
*/
|
|
30706
|
-
createRunBrowserCancelledError(options) {
|
|
30707
|
-
const error = new KnowledgeScrapeError(options.message);
|
|
30708
|
-
error.name = 'RunBrowserCancelledError';
|
|
30709
|
-
error.runBrowserCode = runBrowserConstants.cancelledErrorCode;
|
|
30710
|
-
error.isRetryable = true;
|
|
30711
|
-
error.suggestedNextSteps = [
|
|
30712
|
-
'Retry while request context is still active.',
|
|
30713
|
-
'Increase timeout if operation is expected to run longer.',
|
|
30714
|
-
];
|
|
30715
|
-
error.debug = options.debug;
|
|
30716
|
-
error.cause = options.cause;
|
|
30717
|
-
return error;
|
|
30718
|
-
},
|
|
30719
|
-
/**
|
|
30720
|
-
* Checks whether an unknown error carries run_browser classification tags.
|
|
30721
|
-
*/
|
|
30722
|
-
isTaggedRunBrowserError(error) {
|
|
30723
|
-
if (!error || typeof error !== 'object') {
|
|
30724
|
-
return false;
|
|
30725
|
-
}
|
|
30726
|
-
const candidate = error;
|
|
30727
|
-
return (typeof candidate.runBrowserCode === 'string' &&
|
|
30728
|
-
typeof candidate.isRetryable === 'boolean' &&
|
|
30729
|
-
Array.isArray(candidate.suggestedNextSteps) &&
|
|
30730
|
-
typeof candidate.debug === 'object' &&
|
|
30731
|
-
candidate.debug !== null);
|
|
30732
|
-
},
|
|
30733
|
-
/**
|
|
30734
|
-
* Converts unknown errors into structured tool error payloads.
|
|
30735
|
-
*/
|
|
30736
|
-
classifyRunBrowserToolError(options) {
|
|
30737
|
-
if (isRemoteBrowserUnavailableError(options.error)) {
|
|
30738
|
-
return {
|
|
30739
|
-
code: options.error.code,
|
|
30740
|
-
message: options.error.message,
|
|
30741
|
-
isRetryable: options.error.isRetryable,
|
|
30742
|
-
suggestedNextSteps: options.error.suggestedNextSteps,
|
|
30743
|
-
debug: {
|
|
30744
|
-
...options.error.debug,
|
|
30745
|
-
sessionId: options.sessionId,
|
|
30746
|
-
mode: runBrowserRuntime.formatExecutionMode(options.mode),
|
|
30747
|
-
},
|
|
30748
|
-
};
|
|
30749
|
-
}
|
|
30750
|
-
if (this.isTaggedRunBrowserError(options.error)) {
|
|
30751
|
-
return {
|
|
30752
|
-
code: options.error.runBrowserCode,
|
|
30753
|
-
message: options.error.message,
|
|
30754
|
-
isRetryable: options.error.isRetryable,
|
|
30755
|
-
suggestedNextSteps: options.error.suggestedNextSteps,
|
|
30756
|
-
debug: {
|
|
30757
|
-
...options.error.debug,
|
|
30758
|
-
sessionId: options.sessionId,
|
|
30759
|
-
mode: runBrowserRuntime.formatExecutionMode(options.mode),
|
|
30760
|
-
},
|
|
30761
|
-
};
|
|
30762
|
-
}
|
|
30763
|
-
const remoteBrowserEndpoint = REMOTE_BROWSER_URL && REMOTE_BROWSER_URL.trim().length > 0
|
|
30764
|
-
? sanitizeRemoteBrowserEndpoint(REMOTE_BROWSER_URL.trim())
|
|
30765
|
-
: null;
|
|
30766
|
-
const message = getErrorMessage(options.error);
|
|
30767
|
-
return {
|
|
30768
|
-
code: runBrowserConstants.unknownErrorCode,
|
|
30769
|
-
message,
|
|
30770
|
-
isRetryable: false,
|
|
30771
|
-
suggestedNextSteps: ['Inspect debug details to identify the failing phase.', 'Retry with fewer actions.'],
|
|
30772
|
-
debug: {
|
|
30773
|
-
sessionId: options.sessionId,
|
|
30774
|
-
mode: runBrowserRuntime.formatExecutionMode(options.mode),
|
|
30775
|
-
remoteBrowserEndpoint,
|
|
30776
|
-
message,
|
|
30777
|
-
stack: getErrorStack(options.error),
|
|
30778
|
-
},
|
|
30779
|
-
};
|
|
30780
|
-
},
|
|
30781
|
-
/**
|
|
30782
|
-
* Asserts that the run was not aborted.
|
|
30783
|
-
*/
|
|
30784
|
-
assertNotAborted(signal, sessionId) {
|
|
30785
|
-
if (!(signal === null || signal === void 0 ? void 0 : signal.aborted)) {
|
|
30786
|
-
return;
|
|
30787
|
-
}
|
|
30788
|
-
throw this.createRunBrowserCancelledError({
|
|
30789
|
-
message: 'run_browser execution was cancelled.',
|
|
30790
|
-
debug: { sessionId },
|
|
30791
|
-
});
|
|
30792
|
-
},
|
|
30793
|
-
/**
|
|
30794
|
-
* Returns true when the tool error represents remote browser unavailability.
|
|
30795
|
-
*/
|
|
30796
|
-
isRemoteBrowserUnavailableCode(code) {
|
|
30797
|
-
return code === REMOTE_BROWSER_UNAVAILABLE_ERROR_CODE;
|
|
30798
|
-
},
|
|
30799
|
-
};
|
|
30800
|
-
|
|
30801
|
-
/**
|
|
30802
|
-
* In-memory observability counters for browser tool execution.
|
|
30803
|
-
*/
|
|
30804
|
-
const RUN_BROWSER_OBSERVABILITY = {
|
|
30805
|
-
totalRuns: 0,
|
|
30806
|
-
fallbackRuns: 0,
|
|
30807
|
-
errorCodeCounts: {},
|
|
30808
|
-
};
|
|
30809
|
-
/**
|
|
30810
|
-
* Observability counters and metric logging for `run_browser`.
|
|
30811
|
-
*
|
|
30812
|
-
* @private function of `run_browser`
|
|
30813
|
-
*/
|
|
30814
|
-
const runBrowserObservability = {
|
|
30815
|
-
/**
|
|
30816
|
-
* Increments total-run counter and returns the updated value.
|
|
30817
|
-
*/
|
|
30818
|
-
incrementTotalRuns() {
|
|
30819
|
-
RUN_BROWSER_OBSERVABILITY.totalRuns++;
|
|
30820
|
-
return RUN_BROWSER_OBSERVABILITY.totalRuns;
|
|
30821
|
-
},
|
|
30822
|
-
/**
|
|
30823
|
-
* Returns current total run count.
|
|
30824
|
-
*/
|
|
30825
|
-
getTotalRuns() {
|
|
30826
|
-
return RUN_BROWSER_OBSERVABILITY.totalRuns;
|
|
30827
|
-
},
|
|
30828
|
-
/**
|
|
30829
|
-
* Increments fallback counter and returns updated metrics.
|
|
30830
|
-
*/
|
|
30831
|
-
incrementFallbackRunsAndGetMetrics() {
|
|
30832
|
-
RUN_BROWSER_OBSERVABILITY.fallbackRuns++;
|
|
30833
|
-
return {
|
|
30834
|
-
fallbackRuns: RUN_BROWSER_OBSERVABILITY.fallbackRuns,
|
|
30835
|
-
fallbackRate: RUN_BROWSER_OBSERVABILITY.totalRuns === 0
|
|
30836
|
-
? 0
|
|
30837
|
-
: RUN_BROWSER_OBSERVABILITY.fallbackRuns / RUN_BROWSER_OBSERVABILITY.totalRuns,
|
|
30838
|
-
};
|
|
30839
|
-
},
|
|
30840
|
-
/**
|
|
30841
|
-
* Increments one error-code counter and returns the updated value.
|
|
30842
|
-
*/
|
|
30843
|
-
incrementRunBrowserErrorCodeCounter(code) {
|
|
30844
|
-
const currentValue = RUN_BROWSER_OBSERVABILITY.errorCodeCounts[code] || 0;
|
|
30845
|
-
const nextValue = currentValue + 1;
|
|
30846
|
-
RUN_BROWSER_OBSERVABILITY.errorCodeCounts[code] = nextValue;
|
|
30847
|
-
return nextValue;
|
|
30848
|
-
},
|
|
30849
|
-
/**
|
|
30850
|
-
* Writes one structured metric line for browser-tool observability.
|
|
30851
|
-
*/
|
|
30852
|
-
logRunBrowserMetric(options) {
|
|
30853
|
-
console.info('[run_browser][metric]', {
|
|
30854
|
-
tool: 'run_browser',
|
|
30855
|
-
mode: options.mode,
|
|
30856
|
-
sessionId: options.sessionId,
|
|
30857
|
-
event: options.event,
|
|
30858
|
-
...(options.payload || {}),
|
|
30859
|
-
});
|
|
30860
|
-
},
|
|
30861
|
-
};
|
|
30862
|
-
|
|
30863
|
-
/**
|
|
30864
|
-
* Computes one compact preview of a fallback scrape payload.
|
|
30865
|
-
*/
|
|
30866
|
-
function createContentPreview(content) {
|
|
30867
|
-
const normalized = content.replace(/\s+/g, ' ').trim();
|
|
30868
|
-
if (normalized.length <= 280) {
|
|
30869
|
-
return normalized;
|
|
30870
|
-
}
|
|
30871
|
-
return `${normalized.slice(0, 277)}...`;
|
|
30872
|
-
}
|
|
30873
|
-
/**
|
|
30874
|
-
* Payload and markdown formatters for `run_browser` outcomes.
|
|
30875
|
-
*
|
|
30876
|
-
* @private function of `run_browser`
|
|
30877
|
-
*/
|
|
30878
|
-
const runBrowserResultFormatting = {
|
|
30879
|
-
/**
|
|
30880
|
-
* Produces one structured payload consumed by chat UI browser replay renderers.
|
|
30881
|
-
*/
|
|
30882
|
-
createResultPayload(options) {
|
|
30883
|
-
return {
|
|
30884
|
-
schema: runBrowserConstants.resultSchema,
|
|
30885
|
-
sessionId: options.sessionId,
|
|
30886
|
-
mode: options.mode,
|
|
30887
|
-
modeUsed: options.modeUsed,
|
|
30888
|
-
initialUrl: options.initialUrl,
|
|
30889
|
-
finalUrl: options.finalUrl,
|
|
30890
|
-
finalTitle: options.finalTitle,
|
|
30891
|
-
executedActions: options.executedActions,
|
|
30892
|
-
artifacts: options.artifacts,
|
|
30893
|
-
warning: options.warning,
|
|
30894
|
-
error: options.error,
|
|
30895
|
-
fallback: options.modeUsed === 'fallback' && options.fallbackContent !== null
|
|
30896
|
-
? {
|
|
30897
|
-
scraper: 'fetch_url_content',
|
|
30898
|
-
contentPreview: createContentPreview(options.fallbackContent),
|
|
30899
|
-
}
|
|
30900
|
-
: null,
|
|
30901
|
-
timing: options.timing,
|
|
30902
|
-
};
|
|
30903
|
-
},
|
|
30904
|
-
/**
|
|
30905
|
-
* Produces a model-friendly markdown summary from browser execution artifacts.
|
|
30906
|
-
*/
|
|
30907
|
-
formatSuccessResult(options) {
|
|
30908
|
-
const { payload, snapshotPath } = options;
|
|
30909
|
-
return spaceTrim$1((block) => {
|
|
30910
|
-
var _a, _b, _c;
|
|
30911
|
-
return `
|
|
30912
|
-
# Browser run completed
|
|
30913
|
-
|
|
30914
|
-
**Session:** ${payload.sessionId}
|
|
30915
|
-
**Mode requested:** ${runBrowserRuntime.formatExecutionMode(payload.mode)}
|
|
30916
|
-
**Mode used:** ${payload.modeUsed}
|
|
30917
|
-
**Initial URL:** ${payload.initialUrl}
|
|
30918
|
-
**Executed actions:** ${payload.executedActions.length}
|
|
30919
|
-
|
|
30920
|
-
## Final page
|
|
30921
|
-
|
|
30922
|
-
- URL: ${payload.finalUrl || 'Unknown'}
|
|
30923
|
-
- Title: ${payload.finalTitle || 'Unknown'}
|
|
30924
|
-
|
|
30925
|
-
## Timings
|
|
30926
|
-
|
|
30927
|
-
- Connect: ${(_a = payload.timing.connectDurationMs) !== null && _a !== void 0 ? _a : 'Unknown'} ms
|
|
30928
|
-
- Initial navigation: ${(_b = payload.timing.initialNavigationDurationMs) !== null && _b !== void 0 ? _b : 'Unknown'} ms
|
|
30929
|
-
- Time to first byte: ${(_c = payload.timing.timeToFirstByteMs) !== null && _c !== void 0 ? _c : 'Unknown'} ms
|
|
30930
|
-
- Total: ${payload.timing.totalDurationMs} ms
|
|
30931
|
-
|
|
30932
|
-
${payload.artifacts.length === 0
|
|
30933
|
-
? ''
|
|
30934
|
-
: `
|
|
30935
|
-
## Visual replay
|
|
30936
|
-
|
|
30937
|
-
${payload.artifacts
|
|
30938
|
-
.map((artifact, index) => {
|
|
30939
|
-
const actionPart = artifact.actionSummary ? ` (${artifact.actionSummary})` : '';
|
|
30940
|
-
return `- ${index + 1}. ${artifact.label}${actionPart}: ${artifact.path}`;
|
|
30941
|
-
})
|
|
30942
|
-
.join('\n')}
|
|
30943
|
-
`}
|
|
30944
|
-
|
|
30945
|
-
${!snapshotPath
|
|
30946
|
-
? ''
|
|
30947
|
-
: `
|
|
30948
|
-
## Final snapshot
|
|
30949
|
-
|
|
30950
|
-
${snapshotPath}
|
|
30951
|
-
`}
|
|
30952
|
-
|
|
30953
|
-
## Playback payload
|
|
30954
|
-
|
|
30955
|
-
\`\`\`json
|
|
30956
|
-
${JSON.stringify(payload, null, 2)}
|
|
30957
|
-
\`\`\`
|
|
30958
|
-
|
|
30959
|
-
${block(payload.executedActions.length === 0
|
|
30960
|
-
? ''
|
|
30961
|
-
: `
|
|
30962
|
-
## Action log
|
|
30963
|
-
|
|
30964
|
-
${payload.executedActions
|
|
30965
|
-
.map((action, index) => `- ${index + 1}. ${JSON.stringify(action)}`)
|
|
30966
|
-
.join('\n')}
|
|
30967
|
-
`)}
|
|
30968
|
-
|
|
30969
|
-
Note: Browser page has been automatically closed to free up resources.
|
|
30970
|
-
`;
|
|
30971
|
-
});
|
|
30972
|
-
},
|
|
30973
|
-
/**
|
|
30974
|
-
* Produces a model-friendly markdown payload when fallback scraping is used.
|
|
30975
|
-
*/
|
|
30976
|
-
formatFallbackResult(options) {
|
|
30977
|
-
const { payload, fallbackContent, requestedActions } = options;
|
|
30978
|
-
return spaceTrim$1(`
|
|
30979
|
-
# Browser run completed with fallback
|
|
30980
|
-
|
|
30981
|
-
**Session:** ${payload.sessionId}
|
|
30982
|
-
**Mode requested:** ${runBrowserRuntime.formatExecutionMode(payload.mode)}
|
|
30983
|
-
**Mode used:** ${payload.modeUsed}
|
|
30984
|
-
**Initial URL:** ${payload.initialUrl}
|
|
30985
|
-
**Requested actions:** ${requestedActions}
|
|
30986
|
-
**Executed actions:** ${payload.executedActions.length}
|
|
30987
|
-
**Warning:** ${payload.warning || runBrowserConstants.fallbackDynamicContentWarning}
|
|
30988
|
-
|
|
30989
|
-
## Extracted content
|
|
30990
|
-
|
|
30991
|
-
${fallbackContent}
|
|
30992
|
-
|
|
30993
|
-
## Playback payload
|
|
30994
|
-
|
|
30995
|
-
\`\`\`json
|
|
30996
|
-
${JSON.stringify(payload, null, 2)}
|
|
30997
|
-
\`\`\`
|
|
30998
|
-
`);
|
|
30999
|
-
},
|
|
31000
|
-
/**
|
|
31001
|
-
* Produces a model-friendly markdown error payload from browser execution failures.
|
|
31002
|
-
*/
|
|
31003
|
-
formatErrorResult(options) {
|
|
31004
|
-
const { payload } = options;
|
|
31005
|
-
const toolError = payload.error;
|
|
31006
|
-
const suggestedNextSteps = (toolError === null || toolError === void 0 ? void 0 : toolError.suggestedNextSteps) || [];
|
|
31007
|
-
return spaceTrim$1(`
|
|
31008
|
-
# Browser run failed
|
|
31009
|
-
|
|
31010
|
-
**Session:** ${payload.sessionId}
|
|
31011
|
-
**Mode requested:** ${runBrowserRuntime.formatExecutionMode(payload.mode)}
|
|
31012
|
-
**Mode used:** ${payload.modeUsed}
|
|
31013
|
-
**Initial URL:** ${payload.initialUrl}
|
|
31014
|
-
**Error code:** ${(toolError === null || toolError === void 0 ? void 0 : toolError.code) || runBrowserConstants.unknownErrorCode}
|
|
31015
|
-
**Error:** ${(toolError === null || toolError === void 0 ? void 0 : toolError.message) || 'Unknown browser tool error'}
|
|
31016
|
-
|
|
31017
|
-
${suggestedNextSteps.length === 0
|
|
31018
|
-
? ''
|
|
31019
|
-
: `
|
|
31020
|
-
## Suggested next steps
|
|
31021
|
-
|
|
31022
|
-
${suggestedNextSteps.map((step) => `- ${step}`).join('\n')}
|
|
31023
|
-
`}
|
|
31024
|
-
|
|
31025
|
-
## Playback payload
|
|
31026
|
-
|
|
31027
|
-
\`\`\`json
|
|
31028
|
-
${JSON.stringify(payload, null, 2)}
|
|
31029
|
-
\`\`\`
|
|
31030
|
-
|
|
31031
|
-
The browser tool could not complete the requested actions.
|
|
31032
|
-
`);
|
|
31033
|
-
},
|
|
31034
|
-
};
|
|
31035
|
-
|
|
31036
|
-
/**
|
|
31037
|
-
* Attempts to locate the specified application on a Linux system using the 'which' command.
|
|
31038
|
-
* Returns the path to the executable if found, or null otherwise.
|
|
31039
|
-
*
|
|
31040
|
-
* @private within the repository
|
|
31041
|
-
*/
|
|
31042
|
-
async function locateAppOnLinux({ linuxWhich, }) {
|
|
31043
|
-
try {
|
|
31044
|
-
const result = await $execCommand({ crashOnError: true, command: `which ${linuxWhich}` });
|
|
31045
|
-
return result.trim();
|
|
31046
|
-
}
|
|
31047
|
-
catch (error) {
|
|
31048
|
-
assertsError(error);
|
|
31049
|
-
return null;
|
|
31050
|
-
}
|
|
31051
|
-
}
|
|
31052
|
-
/**
|
|
31053
|
-
* TODO: [🧠][♿] Maybe export through `@promptbook/node`
|
|
31054
|
-
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
31055
|
-
*/
|
|
31056
|
-
|
|
31057
|
-
/**
|
|
31058
|
-
* Checks if the file is executable
|
|
31059
|
-
*
|
|
31060
|
-
* @private within the repository
|
|
31061
|
-
*/
|
|
31062
|
-
async function isExecutable(path, fs) {
|
|
31063
|
-
try {
|
|
31064
|
-
await fs.access(path, fs.constants.X_OK);
|
|
31065
|
-
return true;
|
|
31066
|
-
}
|
|
31067
|
-
catch (error) {
|
|
31068
|
-
return false;
|
|
31069
|
-
}
|
|
31070
|
-
}
|
|
31071
|
-
/**
|
|
31072
|
-
* Note: Not [~🟢~] because it is not directly dependent on `fs
|
|
31073
|
-
* TODO: [🖇] What about symlinks?
|
|
30541
|
+
* Note: Not [~🟢~] because it is not directly dependent on `fs
|
|
30542
|
+
* TODO: [🖇] What about symlinks?
|
|
31074
30543
|
*/
|
|
31075
30544
|
|
|
31076
30545
|
// Note: Module `userhome` has no types available, so it is imported using `require`
|
|
@@ -31182,1283 +30651,6 @@ function locateApp(options) {
|
|
|
31182
30651
|
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
31183
30652
|
*/
|
|
31184
30653
|
|
|
31185
|
-
/**
|
|
31186
|
-
* @@@
|
|
31187
|
-
*
|
|
31188
|
-
* @private within the repository
|
|
31189
|
-
*/
|
|
31190
|
-
function locateChrome() {
|
|
31191
|
-
return locateApp({
|
|
31192
|
-
appName: 'Chrome',
|
|
31193
|
-
linuxWhich: 'google-chrome',
|
|
31194
|
-
windowsSuffix: '\\Google\\Chrome\\Application\\chrome.exe',
|
|
31195
|
-
macOsName: 'Google Chrome',
|
|
31196
|
-
});
|
|
31197
|
-
}
|
|
31198
|
-
|
|
31199
|
-
/**
|
|
31200
|
-
* Creates one standard abort error for cancelled retry loops.
|
|
31201
|
-
*
|
|
31202
|
-
* @private utility for Agents Server runtime retries
|
|
31203
|
-
*/
|
|
31204
|
-
function createAbortError$1() {
|
|
31205
|
-
const error = new Error('Operation was aborted.');
|
|
31206
|
-
error.name = 'AbortError';
|
|
31207
|
-
return error;
|
|
31208
|
-
}
|
|
31209
|
-
/**
|
|
31210
|
-
* Throws when the supplied signal is already aborted.
|
|
31211
|
-
*
|
|
31212
|
-
* @private utility for Agents Server runtime retries
|
|
31213
|
-
*/
|
|
31214
|
-
function assertNotAborted(signal) {
|
|
31215
|
-
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
31216
|
-
throw createAbortError$1();
|
|
31217
|
-
}
|
|
31218
|
-
}
|
|
31219
|
-
/**
|
|
31220
|
-
* Waits for a duration while respecting cancellation.
|
|
31221
|
-
*
|
|
31222
|
-
* @private utility for Agents Server runtime retries
|
|
31223
|
-
*/
|
|
31224
|
-
async function sleepWithAbort(delayMs, signal) {
|
|
31225
|
-
if (delayMs <= 0) {
|
|
31226
|
-
assertNotAborted(signal);
|
|
31227
|
-
return;
|
|
31228
|
-
}
|
|
31229
|
-
await new Promise((resolve, reject) => {
|
|
31230
|
-
const timeout = setTimeout(() => {
|
|
31231
|
-
signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);
|
|
31232
|
-
resolve();
|
|
31233
|
-
}, delayMs);
|
|
31234
|
-
const onAbort = () => {
|
|
31235
|
-
clearTimeout(timeout);
|
|
31236
|
-
signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);
|
|
31237
|
-
reject(createAbortError$1());
|
|
31238
|
-
};
|
|
31239
|
-
signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', onAbort, { once: true });
|
|
31240
|
-
});
|
|
31241
|
-
}
|
|
31242
|
-
/**
|
|
31243
|
-
* Resolves the retry wait duration for one failed attempt.
|
|
31244
|
-
*
|
|
31245
|
-
* @private utility for Agents Server runtime retries
|
|
31246
|
-
*/
|
|
31247
|
-
function resolveBackoffDelayMs(options) {
|
|
31248
|
-
const exponentialDelay = options.initialDelayMs * Math.pow(options.backoffFactor, Math.max(0, options.attempt - 1));
|
|
31249
|
-
const boundedDelay = Math.min(exponentialDelay, options.maxDelayMs);
|
|
31250
|
-
const jitterDelay = boundedDelay * options.jitterRatio * Math.max(0, options.random());
|
|
31251
|
-
return Math.max(0, Math.round(boundedDelay + jitterDelay));
|
|
31252
|
-
}
|
|
31253
|
-
/**
|
|
31254
|
-
* Retries one async operation with exponential backoff and jitter.
|
|
31255
|
-
*
|
|
31256
|
-
* @private utility for Agents Server runtime retries
|
|
31257
|
-
*/
|
|
31258
|
-
async function retryWithBackoff(operation, options) {
|
|
31259
|
-
var _a, _b, _c;
|
|
31260
|
-
const startedAt = Date.now();
|
|
31261
|
-
const totalAttempts = Math.max(1, options.retries + 1);
|
|
31262
|
-
const random = (_a = options.random) !== null && _a !== void 0 ? _a : Math.random;
|
|
31263
|
-
const sleep = (_b = options.sleep) !== null && _b !== void 0 ? _b : sleepWithAbort;
|
|
31264
|
-
for (let attempt = 1; attempt <= totalAttempts; attempt++) {
|
|
31265
|
-
assertNotAborted(options.signal);
|
|
31266
|
-
try {
|
|
31267
|
-
const value = await operation(attempt);
|
|
31268
|
-
return {
|
|
31269
|
-
value,
|
|
31270
|
-
attempts: attempt,
|
|
31271
|
-
durationMs: Date.now() - startedAt,
|
|
31272
|
-
};
|
|
31273
|
-
}
|
|
31274
|
-
catch (error) {
|
|
31275
|
-
const isLastAttempt = attempt >= totalAttempts;
|
|
31276
|
-
const isRetryable = options.shouldRetry ? options.shouldRetry(error, attempt) : true;
|
|
31277
|
-
if (isLastAttempt || !isRetryable) {
|
|
31278
|
-
throw error;
|
|
31279
|
-
}
|
|
31280
|
-
const delayMs = resolveBackoffDelayMs({
|
|
31281
|
-
attempt,
|
|
31282
|
-
initialDelayMs: options.initialDelayMs,
|
|
31283
|
-
maxDelayMs: options.maxDelayMs,
|
|
31284
|
-
backoffFactor: options.backoffFactor,
|
|
31285
|
-
jitterRatio: options.jitterRatio,
|
|
31286
|
-
random,
|
|
31287
|
-
});
|
|
31288
|
-
(_c = options.onRetry) === null || _c === void 0 ? void 0 : _c.call(options, {
|
|
31289
|
-
attempt,
|
|
31290
|
-
retries: options.retries,
|
|
31291
|
-
delayMs,
|
|
31292
|
-
error,
|
|
31293
|
-
});
|
|
31294
|
-
await sleep(delayMs, options.signal);
|
|
31295
|
-
}
|
|
31296
|
-
}
|
|
31297
|
-
throw new Error('Retry loop exited unexpectedly.');
|
|
31298
|
-
}
|
|
31299
|
-
|
|
31300
|
-
const DEFAULT_BROWSER_USER_DATA_DIR = join(tmpdir(), 'promptbook', 'browser', 'user-data');
|
|
31301
|
-
/**
|
|
31302
|
-
* Default remote browser connect timeout in milliseconds.
|
|
31303
|
-
*/
|
|
31304
|
-
const DEFAULT_REMOTE_CONNECT_TIMEOUT_MS = 10000;
|
|
31305
|
-
/**
|
|
31306
|
-
* Default retry count for remote browser connection establishment.
|
|
31307
|
-
*/
|
|
31308
|
-
const DEFAULT_REMOTE_CONNECT_RETRIES = 2;
|
|
31309
|
-
/**
|
|
31310
|
-
* Default initial retry delay for remote browser connection.
|
|
31311
|
-
*/
|
|
31312
|
-
const DEFAULT_REMOTE_CONNECT_BACKOFF_INITIAL_MS = 250;
|
|
31313
|
-
/**
|
|
31314
|
-
* Default maximum retry delay for remote browser connection.
|
|
31315
|
-
*/
|
|
31316
|
-
const DEFAULT_REMOTE_CONNECT_BACKOFF_MAX_MS = 1000;
|
|
31317
|
-
/**
|
|
31318
|
-
* Default exponential multiplier for remote browser retry delay.
|
|
31319
|
-
*/
|
|
31320
|
-
const DEFAULT_REMOTE_CONNECT_BACKOFF_FACTOR = 4;
|
|
31321
|
-
/**
|
|
31322
|
-
* Default retry jitter ratio for remote browser connection.
|
|
31323
|
-
*/
|
|
31324
|
-
const DEFAULT_REMOTE_CONNECT_JITTER_RATIO = 0.2;
|
|
31325
|
-
/**
|
|
31326
|
-
* In-memory metrics counters for remote browser connect attempts.
|
|
31327
|
-
*/
|
|
31328
|
-
const REMOTE_BROWSER_CONNECT_METRICS = {
|
|
31329
|
-
success: 0,
|
|
31330
|
-
failure: 0,
|
|
31331
|
-
};
|
|
31332
|
-
/**
|
|
31333
|
-
* Reads a positive integer from environment variables with a fallback default.
|
|
31334
|
-
*/
|
|
31335
|
-
function resolvePositiveIntFromEnv(variableName, defaultValue) {
|
|
31336
|
-
const rawValue = process.env[variableName];
|
|
31337
|
-
if (!rawValue || !rawValue.trim()) {
|
|
31338
|
-
return defaultValue;
|
|
31339
|
-
}
|
|
31340
|
-
const parsed = Number.parseInt(rawValue.trim(), 10);
|
|
31341
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
31342
|
-
return defaultValue;
|
|
31343
|
-
}
|
|
31344
|
-
return parsed;
|
|
31345
|
-
}
|
|
31346
|
-
/**
|
|
31347
|
-
* Reads a positive number from environment variables with a fallback default.
|
|
31348
|
-
*/
|
|
31349
|
-
function resolvePositiveNumberFromEnv(variableName, defaultValue) {
|
|
31350
|
-
const rawValue = process.env[variableName];
|
|
31351
|
-
if (!rawValue || !rawValue.trim()) {
|
|
31352
|
-
return defaultValue;
|
|
31353
|
-
}
|
|
31354
|
-
const parsed = Number.parseFloat(rawValue.trim());
|
|
31355
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
31356
|
-
return defaultValue;
|
|
31357
|
-
}
|
|
31358
|
-
return parsed;
|
|
31359
|
-
}
|
|
31360
|
-
/**
|
|
31361
|
-
* Reads a non-negative integer from environment variables with a fallback default.
|
|
31362
|
-
*/
|
|
31363
|
-
function resolveNonNegativeIntFromEnv(variableName, defaultValue) {
|
|
31364
|
-
const rawValue = process.env[variableName];
|
|
31365
|
-
if (!rawValue || !rawValue.trim()) {
|
|
31366
|
-
return defaultValue;
|
|
31367
|
-
}
|
|
31368
|
-
const parsed = Number.parseInt(rawValue.trim(), 10);
|
|
31369
|
-
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
31370
|
-
return defaultValue;
|
|
31371
|
-
}
|
|
31372
|
-
return parsed;
|
|
31373
|
-
}
|
|
31374
|
-
/**
|
|
31375
|
-
* Reads a non-negative number from environment variables with a fallback default.
|
|
31376
|
-
*/
|
|
31377
|
-
function resolveNonNegativeNumberFromEnv(variableName, defaultValue) {
|
|
31378
|
-
const rawValue = process.env[variableName];
|
|
31379
|
-
if (!rawValue || !rawValue.trim()) {
|
|
31380
|
-
return defaultValue;
|
|
31381
|
-
}
|
|
31382
|
-
const parsed = Number.parseFloat(rawValue.trim());
|
|
31383
|
-
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
31384
|
-
return defaultValue;
|
|
31385
|
-
}
|
|
31386
|
-
return parsed;
|
|
31387
|
-
}
|
|
31388
|
-
/**
|
|
31389
|
-
* Creates one standard abort error.
|
|
31390
|
-
*/
|
|
31391
|
-
function createAbortError() {
|
|
31392
|
-
const error = new Error('Browser connection request was aborted.');
|
|
31393
|
-
error.name = 'AbortError';
|
|
31394
|
-
return error;
|
|
31395
|
-
}
|
|
31396
|
-
/**
|
|
31397
|
-
* Provides browser context instances with support for both local and remote browser connections.
|
|
31398
|
-
*
|
|
31399
|
-
* This provider manages browser lifecycle and supports:
|
|
31400
|
-
* - Local mode: Launches a persistent Chromium context on the same machine
|
|
31401
|
-
* - Remote mode: Connects to a remote Playwright browser via WebSocket
|
|
31402
|
-
*
|
|
31403
|
-
* The remote mode is useful for environments like Vercel where running a full browser
|
|
31404
|
-
* is not possible due to resource constraints.
|
|
31405
|
-
*
|
|
31406
|
-
* @private internal utility for Agents Server browser tools
|
|
31407
|
-
*/
|
|
31408
|
-
class BrowserConnectionProvider {
|
|
31409
|
-
/**
|
|
31410
|
-
* Creates a new BrowserConnectionProvider.
|
|
31411
|
-
*
|
|
31412
|
-
* @param options - Provider options
|
|
31413
|
-
* @param options.isVerbose - Enable verbose logging
|
|
31414
|
-
*/
|
|
31415
|
-
constructor(options = {}) {
|
|
31416
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
31417
|
-
this.browserContext = null;
|
|
31418
|
-
this.connectionMode = null;
|
|
31419
|
-
this.isVerbose = (_a = options.isVerbose) !== null && _a !== void 0 ? _a : false;
|
|
31420
|
-
this.remoteConnectTimeoutMs =
|
|
31421
|
-
(_b = options.remoteConnectTimeoutMs) !== null && _b !== void 0 ? _b : resolvePositiveIntFromEnv('RUN_BROWSER_CONNECT_TIMEOUT_MS', DEFAULT_REMOTE_CONNECT_TIMEOUT_MS);
|
|
31422
|
-
this.remoteConnectRetries =
|
|
31423
|
-
(_c = options.remoteConnectRetries) !== null && _c !== void 0 ? _c : resolveNonNegativeIntFromEnv('RUN_BROWSER_CONNECT_RETRIES', DEFAULT_REMOTE_CONNECT_RETRIES);
|
|
31424
|
-
this.remoteConnectBackoffInitialMs =
|
|
31425
|
-
(_d = options.remoteConnectBackoffInitialMs) !== null && _d !== void 0 ? _d : resolvePositiveIntFromEnv('RUN_BROWSER_CONNECT_BACKOFF_INITIAL_MS', DEFAULT_REMOTE_CONNECT_BACKOFF_INITIAL_MS);
|
|
31426
|
-
this.remoteConnectBackoffMaxMs =
|
|
31427
|
-
(_e = options.remoteConnectBackoffMaxMs) !== null && _e !== void 0 ? _e : resolvePositiveIntFromEnv('RUN_BROWSER_CONNECT_BACKOFF_MAX_MS', DEFAULT_REMOTE_CONNECT_BACKOFF_MAX_MS);
|
|
31428
|
-
this.remoteConnectBackoffFactor =
|
|
31429
|
-
(_f = options.remoteConnectBackoffFactor) !== null && _f !== void 0 ? _f : resolvePositiveNumberFromEnv('RUN_BROWSER_CONNECT_BACKOFF_FACTOR', DEFAULT_REMOTE_CONNECT_BACKOFF_FACTOR);
|
|
31430
|
-
this.remoteConnectJitterRatio =
|
|
31431
|
-
(_g = options.remoteConnectJitterRatio) !== null && _g !== void 0 ? _g : resolveNonNegativeNumberFromEnv('RUN_BROWSER_CONNECT_JITTER_RATIO', DEFAULT_REMOTE_CONNECT_JITTER_RATIO);
|
|
31432
|
-
this.random = (_h = options.random) !== null && _h !== void 0 ? _h : Math.random;
|
|
31433
|
-
this.sleep = options.sleep;
|
|
31434
|
-
}
|
|
31435
|
-
/**
|
|
31436
|
-
* Gets a browser context, creating a new one if needed.
|
|
31437
|
-
*
|
|
31438
|
-
* This method automatically determines whether to use local or remote browser
|
|
31439
|
-
* based on the REMOTE_BROWSER_URL environment variable.
|
|
31440
|
-
*
|
|
31441
|
-
* @returns Browser context instance
|
|
31442
|
-
*/
|
|
31443
|
-
async getBrowserContext(options = {}) {
|
|
31444
|
-
var _a;
|
|
31445
|
-
if ((_a = options.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
|
|
31446
|
-
throw createAbortError();
|
|
31447
|
-
}
|
|
31448
|
-
// Check if we have a cached connection that's still valid
|
|
31449
|
-
if (this.browserContext !== null && this.isBrowserContextAlive(this.browserContext)) {
|
|
31450
|
-
return this.browserContext;
|
|
31451
|
-
}
|
|
31452
|
-
// Determine connection mode from configuration
|
|
31453
|
-
const mode = this.resolveConnectionMode();
|
|
31454
|
-
this.connectionMode = mode;
|
|
31455
|
-
if (this.isVerbose) {
|
|
31456
|
-
console.info('[BrowserConnectionProvider] Creating new browser context', {
|
|
31457
|
-
mode: mode.type,
|
|
31458
|
-
wsEndpoint: mode.type === 'remote' ? mode.wsEndpoint : undefined,
|
|
31459
|
-
});
|
|
31460
|
-
}
|
|
31461
|
-
// Create new browser context based on mode
|
|
31462
|
-
if (mode.type === 'local') {
|
|
31463
|
-
this.browserContext = await this.createLocalBrowserContext();
|
|
31464
|
-
}
|
|
31465
|
-
else {
|
|
31466
|
-
this.browserContext = await this.createRemoteBrowserContext(mode.wsEndpoint, options);
|
|
31467
|
-
}
|
|
31468
|
-
return this.browserContext;
|
|
31469
|
-
}
|
|
31470
|
-
/**
|
|
31471
|
-
* Closes all pages in the current browser context.
|
|
31472
|
-
*
|
|
31473
|
-
* This method is useful for cleanup between agent tasks without closing
|
|
31474
|
-
* the entire browser instance.
|
|
31475
|
-
*/
|
|
31476
|
-
async closeAllPages() {
|
|
31477
|
-
if (!this.browserContext) {
|
|
31478
|
-
return;
|
|
31479
|
-
}
|
|
31480
|
-
try {
|
|
31481
|
-
const pages = this.browserContext.pages();
|
|
31482
|
-
if (this.isVerbose) {
|
|
31483
|
-
console.info('[BrowserConnectionProvider] Closing all pages', {
|
|
31484
|
-
pageCount: pages.length,
|
|
31485
|
-
});
|
|
31486
|
-
}
|
|
31487
|
-
await Promise.all(pages.map((page) => page.close().catch((error) => {
|
|
31488
|
-
console.error('[BrowserConnectionProvider] Failed to close page', { error });
|
|
31489
|
-
})));
|
|
31490
|
-
}
|
|
31491
|
-
catch (error) {
|
|
31492
|
-
console.error('[BrowserConnectionProvider] Error closing pages', { error });
|
|
31493
|
-
}
|
|
31494
|
-
}
|
|
31495
|
-
/**
|
|
31496
|
-
* Closes the browser context and disconnects from the browser.
|
|
31497
|
-
*
|
|
31498
|
-
* This should be called when the browser is no longer needed to free up resources.
|
|
31499
|
-
* For local mode, this closes the browser process. For remote mode, it disconnects
|
|
31500
|
-
* from the remote browser but doesn't shut down the remote server.
|
|
31501
|
-
*/
|
|
31502
|
-
async close() {
|
|
31503
|
-
var _a;
|
|
31504
|
-
if (!this.browserContext) {
|
|
31505
|
-
return;
|
|
31506
|
-
}
|
|
31507
|
-
try {
|
|
31508
|
-
if (this.isVerbose) {
|
|
31509
|
-
console.info('[BrowserConnectionProvider] Closing browser context', {
|
|
31510
|
-
mode: (_a = this.connectionMode) === null || _a === void 0 ? void 0 : _a.type,
|
|
31511
|
-
});
|
|
31512
|
-
}
|
|
31513
|
-
await this.browserContext.close();
|
|
31514
|
-
this.browserContext = null;
|
|
31515
|
-
this.connectionMode = null;
|
|
31516
|
-
}
|
|
31517
|
-
catch (error) {
|
|
31518
|
-
console.error('[BrowserConnectionProvider] Error closing browser context', { error });
|
|
31519
|
-
// Reset state even if close fails
|
|
31520
|
-
this.browserContext = null;
|
|
31521
|
-
this.connectionMode = null;
|
|
31522
|
-
}
|
|
31523
|
-
}
|
|
31524
|
-
/**
|
|
31525
|
-
* Checks if a browser context is still alive and connected.
|
|
31526
|
-
*
|
|
31527
|
-
* @param context - Browser context to check
|
|
31528
|
-
* @returns True if the context is connected and usable
|
|
31529
|
-
*/
|
|
31530
|
-
isBrowserContextAlive(context) {
|
|
31531
|
-
try {
|
|
31532
|
-
const browser = context.browser();
|
|
31533
|
-
return browser !== null && browser.isConnected();
|
|
31534
|
-
}
|
|
31535
|
-
catch (_a) {
|
|
31536
|
-
return false;
|
|
31537
|
-
}
|
|
31538
|
-
}
|
|
31539
|
-
/**
|
|
31540
|
-
* Determines whether to use local or remote browser based on configuration.
|
|
31541
|
-
*
|
|
31542
|
-
* @returns Connection mode configuration
|
|
31543
|
-
*/
|
|
31544
|
-
resolveConnectionMode() {
|
|
31545
|
-
const remoteBrowserUrl = REMOTE_BROWSER_URL;
|
|
31546
|
-
if (remoteBrowserUrl && remoteBrowserUrl.trim().length > 0) {
|
|
31547
|
-
return {
|
|
31548
|
-
type: 'remote',
|
|
31549
|
-
wsEndpoint: remoteBrowserUrl.trim(),
|
|
31550
|
-
};
|
|
31551
|
-
}
|
|
31552
|
-
return { type: 'local' };
|
|
31553
|
-
}
|
|
31554
|
-
/**
|
|
31555
|
-
* Creates a local browser context using persistent Chromium.
|
|
31556
|
-
*
|
|
31557
|
-
* @returns Local browser context
|
|
31558
|
-
*/
|
|
31559
|
-
async createLocalBrowserContext() {
|
|
31560
|
-
if (this.isVerbose) {
|
|
31561
|
-
console.info('[BrowserConnectionProvider] Launching local browser context');
|
|
31562
|
-
}
|
|
31563
|
-
const userDataDir = join(DEFAULT_BROWSER_USER_DATA_DIR, 'run-browser');
|
|
31564
|
-
await mkdir(userDataDir, { recursive: true });
|
|
31565
|
-
const launchOptions = {
|
|
31566
|
-
headless: false,
|
|
31567
|
-
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],
|
|
31568
|
-
};
|
|
31569
|
-
try {
|
|
31570
|
-
const chromePath = await locateChrome();
|
|
31571
|
-
launchOptions.executablePath = chromePath;
|
|
31572
|
-
}
|
|
31573
|
-
catch (error) {
|
|
31574
|
-
if (this.isVerbose) {
|
|
31575
|
-
console.warn('[BrowserConnectionProvider] Could not locate system Chrome; using Playwright bundled Chromium', {
|
|
31576
|
-
error: error instanceof Error ? error.message : String(error),
|
|
31577
|
-
});
|
|
31578
|
-
}
|
|
31579
|
-
}
|
|
31580
|
-
return await chromium.launchPersistentContext(userDataDir, launchOptions);
|
|
31581
|
-
}
|
|
31582
|
-
/**
|
|
31583
|
-
* Creates a remote browser context by connecting to a Playwright server.
|
|
31584
|
-
*
|
|
31585
|
-
* @param wsEndpoint - WebSocket endpoint of the remote Playwright server
|
|
31586
|
-
* @returns Remote browser context
|
|
31587
|
-
*/
|
|
31588
|
-
async createRemoteBrowserContext(wsEndpoint, options) {
|
|
31589
|
-
const endpointDebug = sanitizeRemoteBrowserEndpoint(wsEndpoint);
|
|
31590
|
-
const startedAt = Date.now();
|
|
31591
|
-
if (this.isVerbose) {
|
|
31592
|
-
console.info('[BrowserConnectionProvider] Connecting to remote browser', {
|
|
31593
|
-
endpoint: endpointDebug,
|
|
31594
|
-
connectTimeoutMs: this.remoteConnectTimeoutMs,
|
|
31595
|
-
retries: this.remoteConnectRetries,
|
|
31596
|
-
});
|
|
31597
|
-
}
|
|
31598
|
-
let attempts = 0;
|
|
31599
|
-
try {
|
|
31600
|
-
const connectResult = await retryWithBackoff(async (attempt) => {
|
|
31601
|
-
attempts = attempt;
|
|
31602
|
-
return await chromium.connect(wsEndpoint, {
|
|
31603
|
-
timeout: this.remoteConnectTimeoutMs,
|
|
31604
|
-
});
|
|
31605
|
-
}, {
|
|
31606
|
-
retries: this.remoteConnectRetries,
|
|
31607
|
-
initialDelayMs: this.remoteConnectBackoffInitialMs,
|
|
31608
|
-
maxDelayMs: this.remoteConnectBackoffMaxMs,
|
|
31609
|
-
backoffFactor: this.remoteConnectBackoffFactor,
|
|
31610
|
-
jitterRatio: this.remoteConnectJitterRatio,
|
|
31611
|
-
signal: options.signal,
|
|
31612
|
-
shouldRetry: (error) => isRemoteBrowserInfrastructureError(error),
|
|
31613
|
-
onRetry: ({ attempt, delayMs, error }) => {
|
|
31614
|
-
console.warn('[run_browser][retry]', {
|
|
31615
|
-
tool: 'run_browser',
|
|
31616
|
-
mode: 'remote-browser',
|
|
31617
|
-
sessionId: options.sessionId || null,
|
|
31618
|
-
event: 'remote_browser_connect_retry',
|
|
31619
|
-
attempt,
|
|
31620
|
-
delayMs,
|
|
31621
|
-
endpoint: endpointDebug,
|
|
31622
|
-
errorCode: extractNetworkErrorCode(error),
|
|
31623
|
-
error: getErrorMessage(error),
|
|
31624
|
-
});
|
|
31625
|
-
},
|
|
31626
|
-
random: this.random,
|
|
31627
|
-
sleep: this.sleep,
|
|
31628
|
-
});
|
|
31629
|
-
const browser = connectResult.value;
|
|
31630
|
-
// For remote connections, we need to create a new context
|
|
31631
|
-
// Note: Remote browsers don't support persistent contexts
|
|
31632
|
-
const context = await browser.newContext();
|
|
31633
|
-
REMOTE_BROWSER_CONNECT_METRICS.success++;
|
|
31634
|
-
console.info('[run_browser][metric]', {
|
|
31635
|
-
tool: 'run_browser',
|
|
31636
|
-
mode: 'remote-browser',
|
|
31637
|
-
sessionId: options.sessionId || null,
|
|
31638
|
-
event: 'remote_browser_connect_success',
|
|
31639
|
-
attempts: connectResult.attempts,
|
|
31640
|
-
connectDurationMs: connectResult.durationMs,
|
|
31641
|
-
endpoint: endpointDebug,
|
|
31642
|
-
counter: REMOTE_BROWSER_CONNECT_METRICS.success,
|
|
31643
|
-
});
|
|
31644
|
-
if (this.isVerbose) {
|
|
31645
|
-
console.info('[BrowserConnectionProvider] Successfully connected to remote browser');
|
|
31646
|
-
}
|
|
31647
|
-
return context;
|
|
31648
|
-
}
|
|
31649
|
-
catch (error) {
|
|
31650
|
-
REMOTE_BROWSER_CONNECT_METRICS.failure++;
|
|
31651
|
-
const durationMs = Date.now() - startedAt;
|
|
31652
|
-
const remoteInfraUnavailable = isRemoteBrowserInfrastructureError(error);
|
|
31653
|
-
if (remoteInfraUnavailable) {
|
|
31654
|
-
const remoteBrowserUnavailableError = new RemoteBrowserUnavailableError({
|
|
31655
|
-
message: `Remote browser is unavailable. Could not establish a websocket connection.`,
|
|
31656
|
-
debug: {
|
|
31657
|
-
endpoint: endpointDebug,
|
|
31658
|
-
attempts: Math.max(1, attempts),
|
|
31659
|
-
connectTimeoutMs: this.remoteConnectTimeoutMs,
|
|
31660
|
-
durationMs,
|
|
31661
|
-
networkErrorCode: extractNetworkErrorCode(error),
|
|
31662
|
-
originalMessage: getErrorMessage(error),
|
|
31663
|
-
},
|
|
31664
|
-
cause: error,
|
|
31665
|
-
});
|
|
31666
|
-
console.warn('[run_browser][metric]', {
|
|
31667
|
-
tool: 'run_browser',
|
|
31668
|
-
mode: 'remote-browser',
|
|
31669
|
-
sessionId: options.sessionId || null,
|
|
31670
|
-
event: 'remote_browser_connect_failure',
|
|
31671
|
-
errorCode: remoteBrowserUnavailableError.code,
|
|
31672
|
-
attempts: Math.max(1, attempts),
|
|
31673
|
-
connectDurationMs: durationMs,
|
|
31674
|
-
endpoint: endpointDebug,
|
|
31675
|
-
counter: REMOTE_BROWSER_CONNECT_METRICS.failure,
|
|
31676
|
-
});
|
|
31677
|
-
throw remoteBrowserUnavailableError;
|
|
31678
|
-
}
|
|
31679
|
-
console.error('[run_browser][metric]', {
|
|
31680
|
-
tool: 'run_browser',
|
|
31681
|
-
mode: 'remote-browser',
|
|
31682
|
-
sessionId: options.sessionId || null,
|
|
31683
|
-
event: 'remote_browser_connect_failure',
|
|
31684
|
-
errorCode: 'REMOTE_BROWSER_CONNECT_ERROR',
|
|
31685
|
-
attempts: Math.max(1, attempts),
|
|
31686
|
-
connectDurationMs: durationMs,
|
|
31687
|
-
endpoint: endpointDebug,
|
|
31688
|
-
error: getErrorMessage(error),
|
|
31689
|
-
counter: REMOTE_BROWSER_CONNECT_METRICS.failure,
|
|
31690
|
-
});
|
|
31691
|
-
throw error;
|
|
31692
|
-
}
|
|
31693
|
-
}
|
|
31694
|
-
}
|
|
31695
|
-
|
|
31696
|
-
/**
|
|
31697
|
-
* Singleton instance of the browser connection provider.
|
|
31698
|
-
*
|
|
31699
|
-
* @private internal cache for `$provideBrowserForServer`
|
|
31700
|
-
*/
|
|
31701
|
-
let browserProvider = null;
|
|
31702
|
-
/**
|
|
31703
|
-
* Provides a browser context for server-side operations, with caching to reuse instances.
|
|
31704
|
-
*
|
|
31705
|
-
* This function supports both local and remote browser connections based on environment configuration.
|
|
31706
|
-
* Use REMOTE_BROWSER_URL environment variable to configure a remote Playwright server.
|
|
31707
|
-
*
|
|
31708
|
-
* @param options - Optional runtime request options used for cancellation and logging context.
|
|
31709
|
-
* @returns Browser context instance
|
|
31710
|
-
*/
|
|
31711
|
-
async function $provideBrowserForServer(options = {}) {
|
|
31712
|
-
if (browserProvider === null) {
|
|
31713
|
-
browserProvider = new BrowserConnectionProvider({ isVerbose: false });
|
|
31714
|
-
}
|
|
31715
|
-
return await browserProvider.getBrowserContext(options);
|
|
31716
|
-
}
|
|
31717
|
-
/**
|
|
31718
|
-
* TODO: [🏓] Unite `xxxForServer` and `xxxForNode` naming
|
|
31719
|
-
*/
|
|
31720
|
-
|
|
31721
|
-
/**
|
|
31722
|
-
* Attempts to compute time-to-first-byte from Playwright response timing.
|
|
31723
|
-
*/
|
|
31724
|
-
function resolveTimeToFirstByteMs(response) {
|
|
31725
|
-
if (!response) {
|
|
31726
|
-
return null;
|
|
31727
|
-
}
|
|
31728
|
-
try {
|
|
31729
|
-
const timing = response.request().timing();
|
|
31730
|
-
if (typeof (timing === null || timing === void 0 ? void 0 : timing.responseStart) === 'number' &&
|
|
31731
|
-
typeof (timing === null || timing === void 0 ? void 0 : timing.startTime) === 'number' &&
|
|
31732
|
-
timing.responseStart >= timing.startTime) {
|
|
31733
|
-
return Math.round(timing.responseStart - timing.startTime);
|
|
31734
|
-
}
|
|
31735
|
-
}
|
|
31736
|
-
catch (_a) {
|
|
31737
|
-
return null;
|
|
31738
|
-
}
|
|
31739
|
-
return null;
|
|
31740
|
-
}
|
|
31741
|
-
/**
|
|
31742
|
-
* Page open, action normalization and action execution helpers for `run_browser`.
|
|
31743
|
-
*
|
|
31744
|
-
* @private function of `run_browser`
|
|
31745
|
-
*/
|
|
31746
|
-
const runBrowserWorkflow = {
|
|
31747
|
-
/**
|
|
31748
|
-
* Opens a new browser page and navigates to the requested URL.
|
|
31749
|
-
*/
|
|
31750
|
-
async openPageWithUrl(options) {
|
|
31751
|
-
runBrowserErrorHandling.assertNotAborted(options.signal, options.sessionId);
|
|
31752
|
-
const connectStartedAt = Date.now();
|
|
31753
|
-
const browserContext = await $provideBrowserForServer({
|
|
31754
|
-
signal: options.signal,
|
|
31755
|
-
sessionId: options.sessionId,
|
|
31756
|
-
});
|
|
31757
|
-
const connectDurationMs = Date.now() - connectStartedAt;
|
|
31758
|
-
const page = await browserContext.newPage();
|
|
31759
|
-
page.setDefaultNavigationTimeout(options.timeouts.navigationTimeoutMs);
|
|
31760
|
-
page.setDefaultTimeout(options.timeouts.actionTimeoutMs);
|
|
31761
|
-
const navigationStartedAt = Date.now();
|
|
31762
|
-
try {
|
|
31763
|
-
const navigationResponse = await page.goto(options.url, {
|
|
31764
|
-
waitUntil: 'domcontentloaded',
|
|
31765
|
-
timeout: options.timeouts.navigationTimeoutMs,
|
|
31766
|
-
});
|
|
31767
|
-
return {
|
|
31768
|
-
page,
|
|
31769
|
-
connectDurationMs,
|
|
31770
|
-
initialNavigationDurationMs: Date.now() - navigationStartedAt,
|
|
31771
|
-
timeToFirstByteMs: resolveTimeToFirstByteMs(navigationResponse),
|
|
31772
|
-
};
|
|
31773
|
-
}
|
|
31774
|
-
catch (error) {
|
|
31775
|
-
throw runBrowserErrorHandling.createRunBrowserNavigationError({
|
|
31776
|
-
message: `Failed to navigate to \`${options.url}\`.`,
|
|
31777
|
-
debug: {
|
|
31778
|
-
phase: 'initial-navigation',
|
|
31779
|
-
url: options.url,
|
|
31780
|
-
navigationTimeoutMs: options.timeouts.navigationTimeoutMs,
|
|
31781
|
-
},
|
|
31782
|
-
cause: error,
|
|
31783
|
-
});
|
|
31784
|
-
}
|
|
31785
|
-
},
|
|
31786
|
-
/**
|
|
31787
|
-
* Validates and normalizes browser actions received from the model.
|
|
31788
|
-
*/
|
|
31789
|
-
normalizeActions(actions) {
|
|
31790
|
-
if (!actions || actions.length === 0) {
|
|
31791
|
-
return [];
|
|
31792
|
-
}
|
|
31793
|
-
return actions.map((action, index) => this.normalizeAction(action, index));
|
|
31794
|
-
},
|
|
31795
|
-
/**
|
|
31796
|
-
* Validates and normalizes a single action.
|
|
31797
|
-
*/
|
|
31798
|
-
normalizeAction(action, index) {
|
|
31799
|
-
var _a, _b, _c;
|
|
31800
|
-
switch (action.type) {
|
|
31801
|
-
case 'navigate': {
|
|
31802
|
-
const url = String(action.value || '').trim();
|
|
31803
|
-
if (!url) {
|
|
31804
|
-
throw runBrowserErrorHandling.createRunBrowserValidationError({
|
|
31805
|
-
message: spaceTrim$1(`Action ${index + 1}: \`navigate\` requires non-empty \`value\` URL.`),
|
|
31806
|
-
debug: {
|
|
31807
|
-
actionIndex: index + 1,
|
|
31808
|
-
actionType: action.type,
|
|
31809
|
-
},
|
|
31810
|
-
});
|
|
31811
|
-
}
|
|
31812
|
-
return { type: 'navigate', url };
|
|
31813
|
-
}
|
|
31814
|
-
case 'click': {
|
|
31815
|
-
const selector = String(action.selector || '').trim();
|
|
31816
|
-
if (!selector) {
|
|
31817
|
-
throw runBrowserErrorHandling.createRunBrowserValidationError({
|
|
31818
|
-
message: spaceTrim$1(`Action ${index + 1}: \`click\` requires non-empty \`selector\`.`),
|
|
31819
|
-
debug: {
|
|
31820
|
-
actionIndex: index + 1,
|
|
31821
|
-
actionType: action.type,
|
|
31822
|
-
},
|
|
31823
|
-
});
|
|
31824
|
-
}
|
|
31825
|
-
return { type: 'click', selector };
|
|
31826
|
-
}
|
|
31827
|
-
case 'type': {
|
|
31828
|
-
const selector = String(action.selector || '').trim();
|
|
31829
|
-
if (!selector) {
|
|
31830
|
-
throw runBrowserErrorHandling.createRunBrowserValidationError({
|
|
31831
|
-
message: spaceTrim$1(`Action ${index + 1}: \`type\` requires non-empty \`selector\`.`),
|
|
31832
|
-
debug: {
|
|
31833
|
-
actionIndex: index + 1,
|
|
31834
|
-
actionType: action.type,
|
|
31835
|
-
},
|
|
31836
|
-
});
|
|
31837
|
-
}
|
|
31838
|
-
const text = String((_a = action.value) !== null && _a !== void 0 ? _a : '');
|
|
31839
|
-
return { type: 'type', selector, text };
|
|
31840
|
-
}
|
|
31841
|
-
case 'wait': {
|
|
31842
|
-
const requestedValue = Number.parseInt(String((_b = action.value) !== null && _b !== void 0 ? _b : runBrowserConstants.defaultWaitMs), 10);
|
|
31843
|
-
const milliseconds = Number.isFinite(requestedValue)
|
|
31844
|
-
? Math.min(Math.max(requestedValue, 1), runBrowserConstants.maxWaitMs)
|
|
31845
|
-
: runBrowserConstants.defaultWaitMs;
|
|
31846
|
-
return { type: 'wait', milliseconds };
|
|
31847
|
-
}
|
|
31848
|
-
case 'scroll': {
|
|
31849
|
-
const requestedValue = Number.parseInt(String((_c = action.value) !== null && _c !== void 0 ? _c : runBrowserConstants.defaultScrollPixels), 10);
|
|
31850
|
-
const pixels = Number.isFinite(requestedValue) ? requestedValue : runBrowserConstants.defaultScrollPixels;
|
|
31851
|
-
const rawSelector = String(action.selector || '').trim();
|
|
31852
|
-
return { type: 'scroll', selector: rawSelector || null, pixels };
|
|
31853
|
-
}
|
|
31854
|
-
}
|
|
31855
|
-
},
|
|
31856
|
-
/**
|
|
31857
|
-
* Executes one normalized browser action on a Playwright page.
|
|
31858
|
-
*/
|
|
31859
|
-
async executeAction(options) {
|
|
31860
|
-
const { page, action, actionIndex, timeouts, signal } = options;
|
|
31861
|
-
runBrowserErrorHandling.assertNotAborted(signal, `action-${actionIndex}`);
|
|
31862
|
-
try {
|
|
31863
|
-
switch (action.type) {
|
|
31864
|
-
case 'navigate':
|
|
31865
|
-
await page.goto(action.url, {
|
|
31866
|
-
waitUntil: 'domcontentloaded',
|
|
31867
|
-
timeout: timeouts.navigationTimeoutMs,
|
|
31868
|
-
});
|
|
31869
|
-
return;
|
|
31870
|
-
case 'click':
|
|
31871
|
-
await page.locator(action.selector).first().click({ timeout: timeouts.actionTimeoutMs });
|
|
31872
|
-
return;
|
|
31873
|
-
case 'type':
|
|
31874
|
-
await page.locator(action.selector).first().fill(action.text, { timeout: timeouts.actionTimeoutMs });
|
|
31875
|
-
return;
|
|
31876
|
-
case 'wait':
|
|
31877
|
-
if (action.milliseconds > timeouts.actionTimeoutMs) {
|
|
31878
|
-
throw runBrowserErrorHandling.createRunBrowserActionError({
|
|
31879
|
-
message: `Action ${actionIndex}: \`wait\` exceeds action timeout (${timeouts.actionTimeoutMs}ms).`,
|
|
31880
|
-
debug: {
|
|
31881
|
-
actionIndex,
|
|
31882
|
-
action,
|
|
31883
|
-
actionTimeoutMs: timeouts.actionTimeoutMs,
|
|
31884
|
-
},
|
|
31885
|
-
});
|
|
31886
|
-
}
|
|
31887
|
-
await page.waitForTimeout(action.milliseconds);
|
|
31888
|
-
return;
|
|
31889
|
-
case 'scroll':
|
|
31890
|
-
if (action.selector) {
|
|
31891
|
-
await page
|
|
31892
|
-
.locator(action.selector)
|
|
31893
|
-
.first()
|
|
31894
|
-
.scrollIntoViewIfNeeded({ timeout: timeouts.actionTimeoutMs });
|
|
31895
|
-
}
|
|
31896
|
-
await page.mouse.wheel(0, action.pixels);
|
|
31897
|
-
return;
|
|
31898
|
-
}
|
|
31899
|
-
}
|
|
31900
|
-
catch (error) {
|
|
31901
|
-
if (runBrowserErrorHandling.isTaggedRunBrowserError(error)) {
|
|
31902
|
-
throw error;
|
|
31903
|
-
}
|
|
31904
|
-
if (action.type === 'navigate') {
|
|
31905
|
-
throw runBrowserErrorHandling.createRunBrowserNavigationError({
|
|
31906
|
-
message: `Action ${actionIndex}: failed to navigate to \`${action.url}\`.`,
|
|
31907
|
-
debug: {
|
|
31908
|
-
actionIndex,
|
|
31909
|
-
action,
|
|
31910
|
-
navigationTimeoutMs: timeouts.navigationTimeoutMs,
|
|
31911
|
-
},
|
|
31912
|
-
cause: error,
|
|
31913
|
-
});
|
|
31914
|
-
}
|
|
31915
|
-
throw runBrowserErrorHandling.createRunBrowserActionError({
|
|
31916
|
-
message: `Action ${actionIndex}: failed to execute \`${action.type}\`.`,
|
|
31917
|
-
debug: {
|
|
31918
|
-
actionIndex,
|
|
31919
|
-
action,
|
|
31920
|
-
actionTimeoutMs: timeouts.actionTimeoutMs,
|
|
31921
|
-
},
|
|
31922
|
-
cause: error,
|
|
31923
|
-
});
|
|
31924
|
-
}
|
|
31925
|
-
},
|
|
31926
|
-
};
|
|
31927
|
-
|
|
31928
|
-
/**
|
|
31929
|
-
* Summarizes one normalized browser action in user-facing language.
|
|
31930
|
-
*/
|
|
31931
|
-
function formatRunBrowserActionSummary(action) {
|
|
31932
|
-
switch (action.type) {
|
|
31933
|
-
case 'navigate':
|
|
31934
|
-
return `Navigate to ${action.url}`;
|
|
31935
|
-
case 'click':
|
|
31936
|
-
return `Click ${action.selector}`;
|
|
31937
|
-
case 'type':
|
|
31938
|
-
return `Type into ${action.selector}`;
|
|
31939
|
-
case 'wait':
|
|
31940
|
-
return `Wait ${action.milliseconds}ms`;
|
|
31941
|
-
case 'scroll':
|
|
31942
|
-
return action.selector ? `Scroll ${action.pixels}px in ${action.selector}` : `Scroll ${action.pixels}px on page`;
|
|
31943
|
-
}
|
|
31944
|
-
}
|
|
31945
|
-
/**
|
|
31946
|
-
* Emits one incremental browser-tool update when a hidden chat-progress listener is attached.
|
|
31947
|
-
*/
|
|
31948
|
-
function emitRunBrowserProgress(args, update) {
|
|
31949
|
-
emitToolCallProgressFromToolArgs(args, update);
|
|
31950
|
-
}
|
|
31951
|
-
/**
|
|
31952
|
-
* Returns the current timestamp in the branded ISO-8601 format used by tool-call logs.
|
|
31953
|
-
*/
|
|
31954
|
-
function createRunBrowserLogTimestamp() {
|
|
31955
|
-
return new Date().toISOString();
|
|
31956
|
-
}
|
|
31957
|
-
/**
|
|
31958
|
-
* Executes non-graphical fallback scraping.
|
|
31959
|
-
*/
|
|
31960
|
-
async function runFallbackScrape(url) {
|
|
31961
|
-
return await fetchUrlContent(url);
|
|
31962
|
-
}
|
|
31963
|
-
/**
|
|
31964
|
-
* Runs interactive browser automation through Playwright.
|
|
31965
|
-
*
|
|
31966
|
-
* @param args Tool arguments provided by the model.
|
|
31967
|
-
* @param internalOptions Optional runtime options for cancellation.
|
|
31968
|
-
* @returns Markdown summary with structured playback payload.
|
|
31969
|
-
*/
|
|
31970
|
-
async function run_browser(args, internalOptions = {}) {
|
|
31971
|
-
runBrowserObservability.incrementTotalRuns();
|
|
31972
|
-
const startedAt = Date.now();
|
|
31973
|
-
const sessionId = runBrowserRuntime.createRunBrowserSessionId();
|
|
31974
|
-
const initialUrl = String(args.url || '').trim();
|
|
31975
|
-
const mode = runBrowserRuntime.resolveExecutionMode();
|
|
31976
|
-
const timeoutConfiguration = runBrowserRuntime.resolveTimeoutConfiguration(args.timeouts);
|
|
31977
|
-
let page = null;
|
|
31978
|
-
let connectDurationMs = null;
|
|
31979
|
-
let initialNavigationDurationMs = null;
|
|
31980
|
-
let timeToFirstByteMs = null;
|
|
31981
|
-
try {
|
|
31982
|
-
if (!initialUrl) {
|
|
31983
|
-
throw runBrowserErrorHandling.createRunBrowserValidationError({
|
|
31984
|
-
message: 'Missing required `url` argument.',
|
|
31985
|
-
debug: {
|
|
31986
|
-
field: 'url',
|
|
31987
|
-
},
|
|
31988
|
-
});
|
|
31989
|
-
}
|
|
31990
|
-
const normalizedActions = runBrowserWorkflow.normalizeActions(args.actions);
|
|
31991
|
-
runBrowserErrorHandling.assertNotAborted(internalOptions.signal, sessionId);
|
|
31992
|
-
const openedPage = await runBrowserWorkflow.openPageWithUrl({
|
|
31993
|
-
url: initialUrl,
|
|
31994
|
-
sessionId,
|
|
31995
|
-
timeouts: timeoutConfiguration,
|
|
31996
|
-
signal: internalOptions.signal,
|
|
31997
|
-
});
|
|
31998
|
-
page = openedPage.page;
|
|
31999
|
-
connectDurationMs = openedPage.connectDurationMs;
|
|
32000
|
-
initialNavigationDurationMs = openedPage.initialNavigationDurationMs;
|
|
32001
|
-
timeToFirstByteMs = openedPage.timeToFirstByteMs;
|
|
32002
|
-
emitRunBrowserProgress(args, {
|
|
32003
|
-
state: 'PARTIAL',
|
|
32004
|
-
log: {
|
|
32005
|
-
createdAt: createRunBrowserLogTimestamp(),
|
|
32006
|
-
kind: 'browser-session',
|
|
32007
|
-
title: 'Browser ready',
|
|
32008
|
-
message: 'Opened the initial page and started the browser session.',
|
|
32009
|
-
payload: {
|
|
32010
|
-
sessionId,
|
|
32011
|
-
initialUrl,
|
|
32012
|
-
connectDurationMs,
|
|
32013
|
-
initialNavigationDurationMs,
|
|
32014
|
-
timeToFirstByteMs,
|
|
32015
|
-
},
|
|
32016
|
-
},
|
|
32017
|
-
});
|
|
32018
|
-
const artifacts = [];
|
|
32019
|
-
const initialArtifact = await runBrowserArtifacts.captureSnapshotArtifact({
|
|
32020
|
-
page,
|
|
32021
|
-
sessionId,
|
|
32022
|
-
label: 'Initial page',
|
|
32023
|
-
fileSuffix: 'initial',
|
|
32024
|
-
});
|
|
32025
|
-
if (initialArtifact) {
|
|
32026
|
-
artifacts.push(initialArtifact);
|
|
32027
|
-
}
|
|
32028
|
-
for (const [index, action] of normalizedActions.entries()) {
|
|
32029
|
-
runBrowserErrorHandling.assertNotAborted(internalOptions.signal, sessionId);
|
|
32030
|
-
emitRunBrowserProgress(args, {
|
|
32031
|
-
state: 'PARTIAL',
|
|
32032
|
-
log: {
|
|
32033
|
-
createdAt: createRunBrowserLogTimestamp(),
|
|
32034
|
-
kind: 'browser-action',
|
|
32035
|
-
title: `Action ${index + 1} running`,
|
|
32036
|
-
message: formatRunBrowserActionSummary(action),
|
|
32037
|
-
payload: {
|
|
32038
|
-
actionIndex: index + 1,
|
|
32039
|
-
action,
|
|
32040
|
-
phase: 'running',
|
|
32041
|
-
},
|
|
32042
|
-
},
|
|
32043
|
-
});
|
|
32044
|
-
await runBrowserWorkflow.executeAction({
|
|
32045
|
-
page,
|
|
32046
|
-
action,
|
|
32047
|
-
actionIndex: index + 1,
|
|
32048
|
-
timeouts: timeoutConfiguration,
|
|
32049
|
-
signal: internalOptions.signal,
|
|
32050
|
-
});
|
|
32051
|
-
emitRunBrowserProgress(args, {
|
|
32052
|
-
state: 'PARTIAL',
|
|
32053
|
-
log: {
|
|
32054
|
-
createdAt: createRunBrowserLogTimestamp(),
|
|
32055
|
-
kind: 'browser-action',
|
|
32056
|
-
title: `Action ${index + 1} finished`,
|
|
32057
|
-
message: formatRunBrowserActionSummary(action),
|
|
32058
|
-
payload: {
|
|
32059
|
-
actionIndex: index + 1,
|
|
32060
|
-
action,
|
|
32061
|
-
phase: 'complete',
|
|
32062
|
-
},
|
|
32063
|
-
},
|
|
32064
|
-
});
|
|
32065
|
-
const actionArtifact = await runBrowserArtifacts.captureSnapshotArtifact({
|
|
32066
|
-
page,
|
|
32067
|
-
sessionId,
|
|
32068
|
-
label: `After action ${index + 1}`,
|
|
32069
|
-
fileSuffix: `action-${String(index + 1).padStart(3, '0')}-${action.type}`,
|
|
32070
|
-
actionIndex: index + 1,
|
|
32071
|
-
action,
|
|
32072
|
-
});
|
|
32073
|
-
if (actionArtifact) {
|
|
32074
|
-
artifacts.push(actionArtifact);
|
|
32075
|
-
}
|
|
32076
|
-
}
|
|
32077
|
-
const snapshotPath = await runBrowserArtifacts.captureSnapshot(page, sessionId);
|
|
32078
|
-
const finalUrl = page.url();
|
|
32079
|
-
const finalTitle = await runBrowserArtifacts.getPageTitle(page);
|
|
32080
|
-
if (snapshotPath) {
|
|
32081
|
-
artifacts.push({
|
|
32082
|
-
kind: 'screenshot',
|
|
32083
|
-
label: 'Final page',
|
|
32084
|
-
path: snapshotPath,
|
|
32085
|
-
capturedAt: new Date().toISOString(),
|
|
32086
|
-
url: finalUrl,
|
|
32087
|
-
title: finalTitle,
|
|
32088
|
-
});
|
|
32089
|
-
}
|
|
32090
|
-
const payload = runBrowserResultFormatting.createResultPayload({
|
|
32091
|
-
sessionId,
|
|
32092
|
-
mode,
|
|
32093
|
-
modeUsed: 'remote-browser',
|
|
32094
|
-
initialUrl,
|
|
32095
|
-
finalUrl,
|
|
32096
|
-
finalTitle,
|
|
32097
|
-
executedActions: normalizedActions,
|
|
32098
|
-
artifacts,
|
|
32099
|
-
warning: null,
|
|
32100
|
-
error: null,
|
|
32101
|
-
fallbackContent: null,
|
|
32102
|
-
timing: {
|
|
32103
|
-
connectDurationMs,
|
|
32104
|
-
initialNavigationDurationMs,
|
|
32105
|
-
timeToFirstByteMs,
|
|
32106
|
-
totalDurationMs: Date.now() - startedAt,
|
|
32107
|
-
},
|
|
32108
|
-
});
|
|
32109
|
-
runBrowserObservability.logRunBrowserMetric({
|
|
32110
|
-
event: 'run_browser_success',
|
|
32111
|
-
sessionId,
|
|
32112
|
-
mode: 'remote-browser',
|
|
32113
|
-
payload: {
|
|
32114
|
-
actions: normalizedActions.length,
|
|
32115
|
-
connectDurationMs,
|
|
32116
|
-
initialNavigationDurationMs,
|
|
32117
|
-
timeToFirstByteMs,
|
|
32118
|
-
},
|
|
32119
|
-
});
|
|
32120
|
-
return runBrowserResultFormatting.formatSuccessResult({
|
|
32121
|
-
payload,
|
|
32122
|
-
snapshotPath,
|
|
32123
|
-
});
|
|
32124
|
-
}
|
|
32125
|
-
catch (error) {
|
|
32126
|
-
const toolError = runBrowserErrorHandling.classifyRunBrowserToolError({
|
|
32127
|
-
error,
|
|
32128
|
-
sessionId,
|
|
32129
|
-
mode,
|
|
32130
|
-
});
|
|
32131
|
-
const errorCodeCount = runBrowserObservability.incrementRunBrowserErrorCodeCounter(toolError.code);
|
|
32132
|
-
if (runBrowserErrorHandling.isRemoteBrowserUnavailableCode(toolError.code) && initialUrl) {
|
|
32133
|
-
const fallbackContent = await runFallbackScrape(initialUrl);
|
|
32134
|
-
const { fallbackRuns, fallbackRate } = runBrowserObservability.incrementFallbackRunsAndGetMetrics();
|
|
32135
|
-
emitRunBrowserProgress(args, {
|
|
32136
|
-
state: 'PARTIAL',
|
|
32137
|
-
log: {
|
|
32138
|
-
createdAt: createRunBrowserLogTimestamp(),
|
|
32139
|
-
kind: 'warning',
|
|
32140
|
-
level: 'warning',
|
|
32141
|
-
title: 'Fallback enabled',
|
|
32142
|
-
message: 'Remote browser was unavailable, so fallback scraping was used instead.',
|
|
32143
|
-
payload: {
|
|
32144
|
-
errorCode: toolError.code,
|
|
32145
|
-
initialUrl,
|
|
32146
|
-
},
|
|
32147
|
-
},
|
|
32148
|
-
});
|
|
32149
|
-
const payload = runBrowserResultFormatting.createResultPayload({
|
|
32150
|
-
sessionId,
|
|
32151
|
-
mode,
|
|
32152
|
-
modeUsed: 'fallback',
|
|
32153
|
-
initialUrl,
|
|
32154
|
-
finalUrl: null,
|
|
32155
|
-
finalTitle: null,
|
|
32156
|
-
executedActions: [],
|
|
32157
|
-
artifacts: [],
|
|
32158
|
-
warning: runBrowserConstants.fallbackDynamicContentWarning,
|
|
32159
|
-
error: toolError,
|
|
32160
|
-
fallbackContent,
|
|
32161
|
-
timing: {
|
|
32162
|
-
connectDurationMs,
|
|
32163
|
-
initialNavigationDurationMs,
|
|
32164
|
-
timeToFirstByteMs,
|
|
32165
|
-
totalDurationMs: Date.now() - startedAt,
|
|
32166
|
-
},
|
|
32167
|
-
});
|
|
32168
|
-
runBrowserObservability.logRunBrowserMetric({
|
|
32169
|
-
event: 'run_browser_fallback_used',
|
|
32170
|
-
sessionId,
|
|
32171
|
-
mode: 'fallback',
|
|
32172
|
-
payload: {
|
|
32173
|
-
errorCode: toolError.code,
|
|
32174
|
-
errorCodeCount,
|
|
32175
|
-
fallbackRuns,
|
|
32176
|
-
totalRuns: runBrowserObservability.getTotalRuns(),
|
|
32177
|
-
fallbackRate,
|
|
32178
|
-
},
|
|
32179
|
-
});
|
|
32180
|
-
return runBrowserResultFormatting.formatFallbackResult({
|
|
32181
|
-
payload,
|
|
32182
|
-
fallbackContent,
|
|
32183
|
-
requestedActions: Array.isArray(args.actions) ? args.actions.length : 0,
|
|
32184
|
-
});
|
|
32185
|
-
}
|
|
32186
|
-
emitRunBrowserProgress(args, {
|
|
32187
|
-
state: 'ERROR',
|
|
32188
|
-
log: {
|
|
32189
|
-
createdAt: createRunBrowserLogTimestamp(),
|
|
32190
|
-
kind: 'error',
|
|
32191
|
-
level: 'error',
|
|
32192
|
-
title: 'Browser run failed',
|
|
32193
|
-
message: toolError.message,
|
|
32194
|
-
payload: {
|
|
32195
|
-
code: toolError.code,
|
|
32196
|
-
debug: toolError.debug,
|
|
32197
|
-
},
|
|
32198
|
-
},
|
|
32199
|
-
});
|
|
32200
|
-
const payload = runBrowserResultFormatting.createResultPayload({
|
|
32201
|
-
sessionId,
|
|
32202
|
-
mode,
|
|
32203
|
-
modeUsed: 'remote-browser',
|
|
32204
|
-
initialUrl,
|
|
32205
|
-
finalUrl: page ? page.url() : null,
|
|
32206
|
-
finalTitle: page ? await runBrowserArtifacts.getPageTitle(page) : null,
|
|
32207
|
-
executedActions: [],
|
|
32208
|
-
artifacts: [],
|
|
32209
|
-
warning: null,
|
|
32210
|
-
error: toolError,
|
|
32211
|
-
fallbackContent: null,
|
|
32212
|
-
timing: {
|
|
32213
|
-
connectDurationMs,
|
|
32214
|
-
initialNavigationDurationMs,
|
|
32215
|
-
timeToFirstByteMs,
|
|
32216
|
-
totalDurationMs: Date.now() - startedAt,
|
|
32217
|
-
},
|
|
32218
|
-
});
|
|
32219
|
-
runBrowserObservability.logRunBrowserMetric({
|
|
32220
|
-
event: 'run_browser_failed',
|
|
32221
|
-
sessionId,
|
|
32222
|
-
mode: 'remote-browser',
|
|
32223
|
-
payload: {
|
|
32224
|
-
errorCode: toolError.code,
|
|
32225
|
-
errorCodeCount,
|
|
32226
|
-
connectDurationMs,
|
|
32227
|
-
initialNavigationDurationMs,
|
|
32228
|
-
timeToFirstByteMs,
|
|
32229
|
-
},
|
|
32230
|
-
});
|
|
32231
|
-
return runBrowserResultFormatting.formatErrorResult({
|
|
32232
|
-
payload,
|
|
32233
|
-
});
|
|
32234
|
-
}
|
|
32235
|
-
finally {
|
|
32236
|
-
await runBrowserArtifacts.cleanupPage(page, sessionId);
|
|
32237
|
-
}
|
|
32238
|
-
}
|
|
32239
|
-
|
|
32240
|
-
/**
|
|
32241
|
-
* Resolves the server-side implementation of the `run_browser` tool for Node.js environments.
|
|
32242
|
-
*
|
|
32243
|
-
* This uses lazy `require` to keep the core package decoupled from Agents Server internals.
|
|
32244
|
-
* When the server tool cannot be resolved, the fallback implementation throws a helpful error.
|
|
32245
|
-
*
|
|
32246
|
-
* @private internal utility for USE BROWSER commitment
|
|
32247
|
-
*/
|
|
32248
|
-
function resolveRunBrowserToolForNode() {
|
|
32249
|
-
try {
|
|
32250
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
32251
|
-
// const { run_browser } = require('../../../apps/agents-server/src/tools/run_browser');
|
|
32252
|
-
if (typeof run_browser !== 'function') {
|
|
32253
|
-
throw new Error('run_browser value is not a function but ' + typeof run_browser);
|
|
32254
|
-
}
|
|
32255
|
-
return run_browser;
|
|
32256
|
-
}
|
|
32257
|
-
catch (error) {
|
|
32258
|
-
assertsError(error);
|
|
32259
|
-
return async () => {
|
|
32260
|
-
throw new EnvironmentMismatchError(spaceTrim$1((block) => `
|
|
32261
|
-
\`run_browser\` tool is not available in this environment.
|
|
32262
|
-
This commitment requires the Agents Server browser runtime with Playwright CLI.
|
|
32263
|
-
|
|
32264
|
-
${error.name}:
|
|
32265
|
-
${block(error.message)}
|
|
32266
|
-
`));
|
|
32267
|
-
};
|
|
32268
|
-
}
|
|
32269
|
-
}
|
|
32270
|
-
|
|
32271
|
-
/**
|
|
32272
|
-
* Resolves the server-side implementation of the send_email tool for Node.js environments.
|
|
32273
|
-
*
|
|
32274
|
-
* This uses a lazy require so the core package can still load even if the Agents Server
|
|
32275
|
-
* module is unavailable. When the server tool cannot be resolved, a fallback implementation
|
|
32276
|
-
* throws a helpful error message.
|
|
32277
|
-
*
|
|
32278
|
-
* @private internal utility for USE EMAIL commitment
|
|
32279
|
-
*/
|
|
32280
|
-
function resolveSendEmailToolForNode() {
|
|
32281
|
-
try {
|
|
32282
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
32283
|
-
const { send_email } = require('../../../apps/agents-server/src/tools/send_email');
|
|
32284
|
-
if (typeof send_email !== 'function') {
|
|
32285
|
-
throw new Error('send_email value is not a function but ' + typeof send_email);
|
|
32286
|
-
}
|
|
32287
|
-
return send_email;
|
|
32288
|
-
}
|
|
32289
|
-
catch (error) {
|
|
32290
|
-
const normalizedError = error instanceof Error
|
|
32291
|
-
? error
|
|
32292
|
-
: new Error(typeof error === 'string' ? error : JSON.stringify(error !== null && error !== void 0 ? error : 'Unknown error'));
|
|
32293
|
-
return async () => {
|
|
32294
|
-
throw new EnvironmentMismatchError(spaceTrim$1((block) => `
|
|
32295
|
-
\`send_email\` tool is not available in this environment.
|
|
32296
|
-
This commitment requires Agents Server runtime with wallet-backed SMTP sending.
|
|
32297
|
-
|
|
32298
|
-
${normalizedError.name}:
|
|
32299
|
-
${block(normalizedError.message)}
|
|
32300
|
-
`));
|
|
32301
|
-
};
|
|
32302
|
-
}
|
|
32303
|
-
}
|
|
32304
|
-
|
|
32305
|
-
/**
|
|
32306
|
-
* Resolves the server-side `spawn_agent` tool for Node.js runtimes.
|
|
32307
|
-
*
|
|
32308
|
-
* Uses lazy require so core package can load outside Agents Server.
|
|
32309
|
-
*
|
|
32310
|
-
* @private internal utility for USE SPAWN commitment
|
|
32311
|
-
*/
|
|
32312
|
-
function resolveSpawnAgentToolForNode() {
|
|
32313
|
-
try {
|
|
32314
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
32315
|
-
const { spawn_agent } = require('../../../apps/agents-server/src/tools/spawn_agent');
|
|
32316
|
-
if (typeof spawn_agent !== 'function') {
|
|
32317
|
-
throw new Error('spawn_agent value is not a function but ' + typeof spawn_agent);
|
|
32318
|
-
}
|
|
32319
|
-
return spawn_agent;
|
|
32320
|
-
}
|
|
32321
|
-
catch (error) {
|
|
32322
|
-
const normalizedError = error instanceof Error
|
|
32323
|
-
? error
|
|
32324
|
-
: new Error(typeof error === 'string' ? error : JSON.stringify(error !== null && error !== void 0 ? error : 'Unknown error'));
|
|
32325
|
-
return async () => {
|
|
32326
|
-
throw new EnvironmentMismatchError(spaceTrim$1((block) => `
|
|
32327
|
-
\`spawn_agent\` tool is not available in this environment.
|
|
32328
|
-
This commitment requires Agents Server runtime with agent persistence enabled.
|
|
32329
|
-
|
|
32330
|
-
${normalizedError.name}:
|
|
32331
|
-
${block(normalizedError.message)}
|
|
32332
|
-
`));
|
|
32333
|
-
};
|
|
32334
|
-
}
|
|
32335
|
-
}
|
|
32336
|
-
|
|
32337
|
-
/**
|
|
32338
|
-
* Collects tool functions from all commitment definitions.
|
|
32339
|
-
*
|
|
32340
|
-
* @returns Map of tool function implementations.
|
|
32341
|
-
* @private internal helper for commitment tool registry
|
|
32342
|
-
*/
|
|
32343
|
-
function collectCommitmentToolFunctions() {
|
|
32344
|
-
const allToolFunctions = {};
|
|
32345
|
-
for (const commitmentDefinition of getAllCommitmentDefinitions()) {
|
|
32346
|
-
const toolFunctions = commitmentDefinition.getToolFunctions();
|
|
32347
|
-
for (const [funcName, funcImpl] of Object.entries(toolFunctions)) {
|
|
32348
|
-
if (allToolFunctions[funcName] !== undefined &&
|
|
32349
|
-
just(false) /* <- Note: [??] How to deal with commitment aliases */) {
|
|
32350
|
-
throw new UnexpectedError(`Duplicate tool function name detected: \`${funcName}\` provided by commitment \`${commitmentDefinition.type}\``);
|
|
32351
|
-
}
|
|
32352
|
-
allToolFunctions[funcName] = funcImpl;
|
|
32353
|
-
}
|
|
32354
|
-
}
|
|
32355
|
-
return allToolFunctions;
|
|
32356
|
-
}
|
|
32357
|
-
/**
|
|
32358
|
-
* Creates a proxy that resolves tool functions on demand.
|
|
32359
|
-
*
|
|
32360
|
-
* @param getFunctions - Provider of current tool functions.
|
|
32361
|
-
* @returns Proxy exposing tool functions as properties.
|
|
32362
|
-
* @private internal helper for commitment tool registry
|
|
32363
|
-
*/
|
|
32364
|
-
function createToolFunctionsProxy(getFunctions) {
|
|
32365
|
-
const resolveFunctions = () => getFunctions();
|
|
32366
|
-
return new Proxy({}, {
|
|
32367
|
-
get(_target, prop) {
|
|
32368
|
-
if (typeof prop !== 'string') {
|
|
32369
|
-
return undefined;
|
|
32370
|
-
}
|
|
32371
|
-
return resolveFunctions()[prop];
|
|
32372
|
-
},
|
|
32373
|
-
has(_target, prop) {
|
|
32374
|
-
if (typeof prop !== 'string') {
|
|
32375
|
-
return false;
|
|
32376
|
-
}
|
|
32377
|
-
return prop in resolveFunctions();
|
|
32378
|
-
},
|
|
32379
|
-
ownKeys() {
|
|
32380
|
-
return Object.keys(resolveFunctions());
|
|
32381
|
-
},
|
|
32382
|
-
getOwnPropertyDescriptor(_target, prop) {
|
|
32383
|
-
if (typeof prop !== 'string') {
|
|
32384
|
-
return undefined;
|
|
32385
|
-
}
|
|
32386
|
-
const value = resolveFunctions()[prop];
|
|
32387
|
-
if (value === undefined) {
|
|
32388
|
-
return undefined;
|
|
32389
|
-
}
|
|
32390
|
-
return {
|
|
32391
|
-
enumerable: true,
|
|
32392
|
-
configurable: true,
|
|
32393
|
-
writable: false,
|
|
32394
|
-
value,
|
|
32395
|
-
};
|
|
32396
|
-
},
|
|
32397
|
-
});
|
|
32398
|
-
}
|
|
32399
|
-
/**
|
|
32400
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
32401
|
-
*/
|
|
32402
|
-
|
|
32403
|
-
const nodeToolFunctions = {
|
|
32404
|
-
/**
|
|
32405
|
-
* @@@
|
|
32406
|
-
*
|
|
32407
|
-
* Note: [??] This function has implementation both for browser and node, this is the full one for node
|
|
32408
|
-
*/
|
|
32409
|
-
async fetch_url_content(args) {
|
|
32410
|
-
console.log('!!!! [Tool] fetch_url_content called', { args });
|
|
32411
|
-
const { url } = args;
|
|
32412
|
-
return await fetchUrlContent(url);
|
|
32413
|
-
},
|
|
32414
|
-
/**
|
|
32415
|
-
* @@@
|
|
32416
|
-
*
|
|
32417
|
-
* Note: [??] This function has implementation both for browser and node, this is the server one for node
|
|
32418
|
-
*/
|
|
32419
|
-
run_browser: resolveRunBrowserToolForNode(),
|
|
32420
|
-
/**
|
|
32421
|
-
* @@@
|
|
32422
|
-
*
|
|
32423
|
-
* Note: [??] This function has implementation both for browser and node, this is the server one for node
|
|
32424
|
-
*/
|
|
32425
|
-
send_email: resolveSendEmailToolForNode(),
|
|
32426
|
-
/**
|
|
32427
|
-
* @@@
|
|
32428
|
-
*
|
|
32429
|
-
* Note: [??] This function has implementation both for browser and node, this is the server one for node
|
|
32430
|
-
*/
|
|
32431
|
-
spawn_agent: resolveSpawnAgentToolForNode(),
|
|
32432
|
-
// TODO: !!!! Unhardcode, make proper server function register from definitions
|
|
32433
|
-
};
|
|
32434
|
-
const nodeToolFunctionsProxy = createToolFunctionsProxy(() => ({
|
|
32435
|
-
...collectCommitmentToolFunctions(),
|
|
32436
|
-
...nodeToolFunctions,
|
|
32437
|
-
}));
|
|
32438
|
-
/**
|
|
32439
|
-
* Gets all function implementations provided by all commitments
|
|
32440
|
-
*
|
|
32441
|
-
* Note: This function is intended for server use, there is also equivalent `getAllCommitmentsToolFunctionsForBrowser` for browser use
|
|
32442
|
-
*
|
|
32443
|
-
* @public exported from `@promptbook/node`
|
|
32444
|
-
*/
|
|
32445
|
-
function getAllCommitmentsToolFunctionsForNode() {
|
|
32446
|
-
if (!$isRunningInNode()) {
|
|
32447
|
-
throw new EnvironmentMismatchError(spaceTrim(`
|
|
32448
|
-
Function getAllCommitmentsToolFunctionsForNode should be run in Node.js environment.
|
|
32449
|
-
|
|
32450
|
-
- In browser use getAllCommitmentsToolFunctionsForBrowser instead.
|
|
32451
|
-
- This function can include server-only tools which cannot run in browser environment.
|
|
32452
|
-
|
|
32453
|
-
`));
|
|
32454
|
-
}
|
|
32455
|
-
return nodeToolFunctionsProxy;
|
|
32456
|
-
}
|
|
32457
|
-
/**
|
|
32458
|
-
* Note: [??] Code in this file should never be never released in packages that could be imported into browser environment
|
|
32459
|
-
* TODO: [??] Unite `xxxForServer` and `xxxForNode` naming
|
|
32460
|
-
*/
|
|
32461
|
-
|
|
32462
30654
|
/**
|
|
32463
30655
|
* Locates the LibreOffice executable on the current system by searching platform-specific paths.
|
|
32464
30656
|
* Returns the path to the executable if found, or null otherwise.
|
|
@@ -32615,13 +30807,13 @@ function $registeredLlmToolsMessage() {
|
|
|
32615
30807
|
});
|
|
32616
30808
|
const usedEnvMessage = $usedEnvFilename === null ? `Unknown \`.env\` file` : `Used \`.env\` file:\n${$usedEnvFilename}`;
|
|
32617
30809
|
if (metadata.length === 0) {
|
|
32618
|
-
return spaceTrim$
|
|
30810
|
+
return spaceTrim$1((block) => `
|
|
32619
30811
|
No LLM providers are available.
|
|
32620
30812
|
|
|
32621
30813
|
${block(usedEnvMessage)}
|
|
32622
30814
|
`);
|
|
32623
30815
|
}
|
|
32624
|
-
return spaceTrim$
|
|
30816
|
+
return spaceTrim$1((block) => `
|
|
32625
30817
|
|
|
32626
30818
|
${block(usedEnvMessage)}
|
|
32627
30819
|
|
|
@@ -32667,7 +30859,7 @@ function $registeredLlmToolsMessage() {
|
|
|
32667
30859
|
morePieces.push(`Not configured`); // <- Note: Can not be configured via environment variables
|
|
32668
30860
|
}
|
|
32669
30861
|
}
|
|
32670
|
-
let providerMessage = spaceTrim$
|
|
30862
|
+
let providerMessage = spaceTrim$1(`
|
|
32671
30863
|
${i + 1}) **${title}** \`${className}\` from \`${packageName}\`
|
|
32672
30864
|
${morePieces.join('; ')}
|
|
32673
30865
|
`);
|
|
@@ -32801,7 +30993,7 @@ class $EnvStorage {
|
|
|
32801
30993
|
.filter((line) => !line.startsWith(`# ${GENERATOR_WARNING_IN_ENV}`)) // Remove GENERATOR_WARNING_IN_ENV
|
|
32802
30994
|
.filter((line) => !line.startsWith(`${transformedKey}=`)) // Remove existing key if present
|
|
32803
30995
|
.join('\n');
|
|
32804
|
-
const newEnvContent = spaceTrim$
|
|
30996
|
+
const newEnvContent = spaceTrim$1((block) => `
|
|
32805
30997
|
${block(updatedEnvContent)}
|
|
32806
30998
|
|
|
32807
30999
|
# ${GENERATOR_WARNING_IN_ENV}
|
|
@@ -32830,7 +31022,7 @@ class $EnvStorage {
|
|
|
32830
31022
|
*/
|
|
32831
31023
|
function stringifyPipelineJson(pipeline) {
|
|
32832
31024
|
if (!isSerializableAsJson(pipeline)) {
|
|
32833
|
-
throw new UnexpectedError(spaceTrim$
|
|
31025
|
+
throw new UnexpectedError(spaceTrim$1(`
|
|
32834
31026
|
Cannot stringify the pipeline, because it is not serializable as JSON
|
|
32835
31027
|
|
|
32836
31028
|
There can be multiple reasons:
|
|
@@ -33013,7 +31205,7 @@ function cacheLlmTools(llmTools, options = {}) {
|
|
|
33013
31205
|
let normalizedContent = content;
|
|
33014
31206
|
normalizedContent = normalizedContent.replace(/\s+/g, ' ');
|
|
33015
31207
|
normalizedContent = normalizedContent.split('\r\n').join('\n');
|
|
33016
|
-
normalizedContent = spaceTrim$
|
|
31208
|
+
normalizedContent = spaceTrim$1(normalizedContent);
|
|
33017
31209
|
// Note: Do not need to save everything in the cache, just the relevant parameters
|
|
33018
31210
|
const relevantParameterNames = extractParameterNames(content);
|
|
33019
31211
|
const relevantParameters = Object.fromEntries(Object.entries(parameters).filter(([key]) => relevantParameterNames.has(key)));
|
|
@@ -33249,7 +31441,7 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
|
|
|
33249
31441
|
.find(({ packageName, className }) => llmConfiguration.packageName === packageName && llmConfiguration.className === className);
|
|
33250
31442
|
if (registeredItem === undefined) {
|
|
33251
31443
|
// console.log('$llmToolsRegister.list()', $llmToolsRegister.list());
|
|
33252
|
-
throw new Error(spaceTrim$
|
|
31444
|
+
throw new Error(spaceTrim$1((block) => `
|
|
33253
31445
|
There is no constructor for LLM provider \`${llmConfiguration.className}\` from \`${llmConfiguration.packageName}\`
|
|
33254
31446
|
Running in ${!$isRunningInBrowser() ? '' : 'browser environment'}${!$isRunningInNode() ? '' : 'node environment'}${!$isRunningInWebWorker() ? '' : 'worker environment'}
|
|
33255
31447
|
|
|
@@ -33317,14 +31509,14 @@ async function $provideLlmToolsFromEnv(options = {}) {
|
|
|
33317
31509
|
const configuration = await $provideLlmToolsConfigurationFromEnv();
|
|
33318
31510
|
if (configuration.length === 0) {
|
|
33319
31511
|
if ($llmToolsMetadataRegister.list().length === 0) {
|
|
33320
|
-
throw new UnexpectedError(spaceTrim$
|
|
31512
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
33321
31513
|
No LLM tools registered, this is probably a bug in the Promptbook library
|
|
33322
31514
|
|
|
33323
31515
|
${block($registeredLlmToolsMessage())}}
|
|
33324
31516
|
`));
|
|
33325
31517
|
}
|
|
33326
31518
|
// TODO: [🥃]
|
|
33327
|
-
throw new Error(spaceTrim$
|
|
31519
|
+
throw new Error(spaceTrim$1((block) => `
|
|
33328
31520
|
No LLM tools found in the environment
|
|
33329
31521
|
|
|
33330
31522
|
${block($registeredLlmToolsMessage())}}
|
|
@@ -33463,7 +31655,7 @@ async function $provideScrapersForNode(tools, options) {
|
|
|
33463
31655
|
function extractOneBlockFromMarkdown(markdown) {
|
|
33464
31656
|
const codeBlocks = extractAllBlocksFromMarkdown(markdown);
|
|
33465
31657
|
if (codeBlocks.length !== 1) {
|
|
33466
|
-
throw new ParseError(spaceTrim$
|
|
31658
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
33467
31659
|
There should be exactly 1 code block in task section, found ${codeBlocks.length} code blocks
|
|
33468
31660
|
|
|
33469
31661
|
${block(codeBlocks.map((block, i) => `Block ${i + 1}:\n${block.content}`).join('\n\n\n'))}
|
|
@@ -33572,7 +31764,7 @@ class JavascriptEvalExecutionTools {
|
|
|
33572
31764
|
}
|
|
33573
31765
|
// Note: [💎]
|
|
33574
31766
|
// Note: Using direct eval, following variables are in same scope as eval call so they are accessible from inside the evaluated script:
|
|
33575
|
-
const spaceTrim = (_) =>
|
|
31767
|
+
const spaceTrim = (_) => _spaceTrim(_);
|
|
33576
31768
|
$preserve(spaceTrim);
|
|
33577
31769
|
const removeQuotes$1 = removeQuotes;
|
|
33578
31770
|
$preserve(removeQuotes$1);
|
|
@@ -33663,7 +31855,7 @@ class JavascriptEvalExecutionTools {
|
|
|
33663
31855
|
.join('\n');
|
|
33664
31856
|
// script = templateParameters(script, parameters);
|
|
33665
31857
|
// <- TODO: [🧠][🥳] Should be this is one of two variants how to use parameters in script
|
|
33666
|
-
const statementToEvaluate =
|
|
31858
|
+
const statementToEvaluate = _spaceTrim((block) => `
|
|
33667
31859
|
|
|
33668
31860
|
// Build-in functions:
|
|
33669
31861
|
${block(buildinFunctionsStatement)}
|
|
@@ -33678,7 +31870,7 @@ class JavascriptEvalExecutionTools {
|
|
|
33678
31870
|
(async ()=>{ ${script} })()
|
|
33679
31871
|
`);
|
|
33680
31872
|
if (this.options.isVerbose) {
|
|
33681
|
-
console.info(
|
|
31873
|
+
console.info(_spaceTrim((block) => `
|
|
33682
31874
|
🚀 Evaluating ${scriptLanguage} script:
|
|
33683
31875
|
|
|
33684
31876
|
${block(statementToEvaluate)}`));
|
|
@@ -33687,7 +31879,7 @@ class JavascriptEvalExecutionTools {
|
|
|
33687
31879
|
try {
|
|
33688
31880
|
result = await eval(statementToEvaluate);
|
|
33689
31881
|
if (this.options.isVerbose) {
|
|
33690
|
-
console.info(
|
|
31882
|
+
console.info(_spaceTrim((block) => `
|
|
33691
31883
|
🚀 Script evaluated successfully, result:
|
|
33692
31884
|
${block(valueToString(result))}
|
|
33693
31885
|
`));
|
|
@@ -33706,7 +31898,7 @@ class JavascriptEvalExecutionTools {
|
|
|
33706
31898
|
To: [PipelineExecutionError: Parameter `{thing}` is not defined],
|
|
33707
31899
|
*/
|
|
33708
31900
|
if (!statementToEvaluate.includes(undefinedName + '(')) {
|
|
33709
|
-
throw new PipelineExecutionError(
|
|
31901
|
+
throw new PipelineExecutionError(_spaceTrim((block) => `
|
|
33710
31902
|
|
|
33711
31903
|
Parameter \`{${undefinedName}}\` is not defined
|
|
33712
31904
|
|
|
@@ -33728,7 +31920,7 @@ class JavascriptEvalExecutionTools {
|
|
|
33728
31920
|
`));
|
|
33729
31921
|
}
|
|
33730
31922
|
else {
|
|
33731
|
-
throw new PipelineExecutionError(
|
|
31923
|
+
throw new PipelineExecutionError(_spaceTrim((block) => `
|
|
33732
31924
|
Function ${undefinedName}() is not defined
|
|
33733
31925
|
|
|
33734
31926
|
- Make sure that the function is one of built-in functions
|
|
@@ -33867,7 +32059,7 @@ const knowledgeCommandParser = {
|
|
|
33867
32059
|
*/
|
|
33868
32060
|
parse(input) {
|
|
33869
32061
|
const { args } = input;
|
|
33870
|
-
const knowledgeSourceContent = spaceTrim$
|
|
32062
|
+
const knowledgeSourceContent = spaceTrim$1(args[0] || '');
|
|
33871
32063
|
if (knowledgeSourceContent === '') {
|
|
33872
32064
|
throw new ParseError(`Source is not defined`);
|
|
33873
32065
|
}
|
|
@@ -34011,7 +32203,7 @@ const sectionCommandParser = {
|
|
|
34011
32203
|
normalized = normalized.split('DIALOGUE').join('DIALOG');
|
|
34012
32204
|
const taskTypes = SectionTypes.filter((sectionType) => normalized.includes(sectionType.split('_TASK').join('')));
|
|
34013
32205
|
if (taskTypes.length !== 1) {
|
|
34014
|
-
throw new ParseError(spaceTrim$
|
|
32206
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
34015
32207
|
Unknown section type "${normalized}"
|
|
34016
32208
|
|
|
34017
32209
|
Supported section types are:
|
|
@@ -34031,7 +32223,7 @@ const sectionCommandParser = {
|
|
|
34031
32223
|
*/
|
|
34032
32224
|
$applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
34033
32225
|
if ($taskJson.isSectionTypeSet === true) {
|
|
34034
|
-
throw new ParseError(spaceTrim$
|
|
32226
|
+
throw new ParseError(spaceTrim$1(`
|
|
34035
32227
|
Section type is already defined in the section.
|
|
34036
32228
|
It can be defined only once.
|
|
34037
32229
|
`));
|
|
@@ -34311,7 +32503,7 @@ const expectCommandParser = {
|
|
|
34311
32503
|
/**
|
|
34312
32504
|
* Description of the FORMAT command
|
|
34313
32505
|
*/
|
|
34314
|
-
description: spaceTrim$
|
|
32506
|
+
description: spaceTrim$1(`
|
|
34315
32507
|
Expect command describes the desired output of the task *(after post-processing)*
|
|
34316
32508
|
It can set limits for the maximum/minimum length of the output, measured in characters, words, sentences, paragraphs or some other shape of the output.
|
|
34317
32509
|
`),
|
|
@@ -34385,7 +32577,7 @@ const expectCommandParser = {
|
|
|
34385
32577
|
}
|
|
34386
32578
|
catch (error) {
|
|
34387
32579
|
assertsError(error);
|
|
34388
|
-
throw new ParseError(spaceTrim$
|
|
32580
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
34389
32581
|
Invalid FORMAT command
|
|
34390
32582
|
${block(error.message)}:
|
|
34391
32583
|
`));
|
|
@@ -34497,7 +32689,7 @@ function validateParameterName(parameterName) {
|
|
|
34497
32689
|
if (!(error instanceof ParseError)) {
|
|
34498
32690
|
throw error;
|
|
34499
32691
|
}
|
|
34500
|
-
throw new ParseError(spaceTrim$
|
|
32692
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
34501
32693
|
${block(error.message)}
|
|
34502
32694
|
|
|
34503
32695
|
Tried to validate parameter name:
|
|
@@ -34556,7 +32748,7 @@ const foreachCommandParser = {
|
|
|
34556
32748
|
const assignSign = args[3];
|
|
34557
32749
|
const formatDefinition = FORMAT_DEFINITIONS.find((formatDefinition) => [formatDefinition.formatName, ...(formatDefinition.aliases || [])].includes(formatName));
|
|
34558
32750
|
if (formatDefinition === undefined) {
|
|
34559
|
-
throw new ParseError(spaceTrim$
|
|
32751
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
34560
32752
|
Unsupported format "${formatName}"
|
|
34561
32753
|
|
|
34562
32754
|
Available formats:
|
|
@@ -34568,7 +32760,7 @@ const foreachCommandParser = {
|
|
|
34568
32760
|
}
|
|
34569
32761
|
const subvalueParser = formatDefinition.subvalueParsers.find((subvalueParser) => [subvalueParser.subvalueName, ...(subvalueParser.aliases || [])].includes(subformatName));
|
|
34570
32762
|
if (subvalueParser === undefined) {
|
|
34571
|
-
throw new ParseError(spaceTrim$
|
|
32763
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
34572
32764
|
Unsupported subformat name "${subformatName}" for format "${formatName}"
|
|
34573
32765
|
|
|
34574
32766
|
Available subformat names for format "${formatDefinition.formatName}":
|
|
@@ -34616,7 +32808,7 @@ const foreachCommandParser = {
|
|
|
34616
32808
|
outputSubparameterName = 'newLine';
|
|
34617
32809
|
}
|
|
34618
32810
|
else {
|
|
34619
|
-
throw new ParseError(spaceTrim$
|
|
32811
|
+
throw new ParseError(spaceTrim$1(`
|
|
34620
32812
|
FOREACH ${formatName} ${subformatName} must specify output subparameter
|
|
34621
32813
|
|
|
34622
32814
|
Correct example:
|
|
@@ -34692,7 +32884,7 @@ const formatCommandParser = {
|
|
|
34692
32884
|
/**
|
|
34693
32885
|
* Description of the FORMAT command
|
|
34694
32886
|
*/
|
|
34695
|
-
description: spaceTrim$
|
|
32887
|
+
description: spaceTrim$1(`
|
|
34696
32888
|
Format command describes the desired output of the task (after post-processing)
|
|
34697
32889
|
It can set limits for the maximum/minimum length of the output, measured in characters, words, sentences, paragraphs or some other shape of the output.
|
|
34698
32890
|
`),
|
|
@@ -35064,7 +33256,7 @@ const formfactorCommandParser = {
|
|
|
35064
33256
|
const formfactorNameCandidate = args[0].toUpperCase();
|
|
35065
33257
|
const formfactor = FORMFACTOR_DEFINITIONS.find((definition) => [definition.name, ...{ aliasNames: [], ...definition }.aliasNames].includes(formfactorNameCandidate));
|
|
35066
33258
|
if (formfactor === undefined) {
|
|
35067
|
-
throw new ParseError(spaceTrim$
|
|
33259
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
35068
33260
|
Unknown formfactor name "${formfactorNameCandidate}"
|
|
35069
33261
|
|
|
35070
33262
|
Available formfactors:
|
|
@@ -35083,7 +33275,7 @@ const formfactorCommandParser = {
|
|
|
35083
33275
|
*/
|
|
35084
33276
|
$applyToPipelineJson(command, $pipelineJson) {
|
|
35085
33277
|
if ($pipelineJson.formfactorName !== undefined && $pipelineJson.formfactorName !== command.formfactorName) {
|
|
35086
|
-
throw new ParseError(spaceTrim$
|
|
33278
|
+
throw new ParseError(spaceTrim$1(`
|
|
35087
33279
|
Redefinition of \`FORMFACTOR\` in the pipeline head
|
|
35088
33280
|
|
|
35089
33281
|
You have used:
|
|
@@ -35231,7 +33423,7 @@ const modelCommandParser = {
|
|
|
35231
33423
|
*/
|
|
35232
33424
|
parse(input) {
|
|
35233
33425
|
const { args, normalized } = input;
|
|
35234
|
-
const availableVariantsMessage = spaceTrim$
|
|
33426
|
+
const availableVariantsMessage = spaceTrim$1((block) => `
|
|
35235
33427
|
Available variants are:
|
|
35236
33428
|
${block(MODEL_VARIANTS.map((variantName) => `- ${variantName}${variantName !== 'EMBEDDING' ? '' : ' (Not available in pipeline)'}`).join('\n'))}
|
|
35237
33429
|
`);
|
|
@@ -35253,14 +33445,14 @@ const modelCommandParser = {
|
|
|
35253
33445
|
// <- Note: [🤖]
|
|
35254
33446
|
}
|
|
35255
33447
|
else if (normalized.startsWith('MODEL_VARIANT_EMBED')) {
|
|
35256
|
-
spaceTrim$
|
|
33448
|
+
spaceTrim$1((block) => `
|
|
35257
33449
|
Embedding model can not be used in pipeline
|
|
35258
33450
|
|
|
35259
33451
|
${block(availableVariantsMessage)}
|
|
35260
33452
|
`);
|
|
35261
33453
|
}
|
|
35262
33454
|
else {
|
|
35263
|
-
throw new ParseError(spaceTrim$
|
|
33455
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
35264
33456
|
Unknown model variant in command:
|
|
35265
33457
|
|
|
35266
33458
|
${block(availableVariantsMessage)}
|
|
@@ -35275,7 +33467,7 @@ const modelCommandParser = {
|
|
|
35275
33467
|
};
|
|
35276
33468
|
}
|
|
35277
33469
|
else {
|
|
35278
|
-
throw new ParseError(spaceTrim$
|
|
33470
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
35279
33471
|
Unknown model key in command.
|
|
35280
33472
|
|
|
35281
33473
|
Supported model keys are:
|
|
@@ -35302,7 +33494,7 @@ const modelCommandParser = {
|
|
|
35302
33494
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
35303
33495
|
}
|
|
35304
33496
|
else {
|
|
35305
|
-
throw new ParseError(spaceTrim$
|
|
33497
|
+
throw new ParseError(spaceTrim$1(`
|
|
35306
33498
|
Redefinition of \`MODEL ${command.key}\` in the pipeline head
|
|
35307
33499
|
|
|
35308
33500
|
You have used:
|
|
@@ -35330,7 +33522,7 @@ const modelCommandParser = {
|
|
|
35330
33522
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
35331
33523
|
}
|
|
35332
33524
|
else {
|
|
35333
|
-
throw new ParseError(spaceTrim$
|
|
33525
|
+
throw new ParseError(spaceTrim$1(`
|
|
35334
33526
|
Redefinition of MODEL \`${command.key}\` in the task "${$taskJson.title || $taskJson.name}"
|
|
35335
33527
|
|
|
35336
33528
|
You have used:
|
|
@@ -35340,7 +33532,7 @@ const modelCommandParser = {
|
|
|
35340
33532
|
}
|
|
35341
33533
|
}
|
|
35342
33534
|
if (command.value === ($pipelineJson.defaultModelRequirements || {})[command.key]) {
|
|
35343
|
-
console.log(spaceTrim$
|
|
33535
|
+
console.log(spaceTrim$1(`
|
|
35344
33536
|
Setting MODEL \`${command.key}\` in the task "${$taskJson.title || $taskJson.name}" to the same value as in the pipeline head
|
|
35345
33537
|
|
|
35346
33538
|
In pipeline head:
|
|
@@ -35423,7 +33615,7 @@ const parameterCommandParser = {
|
|
|
35423
33615
|
// <- TODO: When [🥶] fixed, change to:
|
|
35424
33616
|
// > const parameterDescriptionRaw = rawArgs.split(parameterNameRaw).join('').trim();
|
|
35425
33617
|
if (parameterDescriptionRaw && parameterDescriptionRaw.match(/\{(?<embeddedParameterName>[a-z0-9_]+)\}/im)) {
|
|
35426
|
-
throw new ParseError(spaceTrim$
|
|
33618
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
35427
33619
|
Parameter \`{${parameterNameRaw}}\` can not contain another parameter in description
|
|
35428
33620
|
|
|
35429
33621
|
The description:
|
|
@@ -35605,7 +33797,7 @@ function $applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
|
35605
33797
|
persona.description = personaDescription;
|
|
35606
33798
|
return;
|
|
35607
33799
|
}
|
|
35608
|
-
console.warn(spaceTrim$
|
|
33800
|
+
console.warn(spaceTrim$1(`
|
|
35609
33801
|
|
|
35610
33802
|
Persona "${personaName}" is defined multiple times with different description:
|
|
35611
33803
|
|
|
@@ -35616,7 +33808,7 @@ function $applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
|
35616
33808
|
${personaDescription}
|
|
35617
33809
|
|
|
35618
33810
|
`));
|
|
35619
|
-
persona.description += spaceTrim$
|
|
33811
|
+
persona.description += spaceTrim$1('\n\n' + personaDescription);
|
|
35620
33812
|
}
|
|
35621
33813
|
|
|
35622
33814
|
/**
|
|
@@ -36457,7 +34649,7 @@ function removeMarkdownComments(content) {
|
|
|
36457
34649
|
*/
|
|
36458
34650
|
function isFlatPipeline(pipelineString) {
|
|
36459
34651
|
pipelineString = removeMarkdownComments(pipelineString);
|
|
36460
|
-
pipelineString = spaceTrim$
|
|
34652
|
+
pipelineString = spaceTrim$1(pipelineString);
|
|
36461
34653
|
const isMarkdownBeginningWithHeadline = pipelineString.startsWith('# ');
|
|
36462
34654
|
//const isLastLineReturnStatement = pipelineString.split(/\r?\n/).pop()!.split('`').join('').startsWith('->');
|
|
36463
34655
|
const isBacktickBlockUsed = pipelineString.includes('```');
|
|
@@ -36483,7 +34675,7 @@ function deflatePipeline(pipelineString) {
|
|
|
36483
34675
|
if (!isFlatPipeline(pipelineString)) {
|
|
36484
34676
|
return pipelineString;
|
|
36485
34677
|
}
|
|
36486
|
-
pipelineString = spaceTrim$
|
|
34678
|
+
pipelineString = spaceTrim$1(pipelineString);
|
|
36487
34679
|
const pipelineStringLines = pipelineString.split(/\r?\n/);
|
|
36488
34680
|
const potentialReturnStatement = pipelineStringLines.pop();
|
|
36489
34681
|
let returnStatement;
|
|
@@ -36496,19 +34688,19 @@ function deflatePipeline(pipelineString) {
|
|
|
36496
34688
|
returnStatement = `-> {${DEFAULT_BOOK_OUTPUT_PARAMETER_NAME}}`;
|
|
36497
34689
|
pipelineStringLines.push(potentialReturnStatement);
|
|
36498
34690
|
}
|
|
36499
|
-
const prompt = spaceTrim$
|
|
34691
|
+
const prompt = spaceTrim$1(pipelineStringLines.join('\n'));
|
|
36500
34692
|
let quotedPrompt;
|
|
36501
34693
|
if (prompt.split(/\r?\n/).length <= 1) {
|
|
36502
34694
|
quotedPrompt = `> ${prompt}`;
|
|
36503
34695
|
}
|
|
36504
34696
|
else {
|
|
36505
|
-
quotedPrompt = spaceTrim$
|
|
34697
|
+
quotedPrompt = spaceTrim$1((block) => `
|
|
36506
34698
|
\`\`\`
|
|
36507
34699
|
${block(prompt.split('`').join('\\`'))}
|
|
36508
34700
|
\`\`\`
|
|
36509
34701
|
`);
|
|
36510
34702
|
}
|
|
36511
|
-
pipelineString = validatePipelineString(spaceTrim$
|
|
34703
|
+
pipelineString = validatePipelineString(spaceTrim$1((block) => `
|
|
36512
34704
|
# ${DEFAULT_BOOK_TITLE}
|
|
36513
34705
|
|
|
36514
34706
|
## Prompt
|
|
@@ -36566,7 +34758,7 @@ function parseMarkdownSection(value) {
|
|
|
36566
34758
|
}
|
|
36567
34759
|
const title = lines[0].replace(/^#+\s*/, '');
|
|
36568
34760
|
const level = (_b = (_a = lines[0].match(/^#+/)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
|
|
36569
|
-
const content = spaceTrim$
|
|
34761
|
+
const content = spaceTrim$1(lines.slice(1).join('\n'));
|
|
36570
34762
|
if (level < 1 || level > 6) {
|
|
36571
34763
|
throw new ParseError('Markdown section must have heading level between 1 and 6');
|
|
36572
34764
|
}
|
|
@@ -36594,7 +34786,7 @@ function splitMarkdownIntoSections(markdown) {
|
|
|
36594
34786
|
if (buffer.length === 0) {
|
|
36595
34787
|
return;
|
|
36596
34788
|
}
|
|
36597
|
-
let section = spaceTrim$
|
|
34789
|
+
let section = spaceTrim$1(buffer.join('\n'));
|
|
36598
34790
|
if (section === '') {
|
|
36599
34791
|
return;
|
|
36600
34792
|
}
|
|
@@ -36669,7 +34861,7 @@ function flattenMarkdown(markdown) {
|
|
|
36669
34861
|
flattenedMarkdown += `## ${title}` + `\n\n`;
|
|
36670
34862
|
flattenedMarkdown += content + `\n\n`; // <- [🧠] Maybe 3 new lines?
|
|
36671
34863
|
}
|
|
36672
|
-
return spaceTrim$
|
|
34864
|
+
return spaceTrim$1(flattenedMarkdown);
|
|
36673
34865
|
}
|
|
36674
34866
|
/**
|
|
36675
34867
|
* TODO: [🏛] This can be part of markdown builder
|
|
@@ -37376,7 +35568,7 @@ async function createPipelineCollectionFromDirectory(rootPath, tools, options) {
|
|
|
37376
35568
|
catch (error) {
|
|
37377
35569
|
assertsError(error);
|
|
37378
35570
|
// TODO: [7] DRY
|
|
37379
|
-
const wrappedErrorMessage = spaceTrim$
|
|
35571
|
+
const wrappedErrorMessage = spaceTrim$1((block) => `
|
|
37380
35572
|
${error.name} in pipeline ${fileName.split('\\').join('/')}:
|
|
37381
35573
|
|
|
37382
35574
|
Original error message:
|
|
@@ -37411,7 +35603,7 @@ async function createPipelineCollectionFromDirectory(rootPath, tools, options) {
|
|
|
37411
35603
|
pipeline = { ...pipeline, pipelineUrl };
|
|
37412
35604
|
}
|
|
37413
35605
|
else if (!pipeline.pipelineUrl.startsWith(rootUrl)) {
|
|
37414
|
-
throw new PipelineUrlError(spaceTrim$
|
|
35606
|
+
throw new PipelineUrlError(spaceTrim$1(`
|
|
37415
35607
|
Pipeline with URL ${pipeline.pipelineUrl} is not a child of the root URL ${rootUrl} 🍏
|
|
37416
35608
|
|
|
37417
35609
|
File:
|
|
@@ -37449,7 +35641,7 @@ async function createPipelineCollectionFromDirectory(rootPath, tools, options) {
|
|
|
37449
35641
|
}
|
|
37450
35642
|
else {
|
|
37451
35643
|
const existing = collection.get(pipeline.pipelineUrl);
|
|
37452
|
-
throw new PipelineUrlError(spaceTrim$
|
|
35644
|
+
throw new PipelineUrlError(spaceTrim$1(`
|
|
37453
35645
|
Pipeline with URL ${pipeline.pipelineUrl} is already in the collection 🍏
|
|
37454
35646
|
|
|
37455
35647
|
Conflicting files:
|
|
@@ -37467,7 +35659,7 @@ async function createPipelineCollectionFromDirectory(rootPath, tools, options) {
|
|
|
37467
35659
|
catch (error) {
|
|
37468
35660
|
assertsError(error);
|
|
37469
35661
|
// TODO: [7] DRY
|
|
37470
|
-
const wrappedErrorMessage = spaceTrim$
|
|
35662
|
+
const wrappedErrorMessage = spaceTrim$1((block) => `
|
|
37471
35663
|
${error.name} in pipeline ${fileName.split('\\').join('/')}:
|
|
37472
35664
|
|
|
37473
35665
|
Original error message:
|
|
@@ -37643,7 +35835,7 @@ async function $getCompiledBook(tools, pipelineSource, options) {
|
|
|
37643
35835
|
// console.log(`Strategy 3️⃣`);
|
|
37644
35836
|
const response = await fetch(pipelineSource);
|
|
37645
35837
|
if (response.status >= 300) {
|
|
37646
|
-
throw new NotFoundError(spaceTrim$
|
|
35838
|
+
throw new NotFoundError(spaceTrim$1((block) => `
|
|
37647
35839
|
Book not found on URL:
|
|
37648
35840
|
${block(pipelineSource)}
|
|
37649
35841
|
|
|
@@ -37653,7 +35845,7 @@ async function $getCompiledBook(tools, pipelineSource, options) {
|
|
|
37653
35845
|
const pipelineString = await response.text();
|
|
37654
35846
|
// console.log({ pipelineString });
|
|
37655
35847
|
if (!isValidPipelineString(pipelineString)) {
|
|
37656
|
-
throw new NotFoundError(spaceTrim$
|
|
35848
|
+
throw new NotFoundError(spaceTrim$1((block) => `
|
|
37657
35849
|
Book not found on URL:
|
|
37658
35850
|
${block(pipelineSource)}
|
|
37659
35851
|
|
|
@@ -37675,7 +35867,7 @@ async function $getCompiledBook(tools, pipelineSource, options) {
|
|
|
37675
35867
|
});
|
|
37676
35868
|
return pipelineJson;
|
|
37677
35869
|
} /* not else */
|
|
37678
|
-
throw new NotFoundError(spaceTrim$
|
|
35870
|
+
throw new NotFoundError(spaceTrim$1((block) => `
|
|
37679
35871
|
Book not found:
|
|
37680
35872
|
${block(pipelineSource)}
|
|
37681
35873
|
|
|
@@ -37857,7 +36049,7 @@ function validateBook(source) {
|
|
|
37857
36049
|
* @deprecated Use `$generateBookBoilerplate` instead
|
|
37858
36050
|
* @public exported from `@promptbook/core`
|
|
37859
36051
|
*/
|
|
37860
|
-
padBook(validateBook(spaceTrim$
|
|
36052
|
+
padBook(validateBook(spaceTrim$1(`
|
|
37861
36053
|
AI Avatar
|
|
37862
36054
|
|
|
37863
36055
|
PERSONA A friendly AI assistant that helps you with your tasks
|
|
@@ -37884,7 +36076,7 @@ function book(strings, ...values) {
|
|
|
37884
36076
|
const bookString = prompt(strings, ...values).toString();
|
|
37885
36077
|
if (!isValidPipelineString(bookString)) {
|
|
37886
36078
|
// TODO: Make the CustomError for this
|
|
37887
|
-
throw new Error(spaceTrim$
|
|
36079
|
+
throw new Error(spaceTrim$1(`
|
|
37888
36080
|
The string is not a valid pipeline string
|
|
37889
36081
|
|
|
37890
36082
|
book\`
|
|
@@ -37894,7 +36086,7 @@ function book(strings, ...values) {
|
|
|
37894
36086
|
}
|
|
37895
36087
|
if (!isValidBook(bookString)) {
|
|
37896
36088
|
// TODO: Make the CustomError for this
|
|
37897
|
-
throw new Error(spaceTrim$
|
|
36089
|
+
throw new Error(spaceTrim$1(`
|
|
37898
36090
|
The string is not a valid book
|
|
37899
36091
|
|
|
37900
36092
|
book\`
|
|
@@ -38820,7 +37012,7 @@ function promptbookifyAiText(text) {
|
|
|
38820
37012
|
* TODO: [🧠][✌️] Make some Promptbook-native token system
|
|
38821
37013
|
*/
|
|
38822
37014
|
|
|
38823
|
-
const DEFAULT_AGENT_KIT_MODEL_NAME = 'gpt-5-
|
|
37015
|
+
const DEFAULT_AGENT_KIT_MODEL_NAME = 'gpt-5.4-nano';
|
|
38824
37016
|
/**
|
|
38825
37017
|
* Creates one structured log entry for streamed tool-call updates.
|
|
38826
37018
|
*
|
|
@@ -39315,7 +37507,7 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
|
|
|
39315
37507
|
}),
|
|
39316
37508
|
],
|
|
39317
37509
|
};
|
|
39318
|
-
const errorMessage = spaceTrim$
|
|
37510
|
+
const errorMessage = spaceTrim$1((block) => `
|
|
39319
37511
|
|
|
39320
37512
|
The invoked tool \`${functionName}\` failed with error:
|
|
39321
37513
|
|
|
@@ -40265,7 +38457,7 @@ class SelfLearningManager {
|
|
|
40265
38457
|
if (isJsonSchemaResponseFormat(responseFormat)) {
|
|
40266
38458
|
const jsonSchema = responseFormat.json_schema;
|
|
40267
38459
|
const schemaJson = JSON.stringify(jsonSchema, null, 4);
|
|
40268
|
-
userMessageContent = spaceTrim$
|
|
38460
|
+
userMessageContent = spaceTrim$1((block) => `
|
|
40269
38461
|
${block(prompt.content)}
|
|
40270
38462
|
|
|
40271
38463
|
NOTE Request was made through OpenAI Compatible API with \`response_format\` of type \`json_schema\` with the following schema:
|
|
@@ -40296,12 +38488,12 @@ class SelfLearningManager {
|
|
|
40296
38488
|
const formattedAgentMessage = formatAgentMessageForJsonMode(result.content, usesJsonSchemaMode);
|
|
40297
38489
|
const teacherInstructions = extractOpenTeacherInstructions(agentSource);
|
|
40298
38490
|
const teacherInstructionsSection = teacherInstructions
|
|
40299
|
-
? spaceTrim$
|
|
38491
|
+
? spaceTrim$1((block) => `
|
|
40300
38492
|
**Teacher instructions:**
|
|
40301
38493
|
${block(teacherInstructions)}
|
|
40302
38494
|
`)
|
|
40303
38495
|
: '';
|
|
40304
|
-
const teacherPromptContent = spaceTrim$
|
|
38496
|
+
const teacherPromptContent = spaceTrim$1((block) => `
|
|
40305
38497
|
|
|
40306
38498
|
You are a teacher agent helping another agent to learn from its interactions.
|
|
40307
38499
|
|
|
@@ -40334,7 +38526,7 @@ class SelfLearningManager {
|
|
|
40334
38526
|
? '- This interaction used JSON mode, so the agent answer should stay as a formatted JSON code block.'
|
|
40335
38527
|
: ''}
|
|
40336
38528
|
${block(isInitialMessageMissing
|
|
40337
|
-
? spaceTrim$
|
|
38529
|
+
? spaceTrim$1(`
|
|
40338
38530
|
- The agent source does not have an INITIAL MESSAGE defined, generate one.
|
|
40339
38531
|
- The INITIAL MESSAGE should be welcoming, informative about the agent capabilities and also should give some quick options to start the conversation with the agent.
|
|
40340
38532
|
- The quick option looks like \`[👋 Hello](?message=Hello, how are you?)\`
|
|
@@ -40377,7 +38569,7 @@ class SelfLearningManager {
|
|
|
40377
38569
|
*/
|
|
40378
38570
|
appendToAgentSource(section) {
|
|
40379
38571
|
const currentSource = this.options.getAgentSource();
|
|
40380
|
-
const newSource = padBook(validateBook(spaceTrim$
|
|
38572
|
+
const newSource = padBook(validateBook(spaceTrim$1(currentSource) + section));
|
|
40381
38573
|
this.options.updateAgentSource(newSource);
|
|
40382
38574
|
}
|
|
40383
38575
|
}
|
|
@@ -40405,13 +38597,13 @@ function formatAgentMessageForJsonMode(content, isJsonMode) {
|
|
|
40405
38597
|
}
|
|
40406
38598
|
const parsedJson = tryParseJson(content);
|
|
40407
38599
|
if (parsedJson === null) {
|
|
40408
|
-
return spaceTrim$
|
|
38600
|
+
return spaceTrim$1((block) => `
|
|
40409
38601
|
\`\`\`json
|
|
40410
38602
|
${block(content)}
|
|
40411
38603
|
\`\`\`
|
|
40412
38604
|
`);
|
|
40413
38605
|
}
|
|
40414
|
-
return spaceTrim$
|
|
38606
|
+
return spaceTrim$1((block) => `
|
|
40415
38607
|
\`\`\`json
|
|
40416
38608
|
${block(JSON.stringify(parsedJson, null, 4))}
|
|
40417
38609
|
\`\`\`
|
|
@@ -40443,7 +38635,7 @@ function formatSelfLearningSample(options) {
|
|
|
40443
38635
|
const internalMessagesSection = options.internalMessages
|
|
40444
38636
|
.map((internalMessage) => formatInternalLearningMessage(internalMessage))
|
|
40445
38637
|
.join('\n\n');
|
|
40446
|
-
return spaceTrim$
|
|
38638
|
+
return spaceTrim$1((block) => `
|
|
40447
38639
|
|
|
40448
38640
|
USER MESSAGE
|
|
40449
38641
|
${block(options.userMessageContent)}
|
|
@@ -40461,7 +38653,7 @@ function formatSelfLearningSample(options) {
|
|
|
40461
38653
|
* @private function of Agent
|
|
40462
38654
|
*/
|
|
40463
38655
|
function formatInternalLearningMessage(internalMessage) {
|
|
40464
|
-
return spaceTrim$
|
|
38656
|
+
return spaceTrim$1((block) => `
|
|
40465
38657
|
INTERNAL MESSAGE
|
|
40466
38658
|
${block(stringifyInternalLearningPayload(internalMessage))}
|
|
40467
38659
|
`);
|
|
@@ -40927,7 +39119,7 @@ function buildRemoteAgentSource(profile, meta) {
|
|
|
40927
39119
|
.filter((line) => Boolean(line))
|
|
40928
39120
|
.join('\n');
|
|
40929
39121
|
const personaBlock = profile.personaDescription
|
|
40930
|
-
? spaceTrim$
|
|
39122
|
+
? spaceTrim$1((block) => `
|
|
40931
39123
|
PERSONA
|
|
40932
39124
|
${block(profile.personaDescription || '')}
|
|
40933
39125
|
`)
|
|
@@ -40963,7 +39155,7 @@ class RemoteAgent extends Agent {
|
|
|
40963
39155
|
// <- TODO: [🐱🚀] What about closed-source agents?
|
|
40964
39156
|
// <- TODO: [🐱🚀] Maybe use promptbookFetch
|
|
40965
39157
|
if (!profileResponse.ok) {
|
|
40966
|
-
throw new Error(spaceTrim$
|
|
39158
|
+
throw new Error(spaceTrim$1((block) => `
|
|
40967
39159
|
Failed to fetch remote agent profile:
|
|
40968
39160
|
|
|
40969
39161
|
Agent URL:
|