@promptbook/cli 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 +557 -2337
- package/esm/index.es.js.map +1 -1
- package/{umd/src/cli/cli-commands/coder/find-fresh-emoji-tag.d.ts → esm/src/cli/cli-commands/coder/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 +1 -2
- package/umd/index.umd.js +771 -2548
- package/umd/index.umd.js.map +1 -1
- package/{esm/src/cli/cli-commands/coder/find-fresh-emoji-tag.d.ts → umd/src/cli/cli-commands/coder/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/scripts/{find-fresh-emoji-tag/find-fresh-emoji-tag.d.ts → find-fresh-emoji-tags/find-fresh-emoji-tags.d.ts} +0 -0
- /package/esm/scripts/{find-fresh-emoji-tag → find-fresh-emoji-tags}/utils/$shuffleItems.d.ts +0 -0
- /package/esm/scripts/{find-fresh-emoji-tag → find-fresh-emoji-tags}/utils/emojis.d.ts +0 -0
- /package/umd/scripts/{find-fresh-emoji-tag/find-fresh-emoji-tag.d.ts → find-fresh-emoji-tags/find-fresh-emoji-tags.d.ts} +0 -0
- /package/umd/scripts/{find-fresh-emoji-tag → find-fresh-emoji-tags}/utils/$shuffleItems.d.ts +0 -0
- /package/umd/scripts/{find-fresh-emoji-tag → find-fresh-emoji-tags}/utils/emojis.d.ts +0 -0
package/esm/index.es.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import colors from 'colors';
|
|
2
2
|
import commander from 'commander';
|
|
3
|
-
import
|
|
3
|
+
import _spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import { writeFileSync, readFileSync, existsSync } from 'fs';
|
|
6
6
|
import * as path from 'path';
|
|
@@ -14,13 +14,10 @@ import sha256 from 'crypto-js/sha256';
|
|
|
14
14
|
import { io } from 'socket.io-client';
|
|
15
15
|
import { SHA256 } from 'crypto-js';
|
|
16
16
|
import JSZip from 'jszip';
|
|
17
|
-
import { randomBytes,
|
|
17
|
+
import { randomBytes, createHash } from 'crypto';
|
|
18
18
|
import { Readability } from '@mozilla/readability';
|
|
19
19
|
import { JSDOM } from 'jsdom';
|
|
20
20
|
import { Converter } from 'showdown';
|
|
21
|
-
import { tmpdir } from 'os';
|
|
22
|
-
import { ConfigChecker } from 'configchecker';
|
|
23
|
-
import { chromium } from 'playwright';
|
|
24
21
|
import glob from 'glob-promise';
|
|
25
22
|
import moment from 'moment';
|
|
26
23
|
import express from 'express';
|
|
@@ -60,7 +57,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
60
57
|
* @generated
|
|
61
58
|
* @see https://github.com/webgptorg/promptbook
|
|
62
59
|
*/
|
|
63
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
60
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-15';
|
|
64
61
|
/**
|
|
65
62
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
66
63
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -1428,7 +1425,7 @@ function $isRunningInWebWorker() {
|
|
|
1428
1425
|
function getErrorReportUrl(error) {
|
|
1429
1426
|
const report = {
|
|
1430
1427
|
title: `🐜 Error report from ${NAME}`,
|
|
1431
|
-
body: spaceTrim$
|
|
1428
|
+
body: spaceTrim$1((block) => `
|
|
1432
1429
|
|
|
1433
1430
|
|
|
1434
1431
|
\`${error.name || 'Error'}\` has occurred in the [${NAME}], please look into it @${ADMIN_GITHUB_NAME}.
|
|
@@ -1567,7 +1564,7 @@ function handleActionErrors(action) {
|
|
|
1567
1564
|
*/
|
|
1568
1565
|
function $initializeAboutCommand(program) {
|
|
1569
1566
|
const makeCommand = program.command('about');
|
|
1570
|
-
makeCommand.description(spaceTrim$
|
|
1567
|
+
makeCommand.description(spaceTrim$1(`
|
|
1571
1568
|
Tells about Promptbook CLI and its abilities
|
|
1572
1569
|
`));
|
|
1573
1570
|
makeCommand.action(handleActionErrors(async () => {
|
|
@@ -1607,15 +1604,15 @@ function $initializeAboutCommand(program) {
|
|
|
1607
1604
|
*/
|
|
1608
1605
|
|
|
1609
1606
|
/**
|
|
1610
|
-
* Initializes `coder find-fresh-emoji-
|
|
1607
|
+
* Initializes `coder find-fresh-emoji-tags` command for Promptbook CLI utilities
|
|
1611
1608
|
*
|
|
1612
1609
|
* Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI
|
|
1613
1610
|
*
|
|
1614
1611
|
* @private internal function of `promptbookCli`
|
|
1615
1612
|
*/
|
|
1616
1613
|
function $initializeCoderFindFreshEmojiTagCommand(program) {
|
|
1617
|
-
const command = program.command('find-fresh-emoji-
|
|
1618
|
-
command.description(
|
|
1614
|
+
const command = program.command('find-fresh-emoji-tags');
|
|
1615
|
+
command.description(_spaceTrim(`
|
|
1619
1616
|
Find unused emoji tags in the codebase
|
|
1620
1617
|
|
|
1621
1618
|
Scans entire codebase for emoji tags already in use (format: [emoji])
|
|
@@ -1624,7 +1621,7 @@ function $initializeCoderFindFreshEmojiTagCommand(program) {
|
|
|
1624
1621
|
`));
|
|
1625
1622
|
command.action(handleActionErrors(async () => {
|
|
1626
1623
|
// Note: Import the function dynamically to avoid loading heavy dependencies until needed
|
|
1627
|
-
const { findFreshEmojiTag } = await Promise.resolve().then(function () { return
|
|
1624
|
+
const { findFreshEmojiTag } = await Promise.resolve().then(function () { return findFreshEmojiTags; });
|
|
1628
1625
|
try {
|
|
1629
1626
|
await findFreshEmojiTag();
|
|
1630
1627
|
}
|
|
@@ -1649,7 +1646,7 @@ function $initializeCoderFindFreshEmojiTagCommand(program) {
|
|
|
1649
1646
|
*/
|
|
1650
1647
|
function $initializeCoderFindRefactorCandidatesCommand(program) {
|
|
1651
1648
|
const command = program.command('find-refactor-candidates');
|
|
1652
|
-
command.description(spaceTrim$
|
|
1649
|
+
command.description(spaceTrim$1(`
|
|
1653
1650
|
Scan source files to identify refactoring candidates
|
|
1654
1651
|
|
|
1655
1652
|
Flags files that exceed:
|
|
@@ -1839,7 +1836,7 @@ function buildPromptSlug$1(template, title) {
|
|
|
1839
1836
|
*/
|
|
1840
1837
|
function $initializeCoderRunCommand(program) {
|
|
1841
1838
|
const command = program.command('run');
|
|
1842
|
-
command.description(spaceTrim$
|
|
1839
|
+
command.description(spaceTrim$1(`
|
|
1843
1840
|
Execute coding prompts through selected AI agent
|
|
1844
1841
|
|
|
1845
1842
|
Runners:
|
|
@@ -1857,7 +1854,7 @@ function $initializeCoderRunCommand(program) {
|
|
|
1857
1854
|
`));
|
|
1858
1855
|
command.option('--dry-run', 'Print unwritten prompts without executing', false);
|
|
1859
1856
|
command.option('--agent <agent-name>', 'Select runner: openai-codex, cline, claude-code, opencode, gemini (required for non-dry-run)');
|
|
1860
|
-
command.option('--model <model>', spaceTrim$
|
|
1857
|
+
command.option('--model <model>', spaceTrim$1(`
|
|
1861
1858
|
Model to use (required for openai-codex and gemini)
|
|
1862
1859
|
|
|
1863
1860
|
OpenAI examples: gpt-5.2-codex, default
|
|
@@ -1945,7 +1942,7 @@ function parseIntOption(value) {
|
|
|
1945
1942
|
*/
|
|
1946
1943
|
function $initializeCoderVerifyCommand(program) {
|
|
1947
1944
|
const command = program.command('verify');
|
|
1948
|
-
command.description(spaceTrim$
|
|
1945
|
+
command.description(spaceTrim$1(`
|
|
1949
1946
|
Interactive verification helper for completed prompts
|
|
1950
1947
|
|
|
1951
1948
|
Features:
|
|
@@ -1983,7 +1980,7 @@ function $initializeCoderVerifyCommand(program) {
|
|
|
1983
1980
|
* - find-refactor-candidates: Find files that need refactoring
|
|
1984
1981
|
* - run: Run coding prompts with AI agents
|
|
1985
1982
|
* - verify: Verify completed prompts
|
|
1986
|
-
* - find-fresh-emoji-
|
|
1983
|
+
* - find-fresh-emoji-tags: Find unused emoji tags
|
|
1987
1984
|
*
|
|
1988
1985
|
* Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI
|
|
1989
1986
|
*
|
|
@@ -1991,7 +1988,7 @@ function $initializeCoderVerifyCommand(program) {
|
|
|
1991
1988
|
*/
|
|
1992
1989
|
function $initializeCoderCommand(program) {
|
|
1993
1990
|
const coderCommand = program.command('coder');
|
|
1994
|
-
coderCommand.description(spaceTrim$
|
|
1991
|
+
coderCommand.description(spaceTrim$1(`
|
|
1995
1992
|
Coding utilities for automated development workflows
|
|
1996
1993
|
|
|
1997
1994
|
Subcommands:
|
|
@@ -1999,7 +1996,7 @@ function $initializeCoderCommand(program) {
|
|
|
1999
1996
|
- find-refactor-candidates: Find files that need refactoring
|
|
2000
1997
|
- run: Run coding prompts with AI agents
|
|
2001
1998
|
- verify: Verify completed prompts
|
|
2002
|
-
- find-fresh-emoji-
|
|
1999
|
+
- find-fresh-emoji-tags: Find unused emoji tags
|
|
2003
2000
|
`));
|
|
2004
2001
|
// Register all subcommands
|
|
2005
2002
|
$initializeCoderGenerateBoilerplatesCommand(coderCommand);
|
|
@@ -2028,7 +2025,7 @@ function $initializeCoderCommand(program) {
|
|
|
2028
2025
|
*/
|
|
2029
2026
|
function $initializeHelloCommand(program) {
|
|
2030
2027
|
const helloCommand = program.command('hello');
|
|
2031
|
-
helloCommand.description(spaceTrim$
|
|
2028
|
+
helloCommand.description(spaceTrim$1(`
|
|
2032
2029
|
Just command for testing
|
|
2033
2030
|
`));
|
|
2034
2031
|
helloCommand.alias('hi');
|
|
@@ -2290,13 +2287,13 @@ function $registeredLlmToolsMessage() {
|
|
|
2290
2287
|
});
|
|
2291
2288
|
const usedEnvMessage = $usedEnvFilename === null ? `Unknown \`.env\` file` : `Used \`.env\` file:\n${$usedEnvFilename}`;
|
|
2292
2289
|
if (metadata.length === 0) {
|
|
2293
|
-
return spaceTrim$
|
|
2290
|
+
return spaceTrim$1((block) => `
|
|
2294
2291
|
No LLM providers are available.
|
|
2295
2292
|
|
|
2296
2293
|
${block(usedEnvMessage)}
|
|
2297
2294
|
`);
|
|
2298
2295
|
}
|
|
2299
|
-
return spaceTrim$
|
|
2296
|
+
return spaceTrim$1((block) => `
|
|
2300
2297
|
|
|
2301
2298
|
${block(usedEnvMessage)}
|
|
2302
2299
|
|
|
@@ -2342,7 +2339,7 @@ function $registeredLlmToolsMessage() {
|
|
|
2342
2339
|
morePieces.push(`Not configured`); // <- Note: Can not be configured via environment variables
|
|
2343
2340
|
}
|
|
2344
2341
|
}
|
|
2345
|
-
let providerMessage = spaceTrim$
|
|
2342
|
+
let providerMessage = spaceTrim$1(`
|
|
2346
2343
|
${i + 1}) **${title}** \`${className}\` from \`${packageName}\`
|
|
2347
2344
|
${morePieces.join('; ')}
|
|
2348
2345
|
`);
|
|
@@ -2408,7 +2405,7 @@ function jsonParse(value) {
|
|
|
2408
2405
|
}
|
|
2409
2406
|
else if (typeof value !== 'string') {
|
|
2410
2407
|
console.error('Can not parse JSON from non-string value.', { text: value });
|
|
2411
|
-
throw new Error(spaceTrim$
|
|
2408
|
+
throw new Error(spaceTrim$1(`
|
|
2412
2409
|
Can not parse JSON from non-string value.
|
|
2413
2410
|
|
|
2414
2411
|
The value type: ${typeof value}
|
|
@@ -2422,7 +2419,7 @@ function jsonParse(value) {
|
|
|
2422
2419
|
if (!(error instanceof Error)) {
|
|
2423
2420
|
throw error;
|
|
2424
2421
|
}
|
|
2425
|
-
throw new Error(spaceTrim$
|
|
2422
|
+
throw new Error(spaceTrim$1((block) => `
|
|
2426
2423
|
${block(error.message)}
|
|
2427
2424
|
|
|
2428
2425
|
The expected JSON text:
|
|
@@ -2644,7 +2641,7 @@ class $EnvStorage {
|
|
|
2644
2641
|
.filter((line) => !line.startsWith(`# ${GENERATOR_WARNING_IN_ENV}`)) // Remove GENERATOR_WARNING_IN_ENV
|
|
2645
2642
|
.filter((line) => !line.startsWith(`${transformedKey}=`)) // Remove existing key if present
|
|
2646
2643
|
.join('\n');
|
|
2647
|
-
const newEnvContent = spaceTrim$
|
|
2644
|
+
const newEnvContent = spaceTrim$1((block) => `
|
|
2648
2645
|
${block(updatedEnvContent)}
|
|
2649
2646
|
|
|
2650
2647
|
# ${GENERATOR_WARNING_IN_ENV}
|
|
@@ -2755,7 +2752,7 @@ function checkSerializableAsJson(options) {
|
|
|
2755
2752
|
}
|
|
2756
2753
|
else if (typeof value === 'object') {
|
|
2757
2754
|
if (value instanceof Date) {
|
|
2758
|
-
throw new UnexpectedError(spaceTrim$
|
|
2755
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
2759
2756
|
\`${name}\` is Date
|
|
2760
2757
|
|
|
2761
2758
|
Use \`string_date_iso8601\` instead
|
|
@@ -2774,7 +2771,7 @@ function checkSerializableAsJson(options) {
|
|
|
2774
2771
|
throw new UnexpectedError(`${name} is RegExp`);
|
|
2775
2772
|
}
|
|
2776
2773
|
else if (value instanceof Error) {
|
|
2777
|
-
throw new UnexpectedError(spaceTrim$
|
|
2774
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
2778
2775
|
\`${name}\` is unserialized Error
|
|
2779
2776
|
|
|
2780
2777
|
Use function \`serializeError\`
|
|
@@ -2797,7 +2794,7 @@ function checkSerializableAsJson(options) {
|
|
|
2797
2794
|
}
|
|
2798
2795
|
catch (error) {
|
|
2799
2796
|
assertsError(error);
|
|
2800
|
-
throw new UnexpectedError(spaceTrim$
|
|
2797
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
2801
2798
|
\`${name}\` is not serializable
|
|
2802
2799
|
|
|
2803
2800
|
${block(error.stack || error.message)}
|
|
@@ -2829,7 +2826,7 @@ function checkSerializableAsJson(options) {
|
|
|
2829
2826
|
}
|
|
2830
2827
|
}
|
|
2831
2828
|
else {
|
|
2832
|
-
throw new UnexpectedError(spaceTrim$
|
|
2829
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
2833
2830
|
\`${name}\` is unknown type
|
|
2834
2831
|
|
|
2835
2832
|
Additional message for \`${name}\`:
|
|
@@ -3093,7 +3090,7 @@ function isSerializableAsJson(value) {
|
|
|
3093
3090
|
*/
|
|
3094
3091
|
function stringifyPipelineJson(pipeline) {
|
|
3095
3092
|
if (!isSerializableAsJson(pipeline)) {
|
|
3096
|
-
throw new UnexpectedError(spaceTrim$
|
|
3093
|
+
throw new UnexpectedError(spaceTrim$1(`
|
|
3097
3094
|
Cannot stringify the pipeline, because it is not serializable as JSON
|
|
3098
3095
|
|
|
3099
3096
|
There can be multiple reasons:
|
|
@@ -4007,7 +4004,7 @@ function deserializeError(error, isStackAddedToMessage = true) {
|
|
|
4007
4004
|
message = `${name}: ${message}`;
|
|
4008
4005
|
}
|
|
4009
4006
|
if (isStackAddedToMessage && stack !== undefined && stack !== '') {
|
|
4010
|
-
message = spaceTrim$
|
|
4007
|
+
message = spaceTrim$1((block) => `
|
|
4011
4008
|
${block(message)}
|
|
4012
4009
|
|
|
4013
4010
|
Original stack trace:
|
|
@@ -4034,7 +4031,7 @@ async function createRemoteClient(options) {
|
|
|
4034
4031
|
const remoteServerUrlParsed = new URL(remoteServerUrl);
|
|
4035
4032
|
if (remoteServerUrlParsed.pathname !== '/' && remoteServerUrlParsed.pathname !== '') {
|
|
4036
4033
|
remoteServerUrlParsed.pathname = '/';
|
|
4037
|
-
throw new Error(spaceTrim$
|
|
4034
|
+
throw new Error(spaceTrim$1((block) => `
|
|
4038
4035
|
Remote server requires root url \`/\`
|
|
4039
4036
|
|
|
4040
4037
|
You have provided \`remoteServerUrl\`:
|
|
@@ -4360,7 +4357,7 @@ function serializeError(error) {
|
|
|
4360
4357
|
const { name, message, stack } = error;
|
|
4361
4358
|
const { id } = error;
|
|
4362
4359
|
if (!Object.keys(ALL_ERRORS).includes(name)) {
|
|
4363
|
-
console.error(spaceTrim$
|
|
4360
|
+
console.error(spaceTrim$1((block) => `
|
|
4364
4361
|
|
|
4365
4362
|
Cannot serialize error with name "${name}"
|
|
4366
4363
|
|
|
@@ -4885,7 +4882,7 @@ function buildParametersSection(items) {
|
|
|
4885
4882
|
const entries = items
|
|
4886
4883
|
.flatMap((item) => formatParameterListItem(item).split(/\r?\n/))
|
|
4887
4884
|
.filter((line) => line !== '');
|
|
4888
|
-
return spaceTrim$
|
|
4885
|
+
return spaceTrim$1((block) => `
|
|
4889
4886
|
**Parameters:**
|
|
4890
4887
|
${block(entries.join('\n'))}
|
|
4891
4888
|
|
|
@@ -4958,7 +4955,7 @@ function isPromptString(value) {
|
|
|
4958
4955
|
*/
|
|
4959
4956
|
function prompt(strings, ...values) {
|
|
4960
4957
|
if (values.length === 0) {
|
|
4961
|
-
return new PromptString(spaceTrim$
|
|
4958
|
+
return new PromptString(spaceTrim$1(strings.join('')));
|
|
4962
4959
|
}
|
|
4963
4960
|
const stringsWithHiddenParameters = strings.map((stringsItem) => ParameterEscaping.hideBrackets(stringsItem));
|
|
4964
4961
|
const parameterMetadata = values.map((value) => {
|
|
@@ -4999,7 +4996,7 @@ function prompt(strings, ...values) {
|
|
|
4999
4996
|
? `${result}${stringsItem}`
|
|
5000
4997
|
: `${result}${stringsItem}${ParameterSection.formatParameterPlaceholder(parameterName)}`;
|
|
5001
4998
|
}, '');
|
|
5002
|
-
pipelineString = spaceTrim$
|
|
4999
|
+
pipelineString = spaceTrim$1(pipelineString);
|
|
5003
5000
|
try {
|
|
5004
5001
|
pipelineString = templateParameters(pipelineString, parameters);
|
|
5005
5002
|
}
|
|
@@ -5008,7 +5005,7 @@ function prompt(strings, ...values) {
|
|
|
5008
5005
|
throw error;
|
|
5009
5006
|
}
|
|
5010
5007
|
console.error({ pipelineString, parameters, parameterNames: parameterNamesOrdered, error });
|
|
5011
|
-
throw new UnexpectedError(spaceTrim$
|
|
5008
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
5012
5009
|
Internal error in prompt template literal
|
|
5013
5010
|
|
|
5014
5011
|
${block(JSON.stringify({ strings, values }, null, 4))}}
|
|
@@ -5231,7 +5228,7 @@ const CountUtils = {
|
|
|
5231
5228
|
* @public exported from `@promptbook/utils`
|
|
5232
5229
|
*/
|
|
5233
5230
|
function computeHash(value) {
|
|
5234
|
-
return SHA256(hexEncoder.parse(spaceTrim$
|
|
5231
|
+
return SHA256(hexEncoder.parse(spaceTrim$1(valueToString(value)))).toString( /* hex */);
|
|
5235
5232
|
}
|
|
5236
5233
|
/**
|
|
5237
5234
|
* TODO: [🥬][🥬] Use this ACRY
|
|
@@ -7517,7 +7514,7 @@ function cacheLlmTools(llmTools, options = {}) {
|
|
|
7517
7514
|
let normalizedContent = content;
|
|
7518
7515
|
normalizedContent = normalizedContent.replace(/\s+/g, ' ');
|
|
7519
7516
|
normalizedContent = normalizedContent.split('\r\n').join('\n');
|
|
7520
|
-
normalizedContent = spaceTrim$
|
|
7517
|
+
normalizedContent = spaceTrim$1(normalizedContent);
|
|
7521
7518
|
// Note: Do not need to save everything in the cache, just the relevant parameters
|
|
7522
7519
|
const relevantParameterNames = extractParameterNames(content);
|
|
7523
7520
|
const relevantParameters = Object.fromEntries(Object.entries(parameters).filter(([key]) => relevantParameterNames.has(key)));
|
|
@@ -7987,14 +7984,14 @@ class MultipleLlmExecutionTools {
|
|
|
7987
7984
|
if (description === undefined) {
|
|
7988
7985
|
return headLine;
|
|
7989
7986
|
}
|
|
7990
|
-
return spaceTrim$
|
|
7987
|
+
return spaceTrim$1((block) => `
|
|
7991
7988
|
${headLine}
|
|
7992
7989
|
|
|
7993
7990
|
${ /* <- Note: Indenting the description: */block(description)}
|
|
7994
7991
|
`);
|
|
7995
7992
|
})
|
|
7996
7993
|
.join('\n\n');
|
|
7997
|
-
return spaceTrim$
|
|
7994
|
+
return spaceTrim$1((block) => `
|
|
7998
7995
|
Multiple LLM Providers:
|
|
7999
7996
|
|
|
8000
7997
|
${block(innerModelsTitlesAndDescriptions)}
|
|
@@ -8096,7 +8093,7 @@ class MultipleLlmExecutionTools {
|
|
|
8096
8093
|
// 1) OpenAI throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
8097
8094
|
// 2) AnthropicClaude throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
8098
8095
|
// 3) ...
|
|
8099
|
-
spaceTrim$
|
|
8096
|
+
spaceTrim$1((block) => `
|
|
8100
8097
|
All execution tools of ${this.title} failed:
|
|
8101
8098
|
|
|
8102
8099
|
${block(errors
|
|
@@ -8109,7 +8106,7 @@ class MultipleLlmExecutionTools {
|
|
|
8109
8106
|
throw new PipelineExecutionError(`You have not provided any \`LlmExecutionTools\` into ${this.title}`);
|
|
8110
8107
|
}
|
|
8111
8108
|
else {
|
|
8112
|
-
throw new PipelineExecutionError(spaceTrim$
|
|
8109
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
8113
8110
|
You have not provided any \`LlmExecutionTools\` that support model variant "${prompt.modelRequirements.modelVariant}" into ${this.title}
|
|
8114
8111
|
|
|
8115
8112
|
Available \`LlmExecutionTools\`:
|
|
@@ -8146,7 +8143,7 @@ class MultipleLlmExecutionTools {
|
|
|
8146
8143
|
*/
|
|
8147
8144
|
function joinLlmExecutionTools(title, ...llmExecutionTools) {
|
|
8148
8145
|
if (llmExecutionTools.length === 0) {
|
|
8149
|
-
const warningMessage = spaceTrim$
|
|
8146
|
+
const warningMessage = spaceTrim$1(`
|
|
8150
8147
|
You have not provided any \`LlmExecutionTools\`
|
|
8151
8148
|
This means that you won't be able to execute any prompts that require large language models like GPT-4 or Anthropic's Claude.
|
|
8152
8149
|
|
|
@@ -8204,7 +8201,7 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
|
|
|
8204
8201
|
.find(({ packageName, className }) => llmConfiguration.packageName === packageName && llmConfiguration.className === className);
|
|
8205
8202
|
if (registeredItem === undefined) {
|
|
8206
8203
|
// console.log('$llmToolsRegister.list()', $llmToolsRegister.list());
|
|
8207
|
-
throw new Error(spaceTrim$
|
|
8204
|
+
throw new Error(spaceTrim$1((block) => `
|
|
8208
8205
|
There is no constructor for LLM provider \`${llmConfiguration.className}\` from \`${llmConfiguration.packageName}\`
|
|
8209
8206
|
Running in ${!$isRunningInBrowser() ? '' : 'browser environment'}${!$isRunningInNode() ? '' : 'node environment'}${!$isRunningInWebWorker() ? '' : 'worker environment'}
|
|
8210
8207
|
|
|
@@ -8272,14 +8269,14 @@ async function $provideLlmToolsFromEnv(options = {}) {
|
|
|
8272
8269
|
const configuration = await $provideLlmToolsConfigurationFromEnv();
|
|
8273
8270
|
if (configuration.length === 0) {
|
|
8274
8271
|
if ($llmToolsMetadataRegister.list().length === 0) {
|
|
8275
|
-
throw new UnexpectedError(spaceTrim$
|
|
8272
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
8276
8273
|
No LLM tools registered, this is probably a bug in the Promptbook library
|
|
8277
8274
|
|
|
8278
8275
|
${block($registeredLlmToolsMessage())}}
|
|
8279
8276
|
`));
|
|
8280
8277
|
}
|
|
8281
8278
|
// TODO: [🥃]
|
|
8282
|
-
throw new Error(spaceTrim$
|
|
8279
|
+
throw new Error(spaceTrim$1((block) => `
|
|
8283
8280
|
No LLM tools found in the environment
|
|
8284
8281
|
|
|
8285
8282
|
${block($registeredLlmToolsMessage())}}
|
|
@@ -8389,7 +8386,7 @@ const promptbookFetch = async (urlOrRequest, init) => {
|
|
|
8389
8386
|
else if (urlOrRequest instanceof Request) {
|
|
8390
8387
|
url = urlOrRequest.url;
|
|
8391
8388
|
}
|
|
8392
|
-
throw new PromptbookFetchError(spaceTrim$
|
|
8389
|
+
throw new PromptbookFetchError(spaceTrim$1((block) => `
|
|
8393
8390
|
Can not fetch "${url}"
|
|
8394
8391
|
|
|
8395
8392
|
Fetch error:
|
|
@@ -8443,7 +8440,7 @@ async function $provideLlmToolsForCli(options) {
|
|
|
8443
8440
|
console.log(colors.red(`You can not login to remote server in non-interactive mode`));
|
|
8444
8441
|
process.exit(1);
|
|
8445
8442
|
}
|
|
8446
|
-
console.info(colors.cyan(spaceTrim$
|
|
8443
|
+
console.info(colors.cyan(spaceTrim$1(`
|
|
8447
8444
|
You will be logged in to ${remoteServerUrl}
|
|
8448
8445
|
If you don't have an account, it will be created automatically.
|
|
8449
8446
|
`)));
|
|
@@ -8517,7 +8514,7 @@ async function $provideLlmToolsForCli(options) {
|
|
|
8517
8514
|
*/
|
|
8518
8515
|
function $initializeListModelsCommand(program) {
|
|
8519
8516
|
const listModelsCommand = program.command('list-models');
|
|
8520
|
-
listModelsCommand.description(spaceTrim$
|
|
8517
|
+
listModelsCommand.description(spaceTrim$1(`
|
|
8521
8518
|
List all available and configured LLM models
|
|
8522
8519
|
`));
|
|
8523
8520
|
listModelsCommand.alias('models');
|
|
@@ -9006,14 +9003,14 @@ function $registeredScrapersMessage(availableScrapers) {
|
|
|
9006
9003
|
return { ...metadata, isMetadataAviailable, isInstalled, isAvailableInTools };
|
|
9007
9004
|
});
|
|
9008
9005
|
if (metadata.length === 0) {
|
|
9009
|
-
return spaceTrim$
|
|
9006
|
+
return spaceTrim$1(`
|
|
9010
9007
|
**No scrapers are available**
|
|
9011
9008
|
|
|
9012
9009
|
This is a unexpected behavior, you are probably using some broken version of Promptbook
|
|
9013
9010
|
At least there should be available the metadata of the scrapers
|
|
9014
9011
|
`);
|
|
9015
9012
|
}
|
|
9016
|
-
return spaceTrim$
|
|
9013
|
+
return spaceTrim$1((block) => `
|
|
9017
9014
|
Available scrapers are:
|
|
9018
9015
|
${block(metadata
|
|
9019
9016
|
.map(({ packageName, className, isMetadataAviailable, isInstalled, mimeTypes, isAvailableInBrowser, isAvailableInTools, }, i) => {
|
|
@@ -9064,7 +9061,7 @@ function $registeredScrapersMessage(availableScrapers) {
|
|
|
9064
9061
|
*/
|
|
9065
9062
|
function $initializeListScrapersCommand(program) {
|
|
9066
9063
|
const listModelsCommand = program.command('list-scrapers');
|
|
9067
|
-
listModelsCommand.description(spaceTrim$
|
|
9064
|
+
listModelsCommand.description(spaceTrim$1(`
|
|
9068
9065
|
List all available and configured scrapers and executables
|
|
9069
9066
|
`));
|
|
9070
9067
|
listModelsCommand.alias('scrapers');
|
|
@@ -9072,7 +9069,7 @@ function $initializeListScrapersCommand(program) {
|
|
|
9072
9069
|
// TODO: [🌞] Do not allow on REMOTE_SERVER strategy
|
|
9073
9070
|
const scrapers = await $provideScrapersForNode({});
|
|
9074
9071
|
const executables = await $provideExecutablesForNode();
|
|
9075
|
-
console.info(spaceTrim$
|
|
9072
|
+
console.info(spaceTrim$1((block) => `
|
|
9076
9073
|
${block($registeredScrapersMessage(scrapers))}
|
|
9077
9074
|
|
|
9078
9075
|
All mime-types which can be scraped:
|
|
@@ -9102,7 +9099,7 @@ function $initializeListScrapersCommand(program) {
|
|
|
9102
9099
|
*/
|
|
9103
9100
|
function $initializeLoginCommand(program) {
|
|
9104
9101
|
const loginCommand = program.command('login');
|
|
9105
|
-
loginCommand.description(spaceTrim$
|
|
9102
|
+
loginCommand.description(spaceTrim$1(`
|
|
9106
9103
|
Login to the remote Promptbook server
|
|
9107
9104
|
`));
|
|
9108
9105
|
loginCommand.action(handleActionErrors(async (cliOptions) => {
|
|
@@ -9602,7 +9599,7 @@ function pipelineJsonToString(pipelineJson) {
|
|
|
9602
9599
|
pipelineString += '\n\n';
|
|
9603
9600
|
pipelineString += '```' + contentLanguage;
|
|
9604
9601
|
pipelineString += '\n';
|
|
9605
|
-
pipelineString += spaceTrim$
|
|
9602
|
+
pipelineString += spaceTrim$1(content);
|
|
9606
9603
|
// <- TODO: [main] !!3 Escape
|
|
9607
9604
|
// <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
|
|
9608
9605
|
pipelineString += '\n';
|
|
@@ -10237,7 +10234,7 @@ const CsvFormatParser = {
|
|
|
10237
10234
|
const { value, outputParameterName, settings, mapCallback, onProgress } = options;
|
|
10238
10235
|
const csv = csvParse(value, settings);
|
|
10239
10236
|
if (csv.errors.length !== 0) {
|
|
10240
|
-
throw new CsvFormatError(spaceTrim$
|
|
10237
|
+
throw new CsvFormatError(spaceTrim$1((block) => `
|
|
10241
10238
|
CSV parsing error
|
|
10242
10239
|
|
|
10243
10240
|
Error(s) from CSV parsing:
|
|
@@ -10282,7 +10279,7 @@ const CsvFormatParser = {
|
|
|
10282
10279
|
const { value, settings, mapCallback, onProgress } = options;
|
|
10283
10280
|
const csv = csvParse(value, settings);
|
|
10284
10281
|
if (csv.errors.length !== 0) {
|
|
10285
|
-
throw new CsvFormatError(spaceTrim$
|
|
10282
|
+
throw new CsvFormatError(spaceTrim$1((block) => `
|
|
10286
10283
|
CSV parsing error
|
|
10287
10284
|
|
|
10288
10285
|
Error(s) from CSV parsing:
|
|
@@ -10468,7 +10465,7 @@ function mapAvailableToExpectedParameters(options) {
|
|
|
10468
10465
|
}
|
|
10469
10466
|
// Phase 2️⃣: Non-matching mapping
|
|
10470
10467
|
if (expectedParameterNames.size !== availableParametersNames.size) {
|
|
10471
|
-
throw new PipelineExecutionError(spaceTrim$
|
|
10468
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
10472
10469
|
Can not map available parameters to expected parameters
|
|
10473
10470
|
|
|
10474
10471
|
Mapped parameters:
|
|
@@ -10883,7 +10880,7 @@ async function executeFormatSubvalues(options) {
|
|
|
10883
10880
|
return /* not await */ executeAttempts({ ...options, logLlmCall });
|
|
10884
10881
|
}
|
|
10885
10882
|
if (jokerParameterNames.length !== 0) {
|
|
10886
|
-
throw new UnexpectedError(spaceTrim$
|
|
10883
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
10887
10884
|
JOKER parameters are not supported together with FOREACH command
|
|
10888
10885
|
|
|
10889
10886
|
[🧞♀️] This should be prevented in \`validatePipeline\`
|
|
@@ -10896,7 +10893,7 @@ async function executeFormatSubvalues(options) {
|
|
|
10896
10893
|
if (formatDefinition === undefined) {
|
|
10897
10894
|
throw new UnexpectedError(
|
|
10898
10895
|
// <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
|
|
10899
|
-
spaceTrim$
|
|
10896
|
+
spaceTrim$1((block) => `
|
|
10900
10897
|
Unsupported format "${task.foreach.formatName}"
|
|
10901
10898
|
|
|
10902
10899
|
Available formats:
|
|
@@ -10913,7 +10910,7 @@ async function executeFormatSubvalues(options) {
|
|
|
10913
10910
|
if (subvalueParser === undefined) {
|
|
10914
10911
|
throw new UnexpectedError(
|
|
10915
10912
|
// <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
|
|
10916
|
-
spaceTrim$
|
|
10913
|
+
spaceTrim$1((block) => `
|
|
10917
10914
|
Unsupported subformat name "${task.foreach.subformatName}" for format "${task.foreach.formatName}"
|
|
10918
10915
|
|
|
10919
10916
|
Available subformat names for format "${formatDefinition.formatName}":
|
|
@@ -10953,7 +10950,7 @@ async function executeFormatSubvalues(options) {
|
|
|
10953
10950
|
if (!(error instanceof PipelineExecutionError)) {
|
|
10954
10951
|
throw error;
|
|
10955
10952
|
}
|
|
10956
|
-
const highLevelError = new PipelineExecutionError(spaceTrim$
|
|
10953
|
+
const highLevelError = new PipelineExecutionError(spaceTrim$1((block) => `
|
|
10957
10954
|
${error.message}
|
|
10958
10955
|
|
|
10959
10956
|
This is error in FOREACH command when mapping ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
|
|
@@ -10977,7 +10974,7 @@ async function executeFormatSubvalues(options) {
|
|
|
10977
10974
|
...options,
|
|
10978
10975
|
priority: priority + index,
|
|
10979
10976
|
parameters: allSubparameters,
|
|
10980
|
-
pipelineIdentification: spaceTrim$
|
|
10977
|
+
pipelineIdentification: spaceTrim$1((block) => `
|
|
10981
10978
|
${block(pipelineIdentification)}
|
|
10982
10979
|
Subparameter index: ${index}
|
|
10983
10980
|
`),
|
|
@@ -10986,7 +10983,7 @@ async function executeFormatSubvalues(options) {
|
|
|
10986
10983
|
}
|
|
10987
10984
|
catch (error) {
|
|
10988
10985
|
if (length > BIG_DATASET_TRESHOLD) {
|
|
10989
|
-
console.error(spaceTrim$
|
|
10986
|
+
console.error(spaceTrim$1((block) => `
|
|
10990
10987
|
${error.message}
|
|
10991
10988
|
|
|
10992
10989
|
This is error in FOREACH command when processing ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
|
|
@@ -12030,7 +12027,7 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
|
|
|
12030
12027
|
const fileExtension = getFileExtension(filename);
|
|
12031
12028
|
const mimeType = extensionToMimeType(fileExtension || '');
|
|
12032
12029
|
if (!(await isFileExisting(filename, tools.fs))) {
|
|
12033
|
-
throw new NotFoundError(spaceTrim$
|
|
12030
|
+
throw new NotFoundError(spaceTrim$1((block) => `
|
|
12034
12031
|
Can not make source handler for file which does not exist:
|
|
12035
12032
|
|
|
12036
12033
|
File:
|
|
@@ -12123,7 +12120,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
12123
12120
|
// <- TODO: [🪓] Here should be no need for spreading new array, just `partialPieces = partialPiecesUnchecked`
|
|
12124
12121
|
break;
|
|
12125
12122
|
}
|
|
12126
|
-
console.warn(spaceTrim$
|
|
12123
|
+
console.warn(spaceTrim$1((block) => `
|
|
12127
12124
|
Cannot scrape knowledge from source despite the scraper \`${scraper.metadata.className}\` supports the mime type "${sourceHandler.mimeType}".
|
|
12128
12125
|
|
|
12129
12126
|
The source:
|
|
@@ -12139,7 +12136,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
12139
12136
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
12140
12137
|
}
|
|
12141
12138
|
if (partialPieces === null) {
|
|
12142
|
-
throw new KnowledgeScrapeError(spaceTrim$
|
|
12139
|
+
throw new KnowledgeScrapeError(spaceTrim$1((block) => `
|
|
12143
12140
|
Cannot scrape knowledge
|
|
12144
12141
|
|
|
12145
12142
|
The source:
|
|
@@ -12475,7 +12472,7 @@ const knowledgeCommandParser = {
|
|
|
12475
12472
|
*/
|
|
12476
12473
|
parse(input) {
|
|
12477
12474
|
const { args } = input;
|
|
12478
|
-
const knowledgeSourceContent = spaceTrim$
|
|
12475
|
+
const knowledgeSourceContent = spaceTrim$1(args[0] || '');
|
|
12479
12476
|
if (knowledgeSourceContent === '') {
|
|
12480
12477
|
throw new ParseError(`Source is not defined`);
|
|
12481
12478
|
}
|
|
@@ -12619,7 +12616,7 @@ const sectionCommandParser = {
|
|
|
12619
12616
|
normalized = normalized.split('DIALOGUE').join('DIALOG');
|
|
12620
12617
|
const taskTypes = SectionTypes.filter((sectionType) => normalized.includes(sectionType.split('_TASK').join('')));
|
|
12621
12618
|
if (taskTypes.length !== 1) {
|
|
12622
|
-
throw new ParseError(spaceTrim$
|
|
12619
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
12623
12620
|
Unknown section type "${normalized}"
|
|
12624
12621
|
|
|
12625
12622
|
Supported section types are:
|
|
@@ -12639,7 +12636,7 @@ const sectionCommandParser = {
|
|
|
12639
12636
|
*/
|
|
12640
12637
|
$applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
12641
12638
|
if ($taskJson.isSectionTypeSet === true) {
|
|
12642
|
-
throw new ParseError(spaceTrim$
|
|
12639
|
+
throw new ParseError(spaceTrim$1(`
|
|
12643
12640
|
Section type is already defined in the section.
|
|
12644
12641
|
It can be defined only once.
|
|
12645
12642
|
`));
|
|
@@ -12919,7 +12916,7 @@ const expectCommandParser = {
|
|
|
12919
12916
|
/**
|
|
12920
12917
|
* Description of the FORMAT command
|
|
12921
12918
|
*/
|
|
12922
|
-
description: spaceTrim$
|
|
12919
|
+
description: spaceTrim$1(`
|
|
12923
12920
|
Expect command describes the desired output of the task *(after post-processing)*
|
|
12924
12921
|
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.
|
|
12925
12922
|
`),
|
|
@@ -12993,7 +12990,7 @@ const expectCommandParser = {
|
|
|
12993
12990
|
}
|
|
12994
12991
|
catch (error) {
|
|
12995
12992
|
assertsError(error);
|
|
12996
|
-
throw new ParseError(spaceTrim$
|
|
12993
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
12997
12994
|
Invalid FORMAT command
|
|
12998
12995
|
${block(error.message)}:
|
|
12999
12996
|
`));
|
|
@@ -13105,7 +13102,7 @@ function validateParameterName(parameterName) {
|
|
|
13105
13102
|
if (!(error instanceof ParseError)) {
|
|
13106
13103
|
throw error;
|
|
13107
13104
|
}
|
|
13108
|
-
throw new ParseError(spaceTrim$
|
|
13105
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
13109
13106
|
${block(error.message)}
|
|
13110
13107
|
|
|
13111
13108
|
Tried to validate parameter name:
|
|
@@ -13164,7 +13161,7 @@ const foreachCommandParser = {
|
|
|
13164
13161
|
const assignSign = args[3];
|
|
13165
13162
|
const formatDefinition = FORMAT_DEFINITIONS.find((formatDefinition) => [formatDefinition.formatName, ...(formatDefinition.aliases || [])].includes(formatName));
|
|
13166
13163
|
if (formatDefinition === undefined) {
|
|
13167
|
-
throw new ParseError(spaceTrim$
|
|
13164
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
13168
13165
|
Unsupported format "${formatName}"
|
|
13169
13166
|
|
|
13170
13167
|
Available formats:
|
|
@@ -13176,7 +13173,7 @@ const foreachCommandParser = {
|
|
|
13176
13173
|
}
|
|
13177
13174
|
const subvalueParser = formatDefinition.subvalueParsers.find((subvalueParser) => [subvalueParser.subvalueName, ...(subvalueParser.aliases || [])].includes(subformatName));
|
|
13178
13175
|
if (subvalueParser === undefined) {
|
|
13179
|
-
throw new ParseError(spaceTrim$
|
|
13176
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
13180
13177
|
Unsupported subformat name "${subformatName}" for format "${formatName}"
|
|
13181
13178
|
|
|
13182
13179
|
Available subformat names for format "${formatDefinition.formatName}":
|
|
@@ -13224,7 +13221,7 @@ const foreachCommandParser = {
|
|
|
13224
13221
|
outputSubparameterName = 'newLine';
|
|
13225
13222
|
}
|
|
13226
13223
|
else {
|
|
13227
|
-
throw new ParseError(spaceTrim$
|
|
13224
|
+
throw new ParseError(spaceTrim$1(`
|
|
13228
13225
|
FOREACH ${formatName} ${subformatName} must specify output subparameter
|
|
13229
13226
|
|
|
13230
13227
|
Correct example:
|
|
@@ -13300,7 +13297,7 @@ const formatCommandParser = {
|
|
|
13300
13297
|
/**
|
|
13301
13298
|
* Description of the FORMAT command
|
|
13302
13299
|
*/
|
|
13303
|
-
description: spaceTrim$
|
|
13300
|
+
description: spaceTrim$1(`
|
|
13304
13301
|
Format command describes the desired output of the task (after post-processing)
|
|
13305
13302
|
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.
|
|
13306
13303
|
`),
|
|
@@ -13672,7 +13669,7 @@ const formfactorCommandParser = {
|
|
|
13672
13669
|
const formfactorNameCandidate = args[0].toUpperCase();
|
|
13673
13670
|
const formfactor = FORMFACTOR_DEFINITIONS.find((definition) => [definition.name, ...{ aliasNames: [], ...definition }.aliasNames].includes(formfactorNameCandidate));
|
|
13674
13671
|
if (formfactor === undefined) {
|
|
13675
|
-
throw new ParseError(spaceTrim$
|
|
13672
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
13676
13673
|
Unknown formfactor name "${formfactorNameCandidate}"
|
|
13677
13674
|
|
|
13678
13675
|
Available formfactors:
|
|
@@ -13691,7 +13688,7 @@ const formfactorCommandParser = {
|
|
|
13691
13688
|
*/
|
|
13692
13689
|
$applyToPipelineJson(command, $pipelineJson) {
|
|
13693
13690
|
if ($pipelineJson.formfactorName !== undefined && $pipelineJson.formfactorName !== command.formfactorName) {
|
|
13694
|
-
throw new ParseError(spaceTrim$
|
|
13691
|
+
throw new ParseError(spaceTrim$1(`
|
|
13695
13692
|
Redefinition of \`FORMFACTOR\` in the pipeline head
|
|
13696
13693
|
|
|
13697
13694
|
You have used:
|
|
@@ -13839,7 +13836,7 @@ const modelCommandParser = {
|
|
|
13839
13836
|
*/
|
|
13840
13837
|
parse(input) {
|
|
13841
13838
|
const { args, normalized } = input;
|
|
13842
|
-
const availableVariantsMessage = spaceTrim$
|
|
13839
|
+
const availableVariantsMessage = spaceTrim$1((block) => `
|
|
13843
13840
|
Available variants are:
|
|
13844
13841
|
${block(MODEL_VARIANTS.map((variantName) => `- ${variantName}${variantName !== 'EMBEDDING' ? '' : ' (Not available in pipeline)'}`).join('\n'))}
|
|
13845
13842
|
`);
|
|
@@ -13861,14 +13858,14 @@ const modelCommandParser = {
|
|
|
13861
13858
|
// <- Note: [🤖]
|
|
13862
13859
|
}
|
|
13863
13860
|
else if (normalized.startsWith('MODEL_VARIANT_EMBED')) {
|
|
13864
|
-
spaceTrim$
|
|
13861
|
+
spaceTrim$1((block) => `
|
|
13865
13862
|
Embedding model can not be used in pipeline
|
|
13866
13863
|
|
|
13867
13864
|
${block(availableVariantsMessage)}
|
|
13868
13865
|
`);
|
|
13869
13866
|
}
|
|
13870
13867
|
else {
|
|
13871
|
-
throw new ParseError(spaceTrim$
|
|
13868
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
13872
13869
|
Unknown model variant in command:
|
|
13873
13870
|
|
|
13874
13871
|
${block(availableVariantsMessage)}
|
|
@@ -13883,7 +13880,7 @@ const modelCommandParser = {
|
|
|
13883
13880
|
};
|
|
13884
13881
|
}
|
|
13885
13882
|
else {
|
|
13886
|
-
throw new ParseError(spaceTrim$
|
|
13883
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
13887
13884
|
Unknown model key in command.
|
|
13888
13885
|
|
|
13889
13886
|
Supported model keys are:
|
|
@@ -13910,7 +13907,7 @@ const modelCommandParser = {
|
|
|
13910
13907
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
13911
13908
|
}
|
|
13912
13909
|
else {
|
|
13913
|
-
throw new ParseError(spaceTrim$
|
|
13910
|
+
throw new ParseError(spaceTrim$1(`
|
|
13914
13911
|
Redefinition of \`MODEL ${command.key}\` in the pipeline head
|
|
13915
13912
|
|
|
13916
13913
|
You have used:
|
|
@@ -13938,7 +13935,7 @@ const modelCommandParser = {
|
|
|
13938
13935
|
// <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
|
|
13939
13936
|
}
|
|
13940
13937
|
else {
|
|
13941
|
-
throw new ParseError(spaceTrim$
|
|
13938
|
+
throw new ParseError(spaceTrim$1(`
|
|
13942
13939
|
Redefinition of MODEL \`${command.key}\` in the task "${$taskJson.title || $taskJson.name}"
|
|
13943
13940
|
|
|
13944
13941
|
You have used:
|
|
@@ -13948,7 +13945,7 @@ const modelCommandParser = {
|
|
|
13948
13945
|
}
|
|
13949
13946
|
}
|
|
13950
13947
|
if (command.value === ($pipelineJson.defaultModelRequirements || {})[command.key]) {
|
|
13951
|
-
console.log(spaceTrim$
|
|
13948
|
+
console.log(spaceTrim$1(`
|
|
13952
13949
|
Setting MODEL \`${command.key}\` in the task "${$taskJson.title || $taskJson.name}" to the same value as in the pipeline head
|
|
13953
13950
|
|
|
13954
13951
|
In pipeline head:
|
|
@@ -14031,7 +14028,7 @@ const parameterCommandParser = {
|
|
|
14031
14028
|
// <- TODO: When [🥶] fixed, change to:
|
|
14032
14029
|
// > const parameterDescriptionRaw = rawArgs.split(parameterNameRaw).join('').trim();
|
|
14033
14030
|
if (parameterDescriptionRaw && parameterDescriptionRaw.match(/\{(?<embeddedParameterName>[a-z0-9_]+)\}/im)) {
|
|
14034
|
-
throw new ParseError(spaceTrim$
|
|
14031
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
14035
14032
|
Parameter \`{${parameterNameRaw}}\` can not contain another parameter in description
|
|
14036
14033
|
|
|
14037
14034
|
The description:
|
|
@@ -14213,7 +14210,7 @@ function $applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
|
14213
14210
|
persona.description = personaDescription;
|
|
14214
14211
|
return;
|
|
14215
14212
|
}
|
|
14216
|
-
console.warn(spaceTrim$
|
|
14213
|
+
console.warn(spaceTrim$1(`
|
|
14217
14214
|
|
|
14218
14215
|
Persona "${personaName}" is defined multiple times with different description:
|
|
14219
14216
|
|
|
@@ -14224,7 +14221,7 @@ function $applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
|
14224
14221
|
${personaDescription}
|
|
14225
14222
|
|
|
14226
14223
|
`));
|
|
14227
|
-
persona.description += spaceTrim$
|
|
14224
|
+
persona.description += spaceTrim$1('\n\n' + personaDescription);
|
|
14228
14225
|
}
|
|
14229
14226
|
|
|
14230
14227
|
/**
|
|
@@ -15065,7 +15062,7 @@ function removeMarkdownComments(content) {
|
|
|
15065
15062
|
*/
|
|
15066
15063
|
function isFlatPipeline(pipelineString) {
|
|
15067
15064
|
pipelineString = removeMarkdownComments(pipelineString);
|
|
15068
|
-
pipelineString = spaceTrim$
|
|
15065
|
+
pipelineString = spaceTrim$1(pipelineString);
|
|
15069
15066
|
const isMarkdownBeginningWithHeadline = pipelineString.startsWith('# ');
|
|
15070
15067
|
//const isLastLineReturnStatement = pipelineString.split(/\r?\n/).pop()!.split('`').join('').startsWith('->');
|
|
15071
15068
|
const isBacktickBlockUsed = pipelineString.includes('```');
|
|
@@ -15091,7 +15088,7 @@ function deflatePipeline(pipelineString) {
|
|
|
15091
15088
|
if (!isFlatPipeline(pipelineString)) {
|
|
15092
15089
|
return pipelineString;
|
|
15093
15090
|
}
|
|
15094
|
-
pipelineString = spaceTrim$
|
|
15091
|
+
pipelineString = spaceTrim$1(pipelineString);
|
|
15095
15092
|
const pipelineStringLines = pipelineString.split(/\r?\n/);
|
|
15096
15093
|
const potentialReturnStatement = pipelineStringLines.pop();
|
|
15097
15094
|
let returnStatement;
|
|
@@ -15104,19 +15101,19 @@ function deflatePipeline(pipelineString) {
|
|
|
15104
15101
|
returnStatement = `-> {${DEFAULT_BOOK_OUTPUT_PARAMETER_NAME}}`;
|
|
15105
15102
|
pipelineStringLines.push(potentialReturnStatement);
|
|
15106
15103
|
}
|
|
15107
|
-
const prompt = spaceTrim$
|
|
15104
|
+
const prompt = spaceTrim$1(pipelineStringLines.join('\n'));
|
|
15108
15105
|
let quotedPrompt;
|
|
15109
15106
|
if (prompt.split(/\r?\n/).length <= 1) {
|
|
15110
15107
|
quotedPrompt = `> ${prompt}`;
|
|
15111
15108
|
}
|
|
15112
15109
|
else {
|
|
15113
|
-
quotedPrompt = spaceTrim$
|
|
15110
|
+
quotedPrompt = spaceTrim$1((block) => `
|
|
15114
15111
|
\`\`\`
|
|
15115
15112
|
${block(prompt.split('`').join('\\`'))}
|
|
15116
15113
|
\`\`\`
|
|
15117
15114
|
`);
|
|
15118
15115
|
}
|
|
15119
|
-
pipelineString = validatePipelineString(spaceTrim$
|
|
15116
|
+
pipelineString = validatePipelineString(spaceTrim$1((block) => `
|
|
15120
15117
|
# ${DEFAULT_BOOK_TITLE}
|
|
15121
15118
|
|
|
15122
15119
|
## Prompt
|
|
@@ -15180,7 +15177,7 @@ function extractAllListItemsFromMarkdown(markdown) {
|
|
|
15180
15177
|
function extractOneBlockFromMarkdown(markdown) {
|
|
15181
15178
|
const codeBlocks = extractAllBlocksFromMarkdown(markdown);
|
|
15182
15179
|
if (codeBlocks.length !== 1) {
|
|
15183
|
-
throw new ParseError(spaceTrim$
|
|
15180
|
+
throw new ParseError(spaceTrim$1((block) => `
|
|
15184
15181
|
There should be exactly 1 code block in task section, found ${codeBlocks.length} code blocks
|
|
15185
15182
|
|
|
15186
15183
|
${block(codeBlocks.map((block, i) => `Block ${i + 1}:\n${block.content}`).join('\n\n\n'))}
|
|
@@ -15205,7 +15202,7 @@ function parseMarkdownSection(value) {
|
|
|
15205
15202
|
}
|
|
15206
15203
|
const title = lines[0].replace(/^#+\s*/, '');
|
|
15207
15204
|
const level = (_b = (_a = lines[0].match(/^#+/)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
|
|
15208
|
-
const content = spaceTrim$
|
|
15205
|
+
const content = spaceTrim$1(lines.slice(1).join('\n'));
|
|
15209
15206
|
if (level < 1 || level > 6) {
|
|
15210
15207
|
throw new ParseError('Markdown section must have heading level between 1 and 6');
|
|
15211
15208
|
}
|
|
@@ -15233,7 +15230,7 @@ function splitMarkdownIntoSections(markdown) {
|
|
|
15233
15230
|
if (buffer.length === 0) {
|
|
15234
15231
|
return;
|
|
15235
15232
|
}
|
|
15236
|
-
let section = spaceTrim$
|
|
15233
|
+
let section = spaceTrim$1(buffer.join('\n'));
|
|
15237
15234
|
if (section === '') {
|
|
15238
15235
|
return;
|
|
15239
15236
|
}
|
|
@@ -15308,7 +15305,7 @@ function flattenMarkdown(markdown) {
|
|
|
15308
15305
|
flattenedMarkdown += `## ${title}` + `\n\n`;
|
|
15309
15306
|
flattenedMarkdown += content + `\n\n`; // <- [🧠] Maybe 3 new lines?
|
|
15310
15307
|
}
|
|
15311
|
-
return spaceTrim$
|
|
15308
|
+
return spaceTrim$1(flattenedMarkdown);
|
|
15312
15309
|
}
|
|
15313
15310
|
/**
|
|
15314
15311
|
* TODO: [🏛] This can be part of markdown builder
|
|
@@ -15959,8 +15956,8 @@ class MarkdownScraper {
|
|
|
15959
15956
|
knowledgeTextPieces.map(async (knowledgeTextPiece, i) => {
|
|
15960
15957
|
// Note: These are just default values, they will be overwritten by the actual values:
|
|
15961
15958
|
let name = `piece-${i}`;
|
|
15962
|
-
let title = spaceTrim$
|
|
15963
|
-
const knowledgePieceContent = spaceTrim$
|
|
15959
|
+
let title = spaceTrim$1(knowledgeTextPiece.substring(0, 100));
|
|
15960
|
+
const knowledgePieceContent = spaceTrim$1(knowledgeTextPiece);
|
|
15964
15961
|
let keywords = [];
|
|
15965
15962
|
const index = [];
|
|
15966
15963
|
/*
|
|
@@ -15973,7 +15970,7 @@ class MarkdownScraper {
|
|
|
15973
15970
|
isCrashedOnError: true,
|
|
15974
15971
|
});
|
|
15975
15972
|
const { title: titleRaw = 'Untitled' } = titleResult.outputParameters;
|
|
15976
|
-
title = spaceTrim$
|
|
15973
|
+
title = spaceTrim$1(titleRaw) /* <- TODO: Maybe do in pipeline */;
|
|
15977
15974
|
name = titleToName(title);
|
|
15978
15975
|
// --- Keywords
|
|
15979
15976
|
const keywordsResult = await prepareKeywordsExecutor({ knowledgePieceContent }).asPromise({
|
|
@@ -16326,2071 +16323,61 @@ async function fetchUrlContent(url) {
|
|
|
16326
16323
|
*/
|
|
16327
16324
|
|
|
16328
16325
|
/**
|
|
16329
|
-
*
|
|
16330
|
-
*
|
|
16331
|
-
* @private internal runtime wiring for commitment tools
|
|
16332
|
-
*/
|
|
16333
|
-
const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
|
|
16334
|
-
/**
|
|
16335
|
-
* Hidden argument key used to pass runtime context into individual tool calls.
|
|
16336
|
-
*
|
|
16337
|
-
* @private internal runtime wiring for commitment tools
|
|
16338
|
-
*/
|
|
16339
|
-
const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
|
|
16340
|
-
/**
|
|
16341
|
-
* Prompt parameter key used to pass a hidden tool-progress listener token into script execution.
|
|
16342
|
-
*
|
|
16343
|
-
* @private internal runtime wiring for commitment tools
|
|
16344
|
-
*/
|
|
16345
|
-
const TOOL_PROGRESS_TOKEN_PARAMETER = 'promptbookToolProgressToken';
|
|
16346
|
-
/**
|
|
16347
|
-
* Hidden argument key used to pass a tool-progress listener token into individual tool calls.
|
|
16348
|
-
*
|
|
16349
|
-
* @private internal runtime wiring for commitment tools
|
|
16350
|
-
*/
|
|
16351
|
-
const TOOL_PROGRESS_TOKEN_ARGUMENT = '__promptbookToolProgressToken';
|
|
16352
|
-
/**
|
|
16353
|
-
* Monotonic counter used for hidden progress-listener tokens.
|
|
16354
|
-
*
|
|
16355
|
-
* @private internal runtime wiring for commitment tools
|
|
16356
|
-
*/
|
|
16357
|
-
let toolCallProgressListenerCounter = 0;
|
|
16358
|
-
/**
|
|
16359
|
-
* Active tool-progress listeners keyed by hidden execution token.
|
|
16360
|
-
*
|
|
16361
|
-
* @private internal runtime wiring for commitment tools
|
|
16362
|
-
*/
|
|
16363
|
-
const toolCallProgressListeners = new Map();
|
|
16364
|
-
/**
|
|
16365
|
-
* Parses unknown runtime context payload into a normalized object.
|
|
16366
|
-
*
|
|
16367
|
-
* @private internal runtime wiring for commitment tools
|
|
16368
|
-
*/
|
|
16369
|
-
function parseToolRuntimeContext(rawValue) {
|
|
16370
|
-
if (!rawValue) {
|
|
16371
|
-
return null;
|
|
16372
|
-
}
|
|
16373
|
-
let parsed = rawValue;
|
|
16374
|
-
if (typeof rawValue === 'string') {
|
|
16375
|
-
try {
|
|
16376
|
-
parsed = JSON.parse(rawValue);
|
|
16377
|
-
}
|
|
16378
|
-
catch (_a) {
|
|
16379
|
-
return null;
|
|
16380
|
-
}
|
|
16381
|
-
}
|
|
16382
|
-
if (!parsed || typeof parsed !== 'object') {
|
|
16383
|
-
return null;
|
|
16384
|
-
}
|
|
16385
|
-
return parsed;
|
|
16386
|
-
}
|
|
16387
|
-
/**
|
|
16388
|
-
* Reads runtime context attached to tool call arguments.
|
|
16389
|
-
*
|
|
16390
|
-
* @private internal runtime wiring for commitment tools
|
|
16391
|
-
*/
|
|
16392
|
-
function readToolRuntimeContextFromToolArgs(args) {
|
|
16393
|
-
return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
|
|
16394
|
-
}
|
|
16395
|
-
/**
|
|
16396
|
-
* Reads the hidden tool-progress token from tool arguments.
|
|
16397
|
-
*
|
|
16398
|
-
* @private internal runtime wiring for commitment tools
|
|
16399
|
-
*/
|
|
16400
|
-
function readToolProgressTokenFromToolArgs(args) {
|
|
16401
|
-
const token = args[TOOL_PROGRESS_TOKEN_ARGUMENT];
|
|
16402
|
-
return typeof token === 'string' && token.trim().length > 0 ? token : null;
|
|
16403
|
-
}
|
|
16404
|
-
/**
|
|
16405
|
-
* Serializes runtime context for prompt parameters.
|
|
16406
|
-
*
|
|
16407
|
-
* @private internal runtime wiring for commitment tools
|
|
16408
|
-
*/
|
|
16409
|
-
function serializeToolRuntimeContext(context) {
|
|
16410
|
-
return JSON.stringify(context);
|
|
16411
|
-
}
|
|
16412
|
-
/**
|
|
16413
|
-
* Registers one in-memory listener that receives progress updates emitted by a running tool.
|
|
16414
|
-
*
|
|
16415
|
-
* The returned token is passed into script execution as a hidden argument so tool implementations
|
|
16416
|
-
* can stream progress without exposing extra parameters to the model.
|
|
16417
|
-
*
|
|
16418
|
-
* @param listener - Listener notified about tool progress.
|
|
16419
|
-
* @returns Hidden token used to route progress updates.
|
|
16420
|
-
* @private internal runtime wiring for commitment tools
|
|
16421
|
-
*/
|
|
16422
|
-
function registerToolCallProgressListener(listener) {
|
|
16423
|
-
toolCallProgressListenerCounter += 1;
|
|
16424
|
-
const token = `tool-progress:${Date.now()}:${toolCallProgressListenerCounter}`;
|
|
16425
|
-
toolCallProgressListeners.set(token, listener);
|
|
16426
|
-
return token;
|
|
16427
|
-
}
|
|
16428
|
-
/**
|
|
16429
|
-
* Unregisters one in-memory progress listener.
|
|
16430
|
-
*
|
|
16431
|
-
* @param token - Token previously created by `registerToolCallProgressListener`.
|
|
16432
|
-
* @private internal runtime wiring for commitment tools
|
|
16433
|
-
*/
|
|
16434
|
-
function unregisterToolCallProgressListener(token) {
|
|
16435
|
-
toolCallProgressListeners.delete(token);
|
|
16436
|
-
}
|
|
16437
|
-
/**
|
|
16438
|
-
* Emits one tool progress update using a hidden token carried in tool arguments.
|
|
16439
|
-
*
|
|
16440
|
-
* @param args - Raw tool arguments including hidden runtime keys.
|
|
16441
|
-
* @param update - Incremental progress update.
|
|
16442
|
-
* @returns `true` when a listener was found and notified.
|
|
16443
|
-
* @private internal runtime wiring for commitment tools
|
|
16444
|
-
*/
|
|
16445
|
-
function emitToolCallProgressFromToolArgs(args, update) {
|
|
16446
|
-
const token = readToolProgressTokenFromToolArgs(args);
|
|
16447
|
-
if (!token) {
|
|
16448
|
-
return false;
|
|
16449
|
-
}
|
|
16450
|
-
const listener = toolCallProgressListeners.get(token);
|
|
16451
|
-
if (!listener) {
|
|
16452
|
-
return false;
|
|
16453
|
-
}
|
|
16454
|
-
listener(update);
|
|
16455
|
-
return true;
|
|
16456
|
-
}
|
|
16457
|
-
/**
|
|
16458
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
16459
|
-
*/
|
|
16460
|
-
|
|
16461
|
-
/**
|
|
16462
|
-
* Logical public directory marker used in `run_browser` payload paths.
|
|
16326
|
+
* Cached implementation of `run_browser` when it can be resolved.
|
|
16463
16327
|
*
|
|
16464
|
-
*
|
|
16465
|
-
*/
|
|
16466
|
-
const RUN_BROWSER_ARTIFACT_PUBLIC_DIRECTORY = '.playwright-cli';
|
|
16467
|
-
/**
|
|
16468
|
-
* Runtime environment variable that overrides local artifact storage directory.
|
|
16469
|
-
*/
|
|
16470
|
-
const RUN_BROWSER_ARTIFACT_STORAGE_DIRECTORY_ENV = 'RUN_BROWSER_ARTIFACT_STORAGE_DIRECTORY';
|
|
16471
|
-
/**
|
|
16472
|
-
* Default writable directory for `run_browser` screenshot/video artifacts.
|
|
16473
|
-
*/
|
|
16474
|
-
const DEFAULT_RUN_BROWSER_ARTIFACT_STORAGE_DIRECTORY = join(tmpdir(), 'promptbook', 'run-browser-artifacts');
|
|
16475
|
-
/**
|
|
16476
|
-
* Converts Windows separators to POSIX separators for payload paths.
|
|
16477
|
-
*/
|
|
16478
|
-
function toPosixPath$1(pathname) {
|
|
16479
|
-
return pathname.split('\\').join('/');
|
|
16480
|
-
}
|
|
16481
|
-
/**
|
|
16482
|
-
* Resolves writable filesystem directory used for artifact persistence.
|
|
16483
|
-
*/
|
|
16484
|
-
function resolveRunBrowserArtifactStorageDirectory() {
|
|
16485
|
-
const configuredStorageDirectory = process.env[RUN_BROWSER_ARTIFACT_STORAGE_DIRECTORY_ENV];
|
|
16486
|
-
if (configuredStorageDirectory && configuredStorageDirectory.trim()) {
|
|
16487
|
-
return configuredStorageDirectory.trim();
|
|
16488
|
-
}
|
|
16489
|
-
return DEFAULT_RUN_BROWSER_ARTIFACT_STORAGE_DIRECTORY;
|
|
16490
|
-
}
|
|
16491
|
-
/**
|
|
16492
|
-
* Resolves absolute filesystem path of one artifact filename.
|
|
16493
|
-
*/
|
|
16494
|
-
function resolveRunBrowserArtifactFilesystemPath(artifactFilename) {
|
|
16495
|
-
return join(resolveRunBrowserArtifactStorageDirectory(), artifactFilename);
|
|
16496
|
-
}
|
|
16497
|
-
/**
|
|
16498
|
-
* Resolves payload path of one artifact filename used by replay renderers.
|
|
16499
|
-
*/
|
|
16500
|
-
function resolveRunBrowserArtifactPublicPath(artifactFilename) {
|
|
16501
|
-
return toPosixPath$1(`${RUN_BROWSER_ARTIFACT_PUBLIC_DIRECTORY}/${artifactFilename}`);
|
|
16502
|
-
}
|
|
16503
|
-
|
|
16504
|
-
/**
|
|
16505
|
-
* Error code used for remote-browser infrastructure outages.
|
|
16506
|
-
*/
|
|
16507
|
-
const REMOTE_BROWSER_UNAVAILABLE_ERROR_CODE = 'REMOTE_BROWSER_UNAVAILABLE';
|
|
16508
|
-
/**
|
|
16509
|
-
* Error thrown when a remote Playwright browser cannot be reached.
|
|
16510
|
-
*/
|
|
16511
|
-
class RemoteBrowserUnavailableError extends KnowledgeScrapeError {
|
|
16512
|
-
constructor(options) {
|
|
16513
|
-
var _a;
|
|
16514
|
-
super(options.message);
|
|
16515
|
-
this.code = REMOTE_BROWSER_UNAVAILABLE_ERROR_CODE;
|
|
16516
|
-
this.isRetryable = true;
|
|
16517
|
-
this.debug = options.debug;
|
|
16518
|
-
this.suggestedNextSteps =
|
|
16519
|
-
(_a = options.suggestedNextSteps) !== null && _a !== void 0 ? _a : [
|
|
16520
|
-
'Verify remote browser infrastructure is running and reachable from Agents Server.',
|
|
16521
|
-
'Check firewall and DNS routing for the remote browser host and port.',
|
|
16522
|
-
'Retry later or continue with non-graphical fallback scraping.',
|
|
16523
|
-
];
|
|
16524
|
-
this.cause = options.cause;
|
|
16525
|
-
Object.setPrototypeOf(this, RemoteBrowserUnavailableError.prototype);
|
|
16526
|
-
}
|
|
16527
|
-
}
|
|
16528
|
-
/**
|
|
16529
|
-
* Returns true when an unknown value is one of the remote-browser outage errors.
|
|
16530
|
-
*/
|
|
16531
|
-
function isRemoteBrowserUnavailableError(error) {
|
|
16532
|
-
return error instanceof RemoteBrowserUnavailableError;
|
|
16533
|
-
}
|
|
16534
|
-
/**
|
|
16535
|
-
* Sanitizes a remote websocket endpoint so debug payloads never expose path secrets.
|
|
16536
|
-
*/
|
|
16537
|
-
function sanitizeRemoteBrowserEndpoint(wsEndpoint) {
|
|
16538
|
-
var _a, _b;
|
|
16539
|
-
try {
|
|
16540
|
-
const parsedEndpoint = new URL(wsEndpoint);
|
|
16541
|
-
return {
|
|
16542
|
-
protocol: parsedEndpoint.protocol || null,
|
|
16543
|
-
host: parsedEndpoint.hostname || null,
|
|
16544
|
-
port: parsedEndpoint.port ? Number.parseInt(parsedEndpoint.port, 10) : null,
|
|
16545
|
-
};
|
|
16546
|
-
}
|
|
16547
|
-
catch (_c) {
|
|
16548
|
-
const hostPortMatch = wsEndpoint.trim().match(/^(?:wss?:\/\/)?(?<host>[^:/?#]+)(?::(?<port>\d{1,5}))?/i);
|
|
16549
|
-
const host = ((_a = hostPortMatch === null || hostPortMatch === void 0 ? void 0 : hostPortMatch.groups) === null || _a === void 0 ? void 0 : _a.host) || null;
|
|
16550
|
-
const parsedPort = (_b = hostPortMatch === null || hostPortMatch === void 0 ? void 0 : hostPortMatch.groups) === null || _b === void 0 ? void 0 : _b.port;
|
|
16551
|
-
return {
|
|
16552
|
-
protocol: wsEndpoint.startsWith('wss://') ? 'wss:' : wsEndpoint.startsWith('ws://') ? 'ws:' : null,
|
|
16553
|
-
host,
|
|
16554
|
-
port: parsedPort ? Number.parseInt(parsedPort, 10) : null,
|
|
16555
|
-
};
|
|
16556
|
-
}
|
|
16557
|
-
}
|
|
16558
|
-
/**
|
|
16559
|
-
* Extracts network-like error code from unknown error payload.
|
|
16560
|
-
*/
|
|
16561
|
-
function extractNetworkErrorCode(error) {
|
|
16562
|
-
var _a;
|
|
16563
|
-
if (error && typeof error === 'object') {
|
|
16564
|
-
const maybeCode = error.code;
|
|
16565
|
-
if (typeof maybeCode === 'string' && maybeCode.trim()) {
|
|
16566
|
-
return maybeCode.trim().toUpperCase();
|
|
16567
|
-
}
|
|
16568
|
-
}
|
|
16569
|
-
const message = getErrorMessage(error);
|
|
16570
|
-
const match = message.match(/\b(ECONNREFUSED|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|ECONNRESET|EHOSTUNREACH|ENETUNREACH)\b/i);
|
|
16571
|
-
return ((_a = match === null || match === void 0 ? void 0 : match[1]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || null;
|
|
16572
|
-
}
|
|
16573
|
-
/**
|
|
16574
|
-
* Classifies whether an unknown error most likely represents remote browser infra outage.
|
|
16575
|
-
*/
|
|
16576
|
-
function isRemoteBrowserInfrastructureError(error) {
|
|
16577
|
-
const networkErrorCode = extractNetworkErrorCode(error);
|
|
16578
|
-
if (networkErrorCode) {
|
|
16579
|
-
return true;
|
|
16580
|
-
}
|
|
16581
|
-
const message = getErrorMessage(error).toLowerCase();
|
|
16582
|
-
const isWebSocketFailure = message.includes('websocket') ||
|
|
16583
|
-
message.includes('<ws error>') ||
|
|
16584
|
-
message.includes('ws connect error') ||
|
|
16585
|
-
message.includes('socket hang up');
|
|
16586
|
-
const hasHandshakeFailure = message.includes('unexpected server response') ||
|
|
16587
|
-
message.includes('handshake') ||
|
|
16588
|
-
message.includes('code=1006') ||
|
|
16589
|
-
message.includes('disconnected');
|
|
16590
|
-
return isWebSocketFailure && hasHandshakeFailure;
|
|
16591
|
-
}
|
|
16592
|
-
/**
|
|
16593
|
-
* Converts unknown thrown values into safe string messages.
|
|
16594
|
-
*/
|
|
16595
|
-
function getErrorMessage(error) {
|
|
16596
|
-
return error instanceof Error ? error.message : String(error);
|
|
16597
|
-
}
|
|
16598
|
-
/**
|
|
16599
|
-
* Converts unknown errors into stack payloads that are safe to render in debug mode.
|
|
16600
|
-
*/
|
|
16601
|
-
function getErrorStack(error) {
|
|
16602
|
-
return error instanceof Error && error.stack ? error.stack : null;
|
|
16603
|
-
}
|
|
16604
|
-
|
|
16605
|
-
/**
|
|
16606
|
-
* Matches unsupported characters in snapshot file suffixes.
|
|
16607
|
-
*/
|
|
16608
|
-
const SNAPSHOT_FILE_SUFFIX_UNSAFE_CHARACTER_PATTERN = /[^a-z0-9-]/g;
|
|
16609
|
-
/**
|
|
16610
|
-
* Creates one filesystem-safe optional filename suffix for a snapshot.
|
|
16611
|
-
*/
|
|
16612
|
-
function createSnapshotFileSuffix(rawSuffix) {
|
|
16613
|
-
if (!rawSuffix) {
|
|
16614
|
-
return '';
|
|
16615
|
-
}
|
|
16616
|
-
const normalized = rawSuffix
|
|
16617
|
-
.trim()
|
|
16618
|
-
.toLowerCase()
|
|
16619
|
-
.replace(/\s+/g, '-')
|
|
16620
|
-
.replace(SNAPSHOT_FILE_SUFFIX_UNSAFE_CHARACTER_PATTERN, '-')
|
|
16621
|
-
.replace(/-+/g, '-')
|
|
16622
|
-
.replace(/^-|-$/g, '');
|
|
16623
|
-
return normalized;
|
|
16624
|
-
}
|
|
16625
|
-
/**
|
|
16626
|
-
* Resolves snapshot filename for one session and optional stage suffix.
|
|
16627
|
-
*/
|
|
16628
|
-
function resolveSnapshotFilename(sessionId, fileSuffix) {
|
|
16629
|
-
const safeSuffix = createSnapshotFileSuffix(fileSuffix);
|
|
16630
|
-
return safeSuffix ? `${sessionId}-${safeSuffix}.png` : `${sessionId}.png`;
|
|
16631
|
-
}
|
|
16632
|
-
/**
|
|
16633
|
-
* Creates one user-facing description for an executed browser action.
|
|
16634
|
-
*/
|
|
16635
|
-
function formatActionSummary(action) {
|
|
16636
|
-
switch (action.type) {
|
|
16637
|
-
case 'navigate':
|
|
16638
|
-
return `Navigate to ${action.url}`;
|
|
16639
|
-
case 'click':
|
|
16640
|
-
return `Click ${action.selector}`;
|
|
16641
|
-
case 'type':
|
|
16642
|
-
return `Type into ${action.selector}`;
|
|
16643
|
-
case 'wait':
|
|
16644
|
-
return `Wait ${action.milliseconds}ms`;
|
|
16645
|
-
case 'scroll':
|
|
16646
|
-
return action.selector ? `Scroll ${action.pixels}px in ${action.selector}` : `Scroll ${action.pixels}px on page`;
|
|
16647
|
-
}
|
|
16648
|
-
}
|
|
16649
|
-
/**
|
|
16650
|
-
* Screenshot/artifact and page-cleanup helpers for `run_browser`.
|
|
16651
|
-
*
|
|
16652
|
-
* @private function of `run_browser`
|
|
16653
|
-
*/
|
|
16654
|
-
const runBrowserArtifacts = {
|
|
16655
|
-
/**
|
|
16656
|
-
* Captures a screenshot artifact for the current page and returns relative path.
|
|
16657
|
-
*/
|
|
16658
|
-
async captureSnapshot(page, sessionId, fileSuffix) {
|
|
16659
|
-
const snapshotFilename = resolveSnapshotFilename(sessionId, fileSuffix);
|
|
16660
|
-
const snapshotDirectoryPath = resolveRunBrowserArtifactStorageDirectory();
|
|
16661
|
-
const snapshotPath = resolveRunBrowserArtifactFilesystemPath(snapshotFilename);
|
|
16662
|
-
try {
|
|
16663
|
-
await mkdir(snapshotDirectoryPath, { recursive: true });
|
|
16664
|
-
try {
|
|
16665
|
-
await page.screenshot({ path: snapshotPath, fullPage: true });
|
|
16666
|
-
}
|
|
16667
|
-
catch (error) {
|
|
16668
|
-
console.warn('[run_browser] Full-page snapshot failed, retrying viewport-only screenshot', {
|
|
16669
|
-
sessionId,
|
|
16670
|
-
snapshotFilename,
|
|
16671
|
-
error: getErrorMessage(error),
|
|
16672
|
-
});
|
|
16673
|
-
await page.screenshot({ path: snapshotPath, fullPage: false });
|
|
16674
|
-
}
|
|
16675
|
-
return resolveRunBrowserArtifactPublicPath(snapshotFilename);
|
|
16676
|
-
}
|
|
16677
|
-
catch (error) {
|
|
16678
|
-
console.error('[run_browser] Failed to capture snapshot', {
|
|
16679
|
-
sessionId,
|
|
16680
|
-
snapshotFilename,
|
|
16681
|
-
error: getErrorMessage(error),
|
|
16682
|
-
});
|
|
16683
|
-
return null;
|
|
16684
|
-
}
|
|
16685
|
-
},
|
|
16686
|
-
/**
|
|
16687
|
-
* Safely retrieves page title from current browser page.
|
|
16688
|
-
*/
|
|
16689
|
-
async getPageTitle(page) {
|
|
16690
|
-
try {
|
|
16691
|
-
return await page.title();
|
|
16692
|
-
}
|
|
16693
|
-
catch (_a) {
|
|
16694
|
-
return null;
|
|
16695
|
-
}
|
|
16696
|
-
},
|
|
16697
|
-
/**
|
|
16698
|
-
* Closes browser page and logs non-fatal cleanup errors.
|
|
16699
|
-
*/
|
|
16700
|
-
async cleanupPage(page, sessionId) {
|
|
16701
|
-
if (!page) {
|
|
16702
|
-
return;
|
|
16703
|
-
}
|
|
16704
|
-
try {
|
|
16705
|
-
await page.close();
|
|
16706
|
-
}
|
|
16707
|
-
catch (error) {
|
|
16708
|
-
console.error('[run_browser] Failed to cleanup browser page', {
|
|
16709
|
-
sessionId,
|
|
16710
|
-
error: getErrorMessage(error),
|
|
16711
|
-
});
|
|
16712
|
-
}
|
|
16713
|
-
},
|
|
16714
|
-
/**
|
|
16715
|
-
* Captures one screenshot artifact and enriches it with page metadata.
|
|
16716
|
-
*/
|
|
16717
|
-
async captureSnapshotArtifact(options) {
|
|
16718
|
-
const { page, sessionId, label, fileSuffix, actionIndex, action } = options;
|
|
16719
|
-
const path = await this.captureSnapshot(page, sessionId, fileSuffix);
|
|
16720
|
-
if (!path) {
|
|
16721
|
-
return null;
|
|
16722
|
-
}
|
|
16723
|
-
const actionSummary = action ? formatActionSummary(action) : undefined;
|
|
16724
|
-
return {
|
|
16725
|
-
kind: 'screenshot',
|
|
16726
|
-
label,
|
|
16727
|
-
path,
|
|
16728
|
-
capturedAt: new Date().toISOString(),
|
|
16729
|
-
url: page.url(),
|
|
16730
|
-
title: await this.getPageTitle(page),
|
|
16731
|
-
actionIndex,
|
|
16732
|
-
actionSummary,
|
|
16733
|
-
};
|
|
16734
|
-
},
|
|
16735
|
-
};
|
|
16736
|
-
|
|
16737
|
-
/**
|
|
16738
|
-
* Shared constants used by the `run_browser` tool.
|
|
16739
|
-
*
|
|
16740
|
-
* @private internal constants of `run_browser`
|
|
16741
|
-
*/
|
|
16742
|
-
const runBrowserConstants = {
|
|
16743
|
-
sessionPrefix: 'agents-server-run-browser',
|
|
16744
|
-
snapshotDirectory: '.playwright-cli',
|
|
16745
|
-
resultSchema: 'promptbook/run-browser@1',
|
|
16746
|
-
defaultWaitMs: 1000,
|
|
16747
|
-
maxWaitMs: 60000,
|
|
16748
|
-
defaultScrollPixels: 800,
|
|
16749
|
-
defaultNavigationTimeoutMs: 20000,
|
|
16750
|
-
defaultActionTimeoutMs: 15000,
|
|
16751
|
-
fallbackDynamicContentWarning: 'Remote browser is unavailable. Fallback scraping was used and dynamic content may be missing.',
|
|
16752
|
-
validationErrorCode: 'RUN_BROWSER_VALIDATION_ERROR',
|
|
16753
|
-
navigationFailedErrorCode: 'RUN_BROWSER_NAVIGATION_FAILED',
|
|
16754
|
-
actionFailedErrorCode: 'RUN_BROWSER_ACTION_FAILED',
|
|
16755
|
-
cancelledErrorCode: 'RUN_BROWSER_CANCELLED',
|
|
16756
|
-
unknownErrorCode: 'RUN_BROWSER_UNKNOWN_ERROR',
|
|
16757
|
-
};
|
|
16758
|
-
|
|
16759
|
-
const config = ConfigChecker.from({
|
|
16760
|
-
...process.env,
|
|
16761
|
-
// Note: To expose env variables to the browser, using this seemingly strange syntax:
|
|
16762
|
-
// @see https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#exposing-environment-variables-to-the-browser
|
|
16763
|
-
NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL,
|
|
16764
|
-
NEXT_PUBLIC_VERCEL_ENV: process.env.NEXT_PUBLIC_VERCEL_ENV,
|
|
16765
|
-
NEXT_PUBLIC_VERCEL_TARGET_ENV: process.env.NEXT_PUBLIC_VERCEL_TARGET_ENV,
|
|
16766
|
-
NEXT_PUBLIC_VERCEL_URL: process.env.NEXT_PUBLIC_VERCEL_URL,
|
|
16767
|
-
NEXT_PUBLIC_VERCEL_BRANCH_URL: process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL,
|
|
16768
|
-
NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL: process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL,
|
|
16769
|
-
NEXT_PUBLIC_VERCEL_GIT_PROVIDER: process.env.NEXT_PUBLIC_VERCEL_GIT_PROVIDER,
|
|
16770
|
-
NEXT_PUBLIC_VERCEL_GIT_REPO_OWNER: process.env.NEXT_PUBLIC_VERCEL_GIT_REPO_OWNER,
|
|
16771
|
-
NEXT_PUBLIC_VERCEL_GIT_REPO_SLUG: process.env.NEXT_PUBLIC_VERCEL_GIT_REPO_SLUG,
|
|
16772
|
-
NEXT_PUBLIC_VERCEL_GIT_REPO_ID: process.env.NEXT_PUBLIC_VERCEL_GIT_REPO_ID,
|
|
16773
|
-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,
|
|
16774
|
-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE,
|
|
16775
|
-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF,
|
|
16776
|
-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME,
|
|
16777
|
-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_LOGIN: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_LOGIN,
|
|
16778
|
-
NEXT_PUBLIC_VERCEL_GIT_PREVIOUS_SHA: process.env.NEXT_PUBLIC_VERCEL_GIT_PREVIOUS_SHA,
|
|
16779
|
-
NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID: process.env.NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID,
|
|
16780
|
-
});
|
|
16781
|
-
/**
|
|
16782
|
-
* Public URL of the deployment, e.g. "https://my-app.vercel.app"
|
|
16783
|
-
*
|
|
16784
|
-
* Note: When a request resolves through the global `_Server` registry,
|
|
16785
|
-
* this URL will be overridden by the matched server domain.
|
|
16786
|
-
*/
|
|
16787
|
-
config.get('NEXT_PUBLIC_SITE_URL').url().value;
|
|
16788
|
-
/**
|
|
16789
|
-
* [♐️] Vercel environment: "development" | "preview" | "production"
|
|
16790
|
-
*/
|
|
16791
|
-
config.get('NEXT_PUBLIC_VERCEL_ENV').value;
|
|
16792
|
-
/**
|
|
16793
|
-
* [♐️] Target environment – can be system or custom
|
|
16794
|
-
*/
|
|
16795
|
-
config.get('NEXT_PUBLIC_VERCEL_TARGET_ENV').value;
|
|
16796
|
-
/**
|
|
16797
|
-
* [♐️] Deployment URL (without https://), e.g. "my-app-abc123.vercel.app"
|
|
16798
|
-
*/
|
|
16799
|
-
config.get('NEXT_PUBLIC_VERCEL_URL').value;
|
|
16800
|
-
/**
|
|
16801
|
-
* [♐️] Branch URL (without https://), only for branch deployments
|
|
16802
|
-
*/
|
|
16803
|
-
config.get('NEXT_PUBLIC_VERCEL_BRANCH_URL').value;
|
|
16804
|
-
/**
|
|
16805
|
-
* [♐️] Production domain of the project
|
|
16806
|
-
*/
|
|
16807
|
-
config.get('NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL').value;
|
|
16808
|
-
/**
|
|
16809
|
-
* [♐️] Git provider (github | gitlab | bitbucket)
|
|
16810
|
-
*/
|
|
16811
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_PROVIDER').value;
|
|
16812
|
-
/**
|
|
16813
|
-
* [♐️] Repository owner (e.g. "hejny")
|
|
16814
|
-
*/
|
|
16815
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_REPO_OWNER').value;
|
|
16816
|
-
/**
|
|
16817
|
-
* [♐️] Repository slug (e.g. "my-project")
|
|
16818
|
-
*/
|
|
16819
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_REPO_SLUG').value;
|
|
16820
|
-
/**
|
|
16821
|
-
* [♐️] Repository internal ID
|
|
16822
|
-
*/
|
|
16823
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_REPO_ID').value;
|
|
16824
|
-
/**
|
|
16825
|
-
* [♐️] Git commit SHA (short or long)
|
|
16826
|
-
*/
|
|
16827
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA').value;
|
|
16828
|
-
/**
|
|
16829
|
-
* [♐️] Commit message used for this deployment
|
|
16830
|
-
*/
|
|
16831
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE').value;
|
|
16832
|
-
/**
|
|
16833
|
-
* [♐️] Branch name (ref), e.g. "main"
|
|
16834
|
-
*/
|
|
16835
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF').value;
|
|
16836
|
-
/**
|
|
16837
|
-
* Author name of the commit
|
|
16838
|
-
*/
|
|
16839
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_NAME').value;
|
|
16840
|
-
/**
|
|
16841
|
-
* [♐️] Author login/username
|
|
16842
|
-
*/
|
|
16843
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_LOGIN').value;
|
|
16844
|
-
/**
|
|
16845
|
-
* [♐️] Previous deployment commit SHA (if exists)
|
|
16846
|
-
*/
|
|
16847
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_PREVIOUS_SHA').value;
|
|
16848
|
-
/**
|
|
16849
|
-
* [♐️] Pull Request ID for PR-based deployments
|
|
16850
|
-
*/
|
|
16851
|
-
config.get('NEXT_PUBLIC_VERCEL_GIT_PULL_REQUEST_ID').value;
|
|
16852
|
-
/**
|
|
16853
|
-
* Supabase table prefix
|
|
16854
|
-
*
|
|
16855
|
-
* This remains the fallback/default prefix used before `_Server` contains records
|
|
16856
|
-
* or for local development requests.
|
|
16857
|
-
*/
|
|
16858
|
-
config.get('SUPABASE_TABLE_PREFIX').value;
|
|
16859
|
-
/**
|
|
16860
|
-
* WebSocket endpoint URL for remote Playwright browser server (e.g., ws://browser-server:3000).
|
|
16861
|
-
*
|
|
16862
|
-
* When set, browser automation will connect to this remote server instead of launching a local browser.
|
|
16863
|
-
* This is useful for environments like Vercel where running a full browser locally is not possible.
|
|
16864
|
-
* Leave empty to use local browser mode.
|
|
16865
|
-
*/
|
|
16866
|
-
const rawRemoteBrowserUrl = config.get('REMOTE_BROWSER_URL').value;
|
|
16867
|
-
/**
|
|
16868
|
-
* WebSocket endpoint URL for remote Playwright browser server (e.g., ws://browser-server:3000).
|
|
16869
|
-
*
|
|
16870
|
-
* When set, browser automation will connect to this remote server instead of launching a local browser.
|
|
16871
|
-
* This is useful for environments like Vercel where running a full browser locally is not possible.
|
|
16872
|
-
* Leave empty to use local browser mode.
|
|
16873
|
-
*/
|
|
16874
|
-
const REMOTE_BROWSER_URL = typeof rawRemoteBrowserUrl === 'string' ? rawRemoteBrowserUrl : '';
|
|
16875
|
-
|
|
16876
|
-
/**
|
|
16877
|
-
* Reads a positive integer value from environment variables.
|
|
16878
|
-
*/
|
|
16879
|
-
function resolvePositiveIntFromEnv$1(variableName, defaultValue) {
|
|
16880
|
-
const rawValue = process.env[variableName];
|
|
16881
|
-
if (!rawValue || !rawValue.trim()) {
|
|
16882
|
-
return defaultValue;
|
|
16883
|
-
}
|
|
16884
|
-
const parsed = Number.parseInt(rawValue.trim(), 10);
|
|
16885
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
16886
|
-
return defaultValue;
|
|
16887
|
-
}
|
|
16888
|
-
return parsed;
|
|
16889
|
-
}
|
|
16890
|
-
/**
|
|
16891
|
-
* Runtime helpers for mode/session/timeout handling in `run_browser`.
|
|
16892
|
-
*
|
|
16893
|
-
* @private function of `run_browser`
|
|
16894
|
-
*/
|
|
16895
|
-
const runBrowserRuntime = {
|
|
16896
|
-
/**
|
|
16897
|
-
* Creates a dedicated session id for one tool invocation.
|
|
16898
|
-
*/
|
|
16899
|
-
createRunBrowserSessionId() {
|
|
16900
|
-
return `${runBrowserConstants.sessionPrefix}-${randomUUID()}`;
|
|
16901
|
-
},
|
|
16902
|
-
/**
|
|
16903
|
-
* Determines whether the browser tool is running in local or remote mode.
|
|
16904
|
-
*/
|
|
16905
|
-
resolveExecutionMode() {
|
|
16906
|
-
return REMOTE_BROWSER_URL && REMOTE_BROWSER_URL.trim().length > 0 ? 'remote' : 'local';
|
|
16907
|
-
},
|
|
16908
|
-
/**
|
|
16909
|
-
* Converts the execution mode into a human-readable label.
|
|
16910
|
-
*/
|
|
16911
|
-
formatExecutionMode(mode) {
|
|
16912
|
-
return mode === 'remote' ? 'remote-browser' : 'local-browser';
|
|
16913
|
-
},
|
|
16914
|
-
/**
|
|
16915
|
-
* Resolves timeout configuration from env defaults and optional call overrides.
|
|
16916
|
-
*/
|
|
16917
|
-
resolveTimeoutConfiguration(overrides) {
|
|
16918
|
-
const envNavigationTimeoutMs = resolvePositiveIntFromEnv$1('RUN_BROWSER_NAVIGATION_TIMEOUT_MS', runBrowserConstants.defaultNavigationTimeoutMs);
|
|
16919
|
-
const envActionTimeoutMs = resolvePositiveIntFromEnv$1('RUN_BROWSER_ACTION_TIMEOUT_MS', runBrowserConstants.defaultActionTimeoutMs);
|
|
16920
|
-
const navigationTimeoutMs = (overrides === null || overrides === void 0 ? void 0 : overrides.navigationMs) && Number.isFinite(overrides.navigationMs) && overrides.navigationMs > 0
|
|
16921
|
-
? Math.floor(overrides.navigationMs)
|
|
16922
|
-
: envNavigationTimeoutMs;
|
|
16923
|
-
const actionTimeoutMs = (overrides === null || overrides === void 0 ? void 0 : overrides.actionMs) && Number.isFinite(overrides.actionMs) && overrides.actionMs > 0
|
|
16924
|
-
? Math.floor(overrides.actionMs)
|
|
16925
|
-
: envActionTimeoutMs;
|
|
16926
|
-
return {
|
|
16927
|
-
navigationTimeoutMs,
|
|
16928
|
-
actionTimeoutMs,
|
|
16929
|
-
};
|
|
16930
|
-
},
|
|
16931
|
-
};
|
|
16932
|
-
|
|
16933
|
-
/**
|
|
16934
|
-
* Error classification and cancellation helpers used by `run_browser`.
|
|
16935
|
-
*
|
|
16936
|
-
* @private function of `run_browser`
|
|
16937
|
-
*/
|
|
16938
|
-
const runBrowserErrorHandling = {
|
|
16939
|
-
/**
|
|
16940
|
-
* Creates one tagged ParseError used for deterministic input validation failures.
|
|
16941
|
-
*/
|
|
16942
|
-
createRunBrowserValidationError(options) {
|
|
16943
|
-
const error = new ParseError(options.message);
|
|
16944
|
-
error.name = 'RunBrowserValidationError';
|
|
16945
|
-
error.runBrowserCode = runBrowserConstants.validationErrorCode;
|
|
16946
|
-
error.isRetryable = false;
|
|
16947
|
-
error.suggestedNextSteps = [
|
|
16948
|
-
'Fix the action payload to match the run_browser schema.',
|
|
16949
|
-
'Check selectors and required action fields before retrying.',
|
|
16950
|
-
];
|
|
16951
|
-
error.debug = options.debug;
|
|
16952
|
-
return error;
|
|
16953
|
-
},
|
|
16954
|
-
/**
|
|
16955
|
-
* Creates one tagged KnowledgeScrapeError used for navigation failures.
|
|
16956
|
-
*/
|
|
16957
|
-
createRunBrowserNavigationError(options) {
|
|
16958
|
-
const error = new KnowledgeScrapeError(options.message);
|
|
16959
|
-
error.name = 'RunBrowserNavigationError';
|
|
16960
|
-
error.runBrowserCode = runBrowserConstants.navigationFailedErrorCode;
|
|
16961
|
-
error.isRetryable = false;
|
|
16962
|
-
error.suggestedNextSteps = [
|
|
16963
|
-
'Verify the URL is reachable and not blocked.',
|
|
16964
|
-
'Retry with a simpler action sequence.',
|
|
16965
|
-
];
|
|
16966
|
-
error.debug = options.debug;
|
|
16967
|
-
error.cause = options.cause;
|
|
16968
|
-
return error;
|
|
16969
|
-
},
|
|
16970
|
-
/**
|
|
16971
|
-
* Creates one tagged KnowledgeScrapeError used for action failures.
|
|
16972
|
-
*/
|
|
16973
|
-
createRunBrowserActionError(options) {
|
|
16974
|
-
const error = new KnowledgeScrapeError(options.message);
|
|
16975
|
-
error.name = 'RunBrowserActionError';
|
|
16976
|
-
error.runBrowserCode = runBrowserConstants.actionFailedErrorCode;
|
|
16977
|
-
error.isRetryable = false;
|
|
16978
|
-
error.suggestedNextSteps = [
|
|
16979
|
-
'Verify selectors and action values.',
|
|
16980
|
-
'Reduce the action sequence to isolate the failing step.',
|
|
16981
|
-
];
|
|
16982
|
-
error.debug = options.debug;
|
|
16983
|
-
error.cause = options.cause;
|
|
16984
|
-
return error;
|
|
16985
|
-
},
|
|
16986
|
-
/**
|
|
16987
|
-
* Creates one tagged KnowledgeScrapeError used for cancellation.
|
|
16988
|
-
*/
|
|
16989
|
-
createRunBrowserCancelledError(options) {
|
|
16990
|
-
const error = new KnowledgeScrapeError(options.message);
|
|
16991
|
-
error.name = 'RunBrowserCancelledError';
|
|
16992
|
-
error.runBrowserCode = runBrowserConstants.cancelledErrorCode;
|
|
16993
|
-
error.isRetryable = true;
|
|
16994
|
-
error.suggestedNextSteps = [
|
|
16995
|
-
'Retry while request context is still active.',
|
|
16996
|
-
'Increase timeout if operation is expected to run longer.',
|
|
16997
|
-
];
|
|
16998
|
-
error.debug = options.debug;
|
|
16999
|
-
error.cause = options.cause;
|
|
17000
|
-
return error;
|
|
17001
|
-
},
|
|
17002
|
-
/**
|
|
17003
|
-
* Checks whether an unknown error carries run_browser classification tags.
|
|
17004
|
-
*/
|
|
17005
|
-
isTaggedRunBrowserError(error) {
|
|
17006
|
-
if (!error || typeof error !== 'object') {
|
|
17007
|
-
return false;
|
|
17008
|
-
}
|
|
17009
|
-
const candidate = error;
|
|
17010
|
-
return (typeof candidate.runBrowserCode === 'string' &&
|
|
17011
|
-
typeof candidate.isRetryable === 'boolean' &&
|
|
17012
|
-
Array.isArray(candidate.suggestedNextSteps) &&
|
|
17013
|
-
typeof candidate.debug === 'object' &&
|
|
17014
|
-
candidate.debug !== null);
|
|
17015
|
-
},
|
|
17016
|
-
/**
|
|
17017
|
-
* Converts unknown errors into structured tool error payloads.
|
|
17018
|
-
*/
|
|
17019
|
-
classifyRunBrowserToolError(options) {
|
|
17020
|
-
if (isRemoteBrowserUnavailableError(options.error)) {
|
|
17021
|
-
return {
|
|
17022
|
-
code: options.error.code,
|
|
17023
|
-
message: options.error.message,
|
|
17024
|
-
isRetryable: options.error.isRetryable,
|
|
17025
|
-
suggestedNextSteps: options.error.suggestedNextSteps,
|
|
17026
|
-
debug: {
|
|
17027
|
-
...options.error.debug,
|
|
17028
|
-
sessionId: options.sessionId,
|
|
17029
|
-
mode: runBrowserRuntime.formatExecutionMode(options.mode),
|
|
17030
|
-
},
|
|
17031
|
-
};
|
|
17032
|
-
}
|
|
17033
|
-
if (this.isTaggedRunBrowserError(options.error)) {
|
|
17034
|
-
return {
|
|
17035
|
-
code: options.error.runBrowserCode,
|
|
17036
|
-
message: options.error.message,
|
|
17037
|
-
isRetryable: options.error.isRetryable,
|
|
17038
|
-
suggestedNextSteps: options.error.suggestedNextSteps,
|
|
17039
|
-
debug: {
|
|
17040
|
-
...options.error.debug,
|
|
17041
|
-
sessionId: options.sessionId,
|
|
17042
|
-
mode: runBrowserRuntime.formatExecutionMode(options.mode),
|
|
17043
|
-
},
|
|
17044
|
-
};
|
|
17045
|
-
}
|
|
17046
|
-
const remoteBrowserEndpoint = REMOTE_BROWSER_URL && REMOTE_BROWSER_URL.trim().length > 0
|
|
17047
|
-
? sanitizeRemoteBrowserEndpoint(REMOTE_BROWSER_URL.trim())
|
|
17048
|
-
: null;
|
|
17049
|
-
const message = getErrorMessage(options.error);
|
|
17050
|
-
return {
|
|
17051
|
-
code: runBrowserConstants.unknownErrorCode,
|
|
17052
|
-
message,
|
|
17053
|
-
isRetryable: false,
|
|
17054
|
-
suggestedNextSteps: ['Inspect debug details to identify the failing phase.', 'Retry with fewer actions.'],
|
|
17055
|
-
debug: {
|
|
17056
|
-
sessionId: options.sessionId,
|
|
17057
|
-
mode: runBrowserRuntime.formatExecutionMode(options.mode),
|
|
17058
|
-
remoteBrowserEndpoint,
|
|
17059
|
-
message,
|
|
17060
|
-
stack: getErrorStack(options.error),
|
|
17061
|
-
},
|
|
17062
|
-
};
|
|
17063
|
-
},
|
|
17064
|
-
/**
|
|
17065
|
-
* Asserts that the run was not aborted.
|
|
17066
|
-
*/
|
|
17067
|
-
assertNotAborted(signal, sessionId) {
|
|
17068
|
-
if (!(signal === null || signal === void 0 ? void 0 : signal.aborted)) {
|
|
17069
|
-
return;
|
|
17070
|
-
}
|
|
17071
|
-
throw this.createRunBrowserCancelledError({
|
|
17072
|
-
message: 'run_browser execution was cancelled.',
|
|
17073
|
-
debug: { sessionId },
|
|
17074
|
-
});
|
|
17075
|
-
},
|
|
17076
|
-
/**
|
|
17077
|
-
* Returns true when the tool error represents remote browser unavailability.
|
|
17078
|
-
*/
|
|
17079
|
-
isRemoteBrowserUnavailableCode(code) {
|
|
17080
|
-
return code === REMOTE_BROWSER_UNAVAILABLE_ERROR_CODE;
|
|
17081
|
-
},
|
|
17082
|
-
};
|
|
17083
|
-
|
|
17084
|
-
/**
|
|
17085
|
-
* In-memory observability counters for browser tool execution.
|
|
17086
|
-
*/
|
|
17087
|
-
const RUN_BROWSER_OBSERVABILITY = {
|
|
17088
|
-
totalRuns: 0,
|
|
17089
|
-
fallbackRuns: 0,
|
|
17090
|
-
errorCodeCounts: {},
|
|
17091
|
-
};
|
|
17092
|
-
/**
|
|
17093
|
-
* Observability counters and metric logging for `run_browser`.
|
|
17094
|
-
*
|
|
17095
|
-
* @private function of `run_browser`
|
|
17096
|
-
*/
|
|
17097
|
-
const runBrowserObservability = {
|
|
17098
|
-
/**
|
|
17099
|
-
* Increments total-run counter and returns the updated value.
|
|
17100
|
-
*/
|
|
17101
|
-
incrementTotalRuns() {
|
|
17102
|
-
RUN_BROWSER_OBSERVABILITY.totalRuns++;
|
|
17103
|
-
return RUN_BROWSER_OBSERVABILITY.totalRuns;
|
|
17104
|
-
},
|
|
17105
|
-
/**
|
|
17106
|
-
* Returns current total run count.
|
|
17107
|
-
*/
|
|
17108
|
-
getTotalRuns() {
|
|
17109
|
-
return RUN_BROWSER_OBSERVABILITY.totalRuns;
|
|
17110
|
-
},
|
|
17111
|
-
/**
|
|
17112
|
-
* Increments fallback counter and returns updated metrics.
|
|
17113
|
-
*/
|
|
17114
|
-
incrementFallbackRunsAndGetMetrics() {
|
|
17115
|
-
RUN_BROWSER_OBSERVABILITY.fallbackRuns++;
|
|
17116
|
-
return {
|
|
17117
|
-
fallbackRuns: RUN_BROWSER_OBSERVABILITY.fallbackRuns,
|
|
17118
|
-
fallbackRate: RUN_BROWSER_OBSERVABILITY.totalRuns === 0
|
|
17119
|
-
? 0
|
|
17120
|
-
: RUN_BROWSER_OBSERVABILITY.fallbackRuns / RUN_BROWSER_OBSERVABILITY.totalRuns,
|
|
17121
|
-
};
|
|
17122
|
-
},
|
|
17123
|
-
/**
|
|
17124
|
-
* Increments one error-code counter and returns the updated value.
|
|
17125
|
-
*/
|
|
17126
|
-
incrementRunBrowserErrorCodeCounter(code) {
|
|
17127
|
-
const currentValue = RUN_BROWSER_OBSERVABILITY.errorCodeCounts[code] || 0;
|
|
17128
|
-
const nextValue = currentValue + 1;
|
|
17129
|
-
RUN_BROWSER_OBSERVABILITY.errorCodeCounts[code] = nextValue;
|
|
17130
|
-
return nextValue;
|
|
17131
|
-
},
|
|
17132
|
-
/**
|
|
17133
|
-
* Writes one structured metric line for browser-tool observability.
|
|
17134
|
-
*/
|
|
17135
|
-
logRunBrowserMetric(options) {
|
|
17136
|
-
console.info('[run_browser][metric]', {
|
|
17137
|
-
tool: 'run_browser',
|
|
17138
|
-
mode: options.mode,
|
|
17139
|
-
sessionId: options.sessionId,
|
|
17140
|
-
event: options.event,
|
|
17141
|
-
...(options.payload || {}),
|
|
17142
|
-
});
|
|
17143
|
-
},
|
|
17144
|
-
};
|
|
17145
|
-
|
|
17146
|
-
/**
|
|
17147
|
-
* Computes one compact preview of a fallback scrape payload.
|
|
17148
|
-
*/
|
|
17149
|
-
function createContentPreview(content) {
|
|
17150
|
-
const normalized = content.replace(/\s+/g, ' ').trim();
|
|
17151
|
-
if (normalized.length <= 280) {
|
|
17152
|
-
return normalized;
|
|
17153
|
-
}
|
|
17154
|
-
return `${normalized.slice(0, 277)}...`;
|
|
17155
|
-
}
|
|
17156
|
-
/**
|
|
17157
|
-
* Payload and markdown formatters for `run_browser` outcomes.
|
|
17158
|
-
*
|
|
17159
|
-
* @private function of `run_browser`
|
|
17160
|
-
*/
|
|
17161
|
-
const runBrowserResultFormatting = {
|
|
17162
|
-
/**
|
|
17163
|
-
* Produces one structured payload consumed by chat UI browser replay renderers.
|
|
17164
|
-
*/
|
|
17165
|
-
createResultPayload(options) {
|
|
17166
|
-
return {
|
|
17167
|
-
schema: runBrowserConstants.resultSchema,
|
|
17168
|
-
sessionId: options.sessionId,
|
|
17169
|
-
mode: options.mode,
|
|
17170
|
-
modeUsed: options.modeUsed,
|
|
17171
|
-
initialUrl: options.initialUrl,
|
|
17172
|
-
finalUrl: options.finalUrl,
|
|
17173
|
-
finalTitle: options.finalTitle,
|
|
17174
|
-
executedActions: options.executedActions,
|
|
17175
|
-
artifacts: options.artifacts,
|
|
17176
|
-
warning: options.warning,
|
|
17177
|
-
error: options.error,
|
|
17178
|
-
fallback: options.modeUsed === 'fallback' && options.fallbackContent !== null
|
|
17179
|
-
? {
|
|
17180
|
-
scraper: 'fetch_url_content',
|
|
17181
|
-
contentPreview: createContentPreview(options.fallbackContent),
|
|
17182
|
-
}
|
|
17183
|
-
: null,
|
|
17184
|
-
timing: options.timing,
|
|
17185
|
-
};
|
|
17186
|
-
},
|
|
17187
|
-
/**
|
|
17188
|
-
* Produces a model-friendly markdown summary from browser execution artifacts.
|
|
17189
|
-
*/
|
|
17190
|
-
formatSuccessResult(options) {
|
|
17191
|
-
const { payload, snapshotPath } = options;
|
|
17192
|
-
return spaceTrim$1((block) => {
|
|
17193
|
-
var _a, _b, _c;
|
|
17194
|
-
return `
|
|
17195
|
-
# Browser run completed
|
|
17196
|
-
|
|
17197
|
-
**Session:** ${payload.sessionId}
|
|
17198
|
-
**Mode requested:** ${runBrowserRuntime.formatExecutionMode(payload.mode)}
|
|
17199
|
-
**Mode used:** ${payload.modeUsed}
|
|
17200
|
-
**Initial URL:** ${payload.initialUrl}
|
|
17201
|
-
**Executed actions:** ${payload.executedActions.length}
|
|
17202
|
-
|
|
17203
|
-
## Final page
|
|
17204
|
-
|
|
17205
|
-
- URL: ${payload.finalUrl || 'Unknown'}
|
|
17206
|
-
- Title: ${payload.finalTitle || 'Unknown'}
|
|
17207
|
-
|
|
17208
|
-
## Timings
|
|
17209
|
-
|
|
17210
|
-
- Connect: ${(_a = payload.timing.connectDurationMs) !== null && _a !== void 0 ? _a : 'Unknown'} ms
|
|
17211
|
-
- Initial navigation: ${(_b = payload.timing.initialNavigationDurationMs) !== null && _b !== void 0 ? _b : 'Unknown'} ms
|
|
17212
|
-
- Time to first byte: ${(_c = payload.timing.timeToFirstByteMs) !== null && _c !== void 0 ? _c : 'Unknown'} ms
|
|
17213
|
-
- Total: ${payload.timing.totalDurationMs} ms
|
|
17214
|
-
|
|
17215
|
-
${payload.artifacts.length === 0
|
|
17216
|
-
? ''
|
|
17217
|
-
: `
|
|
17218
|
-
## Visual replay
|
|
17219
|
-
|
|
17220
|
-
${payload.artifacts
|
|
17221
|
-
.map((artifact, index) => {
|
|
17222
|
-
const actionPart = artifact.actionSummary ? ` (${artifact.actionSummary})` : '';
|
|
17223
|
-
return `- ${index + 1}. ${artifact.label}${actionPart}: ${artifact.path}`;
|
|
17224
|
-
})
|
|
17225
|
-
.join('\n')}
|
|
17226
|
-
`}
|
|
17227
|
-
|
|
17228
|
-
${!snapshotPath
|
|
17229
|
-
? ''
|
|
17230
|
-
: `
|
|
17231
|
-
## Final snapshot
|
|
17232
|
-
|
|
17233
|
-
${snapshotPath}
|
|
17234
|
-
`}
|
|
17235
|
-
|
|
17236
|
-
## Playback payload
|
|
17237
|
-
|
|
17238
|
-
\`\`\`json
|
|
17239
|
-
${JSON.stringify(payload, null, 2)}
|
|
17240
|
-
\`\`\`
|
|
17241
|
-
|
|
17242
|
-
${block(payload.executedActions.length === 0
|
|
17243
|
-
? ''
|
|
17244
|
-
: `
|
|
17245
|
-
## Action log
|
|
17246
|
-
|
|
17247
|
-
${payload.executedActions
|
|
17248
|
-
.map((action, index) => `- ${index + 1}. ${JSON.stringify(action)}`)
|
|
17249
|
-
.join('\n')}
|
|
17250
|
-
`)}
|
|
17251
|
-
|
|
17252
|
-
Note: Browser page has been automatically closed to free up resources.
|
|
17253
|
-
`;
|
|
17254
|
-
});
|
|
17255
|
-
},
|
|
17256
|
-
/**
|
|
17257
|
-
* Produces a model-friendly markdown payload when fallback scraping is used.
|
|
17258
|
-
*/
|
|
17259
|
-
formatFallbackResult(options) {
|
|
17260
|
-
const { payload, fallbackContent, requestedActions } = options;
|
|
17261
|
-
return spaceTrim$1(`
|
|
17262
|
-
# Browser run completed with fallback
|
|
17263
|
-
|
|
17264
|
-
**Session:** ${payload.sessionId}
|
|
17265
|
-
**Mode requested:** ${runBrowserRuntime.formatExecutionMode(payload.mode)}
|
|
17266
|
-
**Mode used:** ${payload.modeUsed}
|
|
17267
|
-
**Initial URL:** ${payload.initialUrl}
|
|
17268
|
-
**Requested actions:** ${requestedActions}
|
|
17269
|
-
**Executed actions:** ${payload.executedActions.length}
|
|
17270
|
-
**Warning:** ${payload.warning || runBrowserConstants.fallbackDynamicContentWarning}
|
|
17271
|
-
|
|
17272
|
-
## Extracted content
|
|
17273
|
-
|
|
17274
|
-
${fallbackContent}
|
|
17275
|
-
|
|
17276
|
-
## Playback payload
|
|
17277
|
-
|
|
17278
|
-
\`\`\`json
|
|
17279
|
-
${JSON.stringify(payload, null, 2)}
|
|
17280
|
-
\`\`\`
|
|
17281
|
-
`);
|
|
17282
|
-
},
|
|
17283
|
-
/**
|
|
17284
|
-
* Produces a model-friendly markdown error payload from browser execution failures.
|
|
17285
|
-
*/
|
|
17286
|
-
formatErrorResult(options) {
|
|
17287
|
-
const { payload } = options;
|
|
17288
|
-
const toolError = payload.error;
|
|
17289
|
-
const suggestedNextSteps = (toolError === null || toolError === void 0 ? void 0 : toolError.suggestedNextSteps) || [];
|
|
17290
|
-
return spaceTrim$1(`
|
|
17291
|
-
# Browser run failed
|
|
17292
|
-
|
|
17293
|
-
**Session:** ${payload.sessionId}
|
|
17294
|
-
**Mode requested:** ${runBrowserRuntime.formatExecutionMode(payload.mode)}
|
|
17295
|
-
**Mode used:** ${payload.modeUsed}
|
|
17296
|
-
**Initial URL:** ${payload.initialUrl}
|
|
17297
|
-
**Error code:** ${(toolError === null || toolError === void 0 ? void 0 : toolError.code) || runBrowserConstants.unknownErrorCode}
|
|
17298
|
-
**Error:** ${(toolError === null || toolError === void 0 ? void 0 : toolError.message) || 'Unknown browser tool error'}
|
|
17299
|
-
|
|
17300
|
-
${suggestedNextSteps.length === 0
|
|
17301
|
-
? ''
|
|
17302
|
-
: `
|
|
17303
|
-
## Suggested next steps
|
|
17304
|
-
|
|
17305
|
-
${suggestedNextSteps.map((step) => `- ${step}`).join('\n')}
|
|
17306
|
-
`}
|
|
17307
|
-
|
|
17308
|
-
## Playback payload
|
|
17309
|
-
|
|
17310
|
-
\`\`\`json
|
|
17311
|
-
${JSON.stringify(payload, null, 2)}
|
|
17312
|
-
\`\`\`
|
|
17313
|
-
|
|
17314
|
-
The browser tool could not complete the requested actions.
|
|
17315
|
-
`);
|
|
17316
|
-
},
|
|
17317
|
-
};
|
|
17318
|
-
|
|
17319
|
-
/**
|
|
17320
|
-
* @@@
|
|
17321
|
-
*
|
|
17322
|
-
* @private within the repository
|
|
17323
|
-
*/
|
|
17324
|
-
function locateChrome() {
|
|
17325
|
-
return locateApp({
|
|
17326
|
-
appName: 'Chrome',
|
|
17327
|
-
linuxWhich: 'google-chrome',
|
|
17328
|
-
windowsSuffix: '\\Google\\Chrome\\Application\\chrome.exe',
|
|
17329
|
-
macOsName: 'Google Chrome',
|
|
17330
|
-
});
|
|
17331
|
-
}
|
|
17332
|
-
|
|
17333
|
-
/**
|
|
17334
|
-
* Creates one standard abort error for cancelled retry loops.
|
|
17335
|
-
*
|
|
17336
|
-
* @private utility for Agents Server runtime retries
|
|
17337
|
-
*/
|
|
17338
|
-
function createAbortError$1() {
|
|
17339
|
-
const error = new Error('Operation was aborted.');
|
|
17340
|
-
error.name = 'AbortError';
|
|
17341
|
-
return error;
|
|
17342
|
-
}
|
|
17343
|
-
/**
|
|
17344
|
-
* Throws when the supplied signal is already aborted.
|
|
17345
|
-
*
|
|
17346
|
-
* @private utility for Agents Server runtime retries
|
|
17347
|
-
*/
|
|
17348
|
-
function assertNotAborted(signal) {
|
|
17349
|
-
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
17350
|
-
throw createAbortError$1();
|
|
17351
|
-
}
|
|
17352
|
-
}
|
|
17353
|
-
/**
|
|
17354
|
-
* Waits for a duration while respecting cancellation.
|
|
17355
|
-
*
|
|
17356
|
-
* @private utility for Agents Server runtime retries
|
|
17357
|
-
*/
|
|
17358
|
-
async function sleepWithAbort(delayMs, signal) {
|
|
17359
|
-
if (delayMs <= 0) {
|
|
17360
|
-
assertNotAborted(signal);
|
|
17361
|
-
return;
|
|
17362
|
-
}
|
|
17363
|
-
await new Promise((resolve, reject) => {
|
|
17364
|
-
const timeout = setTimeout(() => {
|
|
17365
|
-
signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);
|
|
17366
|
-
resolve();
|
|
17367
|
-
}, delayMs);
|
|
17368
|
-
const onAbort = () => {
|
|
17369
|
-
clearTimeout(timeout);
|
|
17370
|
-
signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);
|
|
17371
|
-
reject(createAbortError$1());
|
|
17372
|
-
};
|
|
17373
|
-
signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', onAbort, { once: true });
|
|
17374
|
-
});
|
|
17375
|
-
}
|
|
17376
|
-
/**
|
|
17377
|
-
* Resolves the retry wait duration for one failed attempt.
|
|
17378
|
-
*
|
|
17379
|
-
* @private utility for Agents Server runtime retries
|
|
17380
|
-
*/
|
|
17381
|
-
function resolveBackoffDelayMs(options) {
|
|
17382
|
-
const exponentialDelay = options.initialDelayMs * Math.pow(options.backoffFactor, Math.max(0, options.attempt - 1));
|
|
17383
|
-
const boundedDelay = Math.min(exponentialDelay, options.maxDelayMs);
|
|
17384
|
-
const jitterDelay = boundedDelay * options.jitterRatio * Math.max(0, options.random());
|
|
17385
|
-
return Math.max(0, Math.round(boundedDelay + jitterDelay));
|
|
17386
|
-
}
|
|
17387
|
-
/**
|
|
17388
|
-
* Retries one async operation with exponential backoff and jitter.
|
|
17389
|
-
*
|
|
17390
|
-
* @private utility for Agents Server runtime retries
|
|
17391
|
-
*/
|
|
17392
|
-
async function retryWithBackoff(operation, options) {
|
|
17393
|
-
var _a, _b, _c;
|
|
17394
|
-
const startedAt = Date.now();
|
|
17395
|
-
const totalAttempts = Math.max(1, options.retries + 1);
|
|
17396
|
-
const random = (_a = options.random) !== null && _a !== void 0 ? _a : Math.random;
|
|
17397
|
-
const sleep = (_b = options.sleep) !== null && _b !== void 0 ? _b : sleepWithAbort;
|
|
17398
|
-
for (let attempt = 1; attempt <= totalAttempts; attempt++) {
|
|
17399
|
-
assertNotAborted(options.signal);
|
|
17400
|
-
try {
|
|
17401
|
-
const value = await operation(attempt);
|
|
17402
|
-
return {
|
|
17403
|
-
value,
|
|
17404
|
-
attempts: attempt,
|
|
17405
|
-
durationMs: Date.now() - startedAt,
|
|
17406
|
-
};
|
|
17407
|
-
}
|
|
17408
|
-
catch (error) {
|
|
17409
|
-
const isLastAttempt = attempt >= totalAttempts;
|
|
17410
|
-
const isRetryable = options.shouldRetry ? options.shouldRetry(error, attempt) : true;
|
|
17411
|
-
if (isLastAttempt || !isRetryable) {
|
|
17412
|
-
throw error;
|
|
17413
|
-
}
|
|
17414
|
-
const delayMs = resolveBackoffDelayMs({
|
|
17415
|
-
attempt,
|
|
17416
|
-
initialDelayMs: options.initialDelayMs,
|
|
17417
|
-
maxDelayMs: options.maxDelayMs,
|
|
17418
|
-
backoffFactor: options.backoffFactor,
|
|
17419
|
-
jitterRatio: options.jitterRatio,
|
|
17420
|
-
random,
|
|
17421
|
-
});
|
|
17422
|
-
(_c = options.onRetry) === null || _c === void 0 ? void 0 : _c.call(options, {
|
|
17423
|
-
attempt,
|
|
17424
|
-
retries: options.retries,
|
|
17425
|
-
delayMs,
|
|
17426
|
-
error,
|
|
17427
|
-
});
|
|
17428
|
-
await sleep(delayMs, options.signal);
|
|
17429
|
-
}
|
|
17430
|
-
}
|
|
17431
|
-
throw new Error('Retry loop exited unexpectedly.');
|
|
17432
|
-
}
|
|
17433
|
-
|
|
17434
|
-
const DEFAULT_BROWSER_USER_DATA_DIR = join(tmpdir(), 'promptbook', 'browser', 'user-data');
|
|
17435
|
-
/**
|
|
17436
|
-
* Default remote browser connect timeout in milliseconds.
|
|
17437
|
-
*/
|
|
17438
|
-
const DEFAULT_REMOTE_CONNECT_TIMEOUT_MS = 10000;
|
|
17439
|
-
/**
|
|
17440
|
-
* Default retry count for remote browser connection establishment.
|
|
17441
|
-
*/
|
|
17442
|
-
const DEFAULT_REMOTE_CONNECT_RETRIES = 2;
|
|
17443
|
-
/**
|
|
17444
|
-
* Default initial retry delay for remote browser connection.
|
|
17445
|
-
*/
|
|
17446
|
-
const DEFAULT_REMOTE_CONNECT_BACKOFF_INITIAL_MS = 250;
|
|
17447
|
-
/**
|
|
17448
|
-
* Default maximum retry delay for remote browser connection.
|
|
17449
|
-
*/
|
|
17450
|
-
const DEFAULT_REMOTE_CONNECT_BACKOFF_MAX_MS = 1000;
|
|
17451
|
-
/**
|
|
17452
|
-
* Default exponential multiplier for remote browser retry delay.
|
|
17453
|
-
*/
|
|
17454
|
-
const DEFAULT_REMOTE_CONNECT_BACKOFF_FACTOR = 4;
|
|
17455
|
-
/**
|
|
17456
|
-
* Default retry jitter ratio for remote browser connection.
|
|
17457
|
-
*/
|
|
17458
|
-
const DEFAULT_REMOTE_CONNECT_JITTER_RATIO = 0.2;
|
|
17459
|
-
/**
|
|
17460
|
-
* In-memory metrics counters for remote browser connect attempts.
|
|
17461
|
-
*/
|
|
17462
|
-
const REMOTE_BROWSER_CONNECT_METRICS = {
|
|
17463
|
-
success: 0,
|
|
17464
|
-
failure: 0,
|
|
17465
|
-
};
|
|
17466
|
-
/**
|
|
17467
|
-
* Reads a positive integer from environment variables with a fallback default.
|
|
17468
|
-
*/
|
|
17469
|
-
function resolvePositiveIntFromEnv(variableName, defaultValue) {
|
|
17470
|
-
const rawValue = process.env[variableName];
|
|
17471
|
-
if (!rawValue || !rawValue.trim()) {
|
|
17472
|
-
return defaultValue;
|
|
17473
|
-
}
|
|
17474
|
-
const parsed = Number.parseInt(rawValue.trim(), 10);
|
|
17475
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
17476
|
-
return defaultValue;
|
|
17477
|
-
}
|
|
17478
|
-
return parsed;
|
|
17479
|
-
}
|
|
17480
|
-
/**
|
|
17481
|
-
* Reads a positive number from environment variables with a fallback default.
|
|
17482
|
-
*/
|
|
17483
|
-
function resolvePositiveNumberFromEnv(variableName, defaultValue) {
|
|
17484
|
-
const rawValue = process.env[variableName];
|
|
17485
|
-
if (!rawValue || !rawValue.trim()) {
|
|
17486
|
-
return defaultValue;
|
|
17487
|
-
}
|
|
17488
|
-
const parsed = Number.parseFloat(rawValue.trim());
|
|
17489
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
17490
|
-
return defaultValue;
|
|
17491
|
-
}
|
|
17492
|
-
return parsed;
|
|
17493
|
-
}
|
|
17494
|
-
/**
|
|
17495
|
-
* Reads a non-negative integer from environment variables with a fallback default.
|
|
17496
|
-
*/
|
|
17497
|
-
function resolveNonNegativeIntFromEnv(variableName, defaultValue) {
|
|
17498
|
-
const rawValue = process.env[variableName];
|
|
17499
|
-
if (!rawValue || !rawValue.trim()) {
|
|
17500
|
-
return defaultValue;
|
|
17501
|
-
}
|
|
17502
|
-
const parsed = Number.parseInt(rawValue.trim(), 10);
|
|
17503
|
-
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
17504
|
-
return defaultValue;
|
|
17505
|
-
}
|
|
17506
|
-
return parsed;
|
|
17507
|
-
}
|
|
17508
|
-
/**
|
|
17509
|
-
* Reads a non-negative number from environment variables with a fallback default.
|
|
17510
|
-
*/
|
|
17511
|
-
function resolveNonNegativeNumberFromEnv(variableName, defaultValue) {
|
|
17512
|
-
const rawValue = process.env[variableName];
|
|
17513
|
-
if (!rawValue || !rawValue.trim()) {
|
|
17514
|
-
return defaultValue;
|
|
17515
|
-
}
|
|
17516
|
-
const parsed = Number.parseFloat(rawValue.trim());
|
|
17517
|
-
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
17518
|
-
return defaultValue;
|
|
17519
|
-
}
|
|
17520
|
-
return parsed;
|
|
17521
|
-
}
|
|
17522
|
-
/**
|
|
17523
|
-
* Creates one standard abort error.
|
|
17524
|
-
*/
|
|
17525
|
-
function createAbortError() {
|
|
17526
|
-
const error = new Error('Browser connection request was aborted.');
|
|
17527
|
-
error.name = 'AbortError';
|
|
17528
|
-
return error;
|
|
17529
|
-
}
|
|
17530
|
-
/**
|
|
17531
|
-
* Provides browser context instances with support for both local and remote browser connections.
|
|
17532
|
-
*
|
|
17533
|
-
* This provider manages browser lifecycle and supports:
|
|
17534
|
-
* - Local mode: Launches a persistent Chromium context on the same machine
|
|
17535
|
-
* - Remote mode: Connects to a remote Playwright browser via WebSocket
|
|
17536
|
-
*
|
|
17537
|
-
* The remote mode is useful for environments like Vercel where running a full browser
|
|
17538
|
-
* is not possible due to resource constraints.
|
|
17539
|
-
*
|
|
17540
|
-
* @private internal utility for Agents Server browser tools
|
|
16328
|
+
* @private internal utility for USE BROWSER commitment
|
|
17541
16329
|
*/
|
|
17542
|
-
|
|
17543
|
-
/**
|
|
17544
|
-
* Creates a new BrowserConnectionProvider.
|
|
17545
|
-
*
|
|
17546
|
-
* @param options - Provider options
|
|
17547
|
-
* @param options.isVerbose - Enable verbose logging
|
|
17548
|
-
*/
|
|
17549
|
-
constructor(options = {}) {
|
|
17550
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
17551
|
-
this.browserContext = null;
|
|
17552
|
-
this.connectionMode = null;
|
|
17553
|
-
this.isVerbose = (_a = options.isVerbose) !== null && _a !== void 0 ? _a : false;
|
|
17554
|
-
this.remoteConnectTimeoutMs =
|
|
17555
|
-
(_b = options.remoteConnectTimeoutMs) !== null && _b !== void 0 ? _b : resolvePositiveIntFromEnv('RUN_BROWSER_CONNECT_TIMEOUT_MS', DEFAULT_REMOTE_CONNECT_TIMEOUT_MS);
|
|
17556
|
-
this.remoteConnectRetries =
|
|
17557
|
-
(_c = options.remoteConnectRetries) !== null && _c !== void 0 ? _c : resolveNonNegativeIntFromEnv('RUN_BROWSER_CONNECT_RETRIES', DEFAULT_REMOTE_CONNECT_RETRIES);
|
|
17558
|
-
this.remoteConnectBackoffInitialMs =
|
|
17559
|
-
(_d = options.remoteConnectBackoffInitialMs) !== null && _d !== void 0 ? _d : resolvePositiveIntFromEnv('RUN_BROWSER_CONNECT_BACKOFF_INITIAL_MS', DEFAULT_REMOTE_CONNECT_BACKOFF_INITIAL_MS);
|
|
17560
|
-
this.remoteConnectBackoffMaxMs =
|
|
17561
|
-
(_e = options.remoteConnectBackoffMaxMs) !== null && _e !== void 0 ? _e : resolvePositiveIntFromEnv('RUN_BROWSER_CONNECT_BACKOFF_MAX_MS', DEFAULT_REMOTE_CONNECT_BACKOFF_MAX_MS);
|
|
17562
|
-
this.remoteConnectBackoffFactor =
|
|
17563
|
-
(_f = options.remoteConnectBackoffFactor) !== null && _f !== void 0 ? _f : resolvePositiveNumberFromEnv('RUN_BROWSER_CONNECT_BACKOFF_FACTOR', DEFAULT_REMOTE_CONNECT_BACKOFF_FACTOR);
|
|
17564
|
-
this.remoteConnectJitterRatio =
|
|
17565
|
-
(_g = options.remoteConnectJitterRatio) !== null && _g !== void 0 ? _g : resolveNonNegativeNumberFromEnv('RUN_BROWSER_CONNECT_JITTER_RATIO', DEFAULT_REMOTE_CONNECT_JITTER_RATIO);
|
|
17566
|
-
this.random = (_h = options.random) !== null && _h !== void 0 ? _h : Math.random;
|
|
17567
|
-
this.sleep = options.sleep;
|
|
17568
|
-
}
|
|
17569
|
-
/**
|
|
17570
|
-
* Gets a browser context, creating a new one if needed.
|
|
17571
|
-
*
|
|
17572
|
-
* This method automatically determines whether to use local or remote browser
|
|
17573
|
-
* based on the REMOTE_BROWSER_URL environment variable.
|
|
17574
|
-
*
|
|
17575
|
-
* @returns Browser context instance
|
|
17576
|
-
*/
|
|
17577
|
-
async getBrowserContext(options = {}) {
|
|
17578
|
-
var _a;
|
|
17579
|
-
if ((_a = options.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
|
|
17580
|
-
throw createAbortError();
|
|
17581
|
-
}
|
|
17582
|
-
// Check if we have a cached connection that's still valid
|
|
17583
|
-
if (this.browserContext !== null && this.isBrowserContextAlive(this.browserContext)) {
|
|
17584
|
-
return this.browserContext;
|
|
17585
|
-
}
|
|
17586
|
-
// Determine connection mode from configuration
|
|
17587
|
-
const mode = this.resolveConnectionMode();
|
|
17588
|
-
this.connectionMode = mode;
|
|
17589
|
-
if (this.isVerbose) {
|
|
17590
|
-
console.info('[BrowserConnectionProvider] Creating new browser context', {
|
|
17591
|
-
mode: mode.type,
|
|
17592
|
-
wsEndpoint: mode.type === 'remote' ? mode.wsEndpoint : undefined,
|
|
17593
|
-
});
|
|
17594
|
-
}
|
|
17595
|
-
// Create new browser context based on mode
|
|
17596
|
-
if (mode.type === 'local') {
|
|
17597
|
-
this.browserContext = await this.createLocalBrowserContext();
|
|
17598
|
-
}
|
|
17599
|
-
else {
|
|
17600
|
-
this.browserContext = await this.createRemoteBrowserContext(mode.wsEndpoint, options);
|
|
17601
|
-
}
|
|
17602
|
-
return this.browserContext;
|
|
17603
|
-
}
|
|
17604
|
-
/**
|
|
17605
|
-
* Closes all pages in the current browser context.
|
|
17606
|
-
*
|
|
17607
|
-
* This method is useful for cleanup between agent tasks without closing
|
|
17608
|
-
* the entire browser instance.
|
|
17609
|
-
*/
|
|
17610
|
-
async closeAllPages() {
|
|
17611
|
-
if (!this.browserContext) {
|
|
17612
|
-
return;
|
|
17613
|
-
}
|
|
17614
|
-
try {
|
|
17615
|
-
const pages = this.browserContext.pages();
|
|
17616
|
-
if (this.isVerbose) {
|
|
17617
|
-
console.info('[BrowserConnectionProvider] Closing all pages', {
|
|
17618
|
-
pageCount: pages.length,
|
|
17619
|
-
});
|
|
17620
|
-
}
|
|
17621
|
-
await Promise.all(pages.map((page) => page.close().catch((error) => {
|
|
17622
|
-
console.error('[BrowserConnectionProvider] Failed to close page', { error });
|
|
17623
|
-
})));
|
|
17624
|
-
}
|
|
17625
|
-
catch (error) {
|
|
17626
|
-
console.error('[BrowserConnectionProvider] Error closing pages', { error });
|
|
17627
|
-
}
|
|
17628
|
-
}
|
|
17629
|
-
/**
|
|
17630
|
-
* Closes the browser context and disconnects from the browser.
|
|
17631
|
-
*
|
|
17632
|
-
* This should be called when the browser is no longer needed to free up resources.
|
|
17633
|
-
* For local mode, this closes the browser process. For remote mode, it disconnects
|
|
17634
|
-
* from the remote browser but doesn't shut down the remote server.
|
|
17635
|
-
*/
|
|
17636
|
-
async close() {
|
|
17637
|
-
var _a;
|
|
17638
|
-
if (!this.browserContext) {
|
|
17639
|
-
return;
|
|
17640
|
-
}
|
|
17641
|
-
try {
|
|
17642
|
-
if (this.isVerbose) {
|
|
17643
|
-
console.info('[BrowserConnectionProvider] Closing browser context', {
|
|
17644
|
-
mode: (_a = this.connectionMode) === null || _a === void 0 ? void 0 : _a.type,
|
|
17645
|
-
});
|
|
17646
|
-
}
|
|
17647
|
-
await this.browserContext.close();
|
|
17648
|
-
this.browserContext = null;
|
|
17649
|
-
this.connectionMode = null;
|
|
17650
|
-
}
|
|
17651
|
-
catch (error) {
|
|
17652
|
-
console.error('[BrowserConnectionProvider] Error closing browser context', { error });
|
|
17653
|
-
// Reset state even if close fails
|
|
17654
|
-
this.browserContext = null;
|
|
17655
|
-
this.connectionMode = null;
|
|
17656
|
-
}
|
|
17657
|
-
}
|
|
17658
|
-
/**
|
|
17659
|
-
* Checks if a browser context is still alive and connected.
|
|
17660
|
-
*
|
|
17661
|
-
* @param context - Browser context to check
|
|
17662
|
-
* @returns True if the context is connected and usable
|
|
17663
|
-
*/
|
|
17664
|
-
isBrowserContextAlive(context) {
|
|
17665
|
-
try {
|
|
17666
|
-
const browser = context.browser();
|
|
17667
|
-
return browser !== null && browser.isConnected();
|
|
17668
|
-
}
|
|
17669
|
-
catch (_a) {
|
|
17670
|
-
return false;
|
|
17671
|
-
}
|
|
17672
|
-
}
|
|
17673
|
-
/**
|
|
17674
|
-
* Determines whether to use local or remote browser based on configuration.
|
|
17675
|
-
*
|
|
17676
|
-
* @returns Connection mode configuration
|
|
17677
|
-
*/
|
|
17678
|
-
resolveConnectionMode() {
|
|
17679
|
-
const remoteBrowserUrl = REMOTE_BROWSER_URL;
|
|
17680
|
-
if (remoteBrowserUrl && remoteBrowserUrl.trim().length > 0) {
|
|
17681
|
-
return {
|
|
17682
|
-
type: 'remote',
|
|
17683
|
-
wsEndpoint: remoteBrowserUrl.trim(),
|
|
17684
|
-
};
|
|
17685
|
-
}
|
|
17686
|
-
return { type: 'local' };
|
|
17687
|
-
}
|
|
17688
|
-
/**
|
|
17689
|
-
* Creates a local browser context using persistent Chromium.
|
|
17690
|
-
*
|
|
17691
|
-
* @returns Local browser context
|
|
17692
|
-
*/
|
|
17693
|
-
async createLocalBrowserContext() {
|
|
17694
|
-
if (this.isVerbose) {
|
|
17695
|
-
console.info('[BrowserConnectionProvider] Launching local browser context');
|
|
17696
|
-
}
|
|
17697
|
-
const userDataDir = join(DEFAULT_BROWSER_USER_DATA_DIR, 'run-browser');
|
|
17698
|
-
await mkdir(userDataDir, { recursive: true });
|
|
17699
|
-
const launchOptions = {
|
|
17700
|
-
headless: false,
|
|
17701
|
-
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],
|
|
17702
|
-
};
|
|
17703
|
-
try {
|
|
17704
|
-
const chromePath = await locateChrome();
|
|
17705
|
-
launchOptions.executablePath = chromePath;
|
|
17706
|
-
}
|
|
17707
|
-
catch (error) {
|
|
17708
|
-
if (this.isVerbose) {
|
|
17709
|
-
console.warn('[BrowserConnectionProvider] Could not locate system Chrome; using Playwright bundled Chromium', {
|
|
17710
|
-
error: error instanceof Error ? error.message : String(error),
|
|
17711
|
-
});
|
|
17712
|
-
}
|
|
17713
|
-
}
|
|
17714
|
-
return await chromium.launchPersistentContext(userDataDir, launchOptions);
|
|
17715
|
-
}
|
|
17716
|
-
/**
|
|
17717
|
-
* Creates a remote browser context by connecting to a Playwright server.
|
|
17718
|
-
*
|
|
17719
|
-
* @param wsEndpoint - WebSocket endpoint of the remote Playwright server
|
|
17720
|
-
* @returns Remote browser context
|
|
17721
|
-
*/
|
|
17722
|
-
async createRemoteBrowserContext(wsEndpoint, options) {
|
|
17723
|
-
const endpointDebug = sanitizeRemoteBrowserEndpoint(wsEndpoint);
|
|
17724
|
-
const startedAt = Date.now();
|
|
17725
|
-
if (this.isVerbose) {
|
|
17726
|
-
console.info('[BrowserConnectionProvider] Connecting to remote browser', {
|
|
17727
|
-
endpoint: endpointDebug,
|
|
17728
|
-
connectTimeoutMs: this.remoteConnectTimeoutMs,
|
|
17729
|
-
retries: this.remoteConnectRetries,
|
|
17730
|
-
});
|
|
17731
|
-
}
|
|
17732
|
-
let attempts = 0;
|
|
17733
|
-
try {
|
|
17734
|
-
const connectResult = await retryWithBackoff(async (attempt) => {
|
|
17735
|
-
attempts = attempt;
|
|
17736
|
-
return await chromium.connect(wsEndpoint, {
|
|
17737
|
-
timeout: this.remoteConnectTimeoutMs,
|
|
17738
|
-
});
|
|
17739
|
-
}, {
|
|
17740
|
-
retries: this.remoteConnectRetries,
|
|
17741
|
-
initialDelayMs: this.remoteConnectBackoffInitialMs,
|
|
17742
|
-
maxDelayMs: this.remoteConnectBackoffMaxMs,
|
|
17743
|
-
backoffFactor: this.remoteConnectBackoffFactor,
|
|
17744
|
-
jitterRatio: this.remoteConnectJitterRatio,
|
|
17745
|
-
signal: options.signal,
|
|
17746
|
-
shouldRetry: (error) => isRemoteBrowserInfrastructureError(error),
|
|
17747
|
-
onRetry: ({ attempt, delayMs, error }) => {
|
|
17748
|
-
console.warn('[run_browser][retry]', {
|
|
17749
|
-
tool: 'run_browser',
|
|
17750
|
-
mode: 'remote-browser',
|
|
17751
|
-
sessionId: options.sessionId || null,
|
|
17752
|
-
event: 'remote_browser_connect_retry',
|
|
17753
|
-
attempt,
|
|
17754
|
-
delayMs,
|
|
17755
|
-
endpoint: endpointDebug,
|
|
17756
|
-
errorCode: extractNetworkErrorCode(error),
|
|
17757
|
-
error: getErrorMessage(error),
|
|
17758
|
-
});
|
|
17759
|
-
},
|
|
17760
|
-
random: this.random,
|
|
17761
|
-
sleep: this.sleep,
|
|
17762
|
-
});
|
|
17763
|
-
const browser = connectResult.value;
|
|
17764
|
-
// For remote connections, we need to create a new context
|
|
17765
|
-
// Note: Remote browsers don't support persistent contexts
|
|
17766
|
-
const context = await browser.newContext();
|
|
17767
|
-
REMOTE_BROWSER_CONNECT_METRICS.success++;
|
|
17768
|
-
console.info('[run_browser][metric]', {
|
|
17769
|
-
tool: 'run_browser',
|
|
17770
|
-
mode: 'remote-browser',
|
|
17771
|
-
sessionId: options.sessionId || null,
|
|
17772
|
-
event: 'remote_browser_connect_success',
|
|
17773
|
-
attempts: connectResult.attempts,
|
|
17774
|
-
connectDurationMs: connectResult.durationMs,
|
|
17775
|
-
endpoint: endpointDebug,
|
|
17776
|
-
counter: REMOTE_BROWSER_CONNECT_METRICS.success,
|
|
17777
|
-
});
|
|
17778
|
-
if (this.isVerbose) {
|
|
17779
|
-
console.info('[BrowserConnectionProvider] Successfully connected to remote browser');
|
|
17780
|
-
}
|
|
17781
|
-
return context;
|
|
17782
|
-
}
|
|
17783
|
-
catch (error) {
|
|
17784
|
-
REMOTE_BROWSER_CONNECT_METRICS.failure++;
|
|
17785
|
-
const durationMs = Date.now() - startedAt;
|
|
17786
|
-
const remoteInfraUnavailable = isRemoteBrowserInfrastructureError(error);
|
|
17787
|
-
if (remoteInfraUnavailable) {
|
|
17788
|
-
const remoteBrowserUnavailableError = new RemoteBrowserUnavailableError({
|
|
17789
|
-
message: `Remote browser is unavailable. Could not establish a websocket connection.`,
|
|
17790
|
-
debug: {
|
|
17791
|
-
endpoint: endpointDebug,
|
|
17792
|
-
attempts: Math.max(1, attempts),
|
|
17793
|
-
connectTimeoutMs: this.remoteConnectTimeoutMs,
|
|
17794
|
-
durationMs,
|
|
17795
|
-
networkErrorCode: extractNetworkErrorCode(error),
|
|
17796
|
-
originalMessage: getErrorMessage(error),
|
|
17797
|
-
},
|
|
17798
|
-
cause: error,
|
|
17799
|
-
});
|
|
17800
|
-
console.warn('[run_browser][metric]', {
|
|
17801
|
-
tool: 'run_browser',
|
|
17802
|
-
mode: 'remote-browser',
|
|
17803
|
-
sessionId: options.sessionId || null,
|
|
17804
|
-
event: 'remote_browser_connect_failure',
|
|
17805
|
-
errorCode: remoteBrowserUnavailableError.code,
|
|
17806
|
-
attempts: Math.max(1, attempts),
|
|
17807
|
-
connectDurationMs: durationMs,
|
|
17808
|
-
endpoint: endpointDebug,
|
|
17809
|
-
counter: REMOTE_BROWSER_CONNECT_METRICS.failure,
|
|
17810
|
-
});
|
|
17811
|
-
throw remoteBrowserUnavailableError;
|
|
17812
|
-
}
|
|
17813
|
-
console.error('[run_browser][metric]', {
|
|
17814
|
-
tool: 'run_browser',
|
|
17815
|
-
mode: 'remote-browser',
|
|
17816
|
-
sessionId: options.sessionId || null,
|
|
17817
|
-
event: 'remote_browser_connect_failure',
|
|
17818
|
-
errorCode: 'REMOTE_BROWSER_CONNECT_ERROR',
|
|
17819
|
-
attempts: Math.max(1, attempts),
|
|
17820
|
-
connectDurationMs: durationMs,
|
|
17821
|
-
endpoint: endpointDebug,
|
|
17822
|
-
error: getErrorMessage(error),
|
|
17823
|
-
counter: REMOTE_BROWSER_CONNECT_METRICS.failure,
|
|
17824
|
-
});
|
|
17825
|
-
throw error;
|
|
17826
|
-
}
|
|
17827
|
-
}
|
|
17828
|
-
}
|
|
17829
|
-
|
|
16330
|
+
let cachedRunBrowserTool = null;
|
|
17830
16331
|
/**
|
|
17831
|
-
*
|
|
16332
|
+
* Cached loading error to avoid repeating expensive resolution attempts.
|
|
17832
16333
|
*
|
|
17833
|
-
* @private internal
|
|
16334
|
+
* @private internal utility for USE BROWSER commitment
|
|
17834
16335
|
*/
|
|
17835
|
-
let
|
|
16336
|
+
let cachedRunBrowserToolError = null;
|
|
17836
16337
|
/**
|
|
17837
|
-
*
|
|
17838
|
-
*
|
|
17839
|
-
* This function supports both local and remote browser connections based on environment configuration.
|
|
17840
|
-
* Use REMOTE_BROWSER_URL environment variable to configure a remote Playwright server.
|
|
16338
|
+
* Attempts to load the server-side `run_browser` tool lazily.
|
|
17841
16339
|
*
|
|
17842
|
-
* @
|
|
17843
|
-
* @
|
|
16340
|
+
* @returns Loaded `run_browser` implementation
|
|
16341
|
+
* @private internal utility for USE BROWSER commitment
|
|
17844
16342
|
*/
|
|
17845
|
-
|
|
17846
|
-
if (
|
|
17847
|
-
|
|
16343
|
+
function loadRunBrowserToolForNode() {
|
|
16344
|
+
if (cachedRunBrowserTool !== null) {
|
|
16345
|
+
return cachedRunBrowserTool;
|
|
17848
16346
|
}
|
|
17849
|
-
|
|
17850
|
-
|
|
17851
|
-
/**
|
|
17852
|
-
* TODO: [🏓] Unite `xxxForServer` and `xxxForNode` naming
|
|
17853
|
-
*/
|
|
17854
|
-
|
|
17855
|
-
/**
|
|
17856
|
-
* Attempts to compute time-to-first-byte from Playwright response timing.
|
|
17857
|
-
*/
|
|
17858
|
-
function resolveTimeToFirstByteMs(response) {
|
|
17859
|
-
if (!response) {
|
|
17860
|
-
return null;
|
|
16347
|
+
if (cachedRunBrowserToolError !== null) {
|
|
16348
|
+
throw cachedRunBrowserToolError;
|
|
17861
16349
|
}
|
|
17862
16350
|
try {
|
|
17863
|
-
|
|
17864
|
-
|
|
17865
|
-
|
|
17866
|
-
|
|
17867
|
-
return Math.round(timing.responseStart - timing.startTime);
|
|
17868
|
-
}
|
|
17869
|
-
}
|
|
17870
|
-
catch (_a) {
|
|
17871
|
-
return null;
|
|
17872
|
-
}
|
|
17873
|
-
return null;
|
|
17874
|
-
}
|
|
17875
|
-
/**
|
|
17876
|
-
* Page open, action normalization and action execution helpers for `run_browser`.
|
|
17877
|
-
*
|
|
17878
|
-
* @private function of `run_browser`
|
|
17879
|
-
*/
|
|
17880
|
-
const runBrowserWorkflow = {
|
|
17881
|
-
/**
|
|
17882
|
-
* Opens a new browser page and navigates to the requested URL.
|
|
17883
|
-
*/
|
|
17884
|
-
async openPageWithUrl(options) {
|
|
17885
|
-
runBrowserErrorHandling.assertNotAborted(options.signal, options.sessionId);
|
|
17886
|
-
const connectStartedAt = Date.now();
|
|
17887
|
-
const browserContext = await $provideBrowserForServer({
|
|
17888
|
-
signal: options.signal,
|
|
17889
|
-
sessionId: options.sessionId,
|
|
17890
|
-
});
|
|
17891
|
-
const connectDurationMs = Date.now() - connectStartedAt;
|
|
17892
|
-
const page = await browserContext.newPage();
|
|
17893
|
-
page.setDefaultNavigationTimeout(options.timeouts.navigationTimeoutMs);
|
|
17894
|
-
page.setDefaultTimeout(options.timeouts.actionTimeoutMs);
|
|
17895
|
-
const navigationStartedAt = Date.now();
|
|
17896
|
-
try {
|
|
17897
|
-
const navigationResponse = await page.goto(options.url, {
|
|
17898
|
-
waitUntil: 'domcontentloaded',
|
|
17899
|
-
timeout: options.timeouts.navigationTimeoutMs,
|
|
17900
|
-
});
|
|
17901
|
-
return {
|
|
17902
|
-
page,
|
|
17903
|
-
connectDurationMs,
|
|
17904
|
-
initialNavigationDurationMs: Date.now() - navigationStartedAt,
|
|
17905
|
-
timeToFirstByteMs: resolveTimeToFirstByteMs(navigationResponse),
|
|
17906
|
-
};
|
|
17907
|
-
}
|
|
17908
|
-
catch (error) {
|
|
17909
|
-
throw runBrowserErrorHandling.createRunBrowserNavigationError({
|
|
17910
|
-
message: `Failed to navigate to \`${options.url}\`.`,
|
|
17911
|
-
debug: {
|
|
17912
|
-
phase: 'initial-navigation',
|
|
17913
|
-
url: options.url,
|
|
17914
|
-
navigationTimeoutMs: options.timeouts.navigationTimeoutMs,
|
|
17915
|
-
},
|
|
17916
|
-
cause: error,
|
|
17917
|
-
});
|
|
17918
|
-
}
|
|
17919
|
-
},
|
|
17920
|
-
/**
|
|
17921
|
-
* Validates and normalizes browser actions received from the model.
|
|
17922
|
-
*/
|
|
17923
|
-
normalizeActions(actions) {
|
|
17924
|
-
if (!actions || actions.length === 0) {
|
|
17925
|
-
return [];
|
|
17926
|
-
}
|
|
17927
|
-
return actions.map((action, index) => this.normalizeAction(action, index));
|
|
17928
|
-
},
|
|
17929
|
-
/**
|
|
17930
|
-
* Validates and normalizes a single action.
|
|
17931
|
-
*/
|
|
17932
|
-
normalizeAction(action, index) {
|
|
17933
|
-
var _a, _b, _c;
|
|
17934
|
-
switch (action.type) {
|
|
17935
|
-
case 'navigate': {
|
|
17936
|
-
const url = String(action.value || '').trim();
|
|
17937
|
-
if (!url) {
|
|
17938
|
-
throw runBrowserErrorHandling.createRunBrowserValidationError({
|
|
17939
|
-
message: spaceTrim$1(`Action ${index + 1}: \`navigate\` requires non-empty \`value\` URL.`),
|
|
17940
|
-
debug: {
|
|
17941
|
-
actionIndex: index + 1,
|
|
17942
|
-
actionType: action.type,
|
|
17943
|
-
},
|
|
17944
|
-
});
|
|
17945
|
-
}
|
|
17946
|
-
return { type: 'navigate', url };
|
|
17947
|
-
}
|
|
17948
|
-
case 'click': {
|
|
17949
|
-
const selector = String(action.selector || '').trim();
|
|
17950
|
-
if (!selector) {
|
|
17951
|
-
throw runBrowserErrorHandling.createRunBrowserValidationError({
|
|
17952
|
-
message: spaceTrim$1(`Action ${index + 1}: \`click\` requires non-empty \`selector\`.`),
|
|
17953
|
-
debug: {
|
|
17954
|
-
actionIndex: index + 1,
|
|
17955
|
-
actionType: action.type,
|
|
17956
|
-
},
|
|
17957
|
-
});
|
|
17958
|
-
}
|
|
17959
|
-
return { type: 'click', selector };
|
|
17960
|
-
}
|
|
17961
|
-
case 'type': {
|
|
17962
|
-
const selector = String(action.selector || '').trim();
|
|
17963
|
-
if (!selector) {
|
|
17964
|
-
throw runBrowserErrorHandling.createRunBrowserValidationError({
|
|
17965
|
-
message: spaceTrim$1(`Action ${index + 1}: \`type\` requires non-empty \`selector\`.`),
|
|
17966
|
-
debug: {
|
|
17967
|
-
actionIndex: index + 1,
|
|
17968
|
-
actionType: action.type,
|
|
17969
|
-
},
|
|
17970
|
-
});
|
|
17971
|
-
}
|
|
17972
|
-
const text = String((_a = action.value) !== null && _a !== void 0 ? _a : '');
|
|
17973
|
-
return { type: 'type', selector, text };
|
|
17974
|
-
}
|
|
17975
|
-
case 'wait': {
|
|
17976
|
-
const requestedValue = Number.parseInt(String((_b = action.value) !== null && _b !== void 0 ? _b : runBrowserConstants.defaultWaitMs), 10);
|
|
17977
|
-
const milliseconds = Number.isFinite(requestedValue)
|
|
17978
|
-
? Math.min(Math.max(requestedValue, 1), runBrowserConstants.maxWaitMs)
|
|
17979
|
-
: runBrowserConstants.defaultWaitMs;
|
|
17980
|
-
return { type: 'wait', milliseconds };
|
|
17981
|
-
}
|
|
17982
|
-
case 'scroll': {
|
|
17983
|
-
const requestedValue = Number.parseInt(String((_c = action.value) !== null && _c !== void 0 ? _c : runBrowserConstants.defaultScrollPixels), 10);
|
|
17984
|
-
const pixels = Number.isFinite(requestedValue) ? requestedValue : runBrowserConstants.defaultScrollPixels;
|
|
17985
|
-
const rawSelector = String(action.selector || '').trim();
|
|
17986
|
-
return { type: 'scroll', selector: rawSelector || null, pixels };
|
|
17987
|
-
}
|
|
17988
|
-
}
|
|
17989
|
-
},
|
|
17990
|
-
/**
|
|
17991
|
-
* Executes one normalized browser action on a Playwright page.
|
|
17992
|
-
*/
|
|
17993
|
-
async executeAction(options) {
|
|
17994
|
-
const { page, action, actionIndex, timeouts, signal } = options;
|
|
17995
|
-
runBrowserErrorHandling.assertNotAborted(signal, `action-${actionIndex}`);
|
|
17996
|
-
try {
|
|
17997
|
-
switch (action.type) {
|
|
17998
|
-
case 'navigate':
|
|
17999
|
-
await page.goto(action.url, {
|
|
18000
|
-
waitUntil: 'domcontentloaded',
|
|
18001
|
-
timeout: timeouts.navigationTimeoutMs,
|
|
18002
|
-
});
|
|
18003
|
-
return;
|
|
18004
|
-
case 'click':
|
|
18005
|
-
await page.locator(action.selector).first().click({ timeout: timeouts.actionTimeoutMs });
|
|
18006
|
-
return;
|
|
18007
|
-
case 'type':
|
|
18008
|
-
await page.locator(action.selector).first().fill(action.text, { timeout: timeouts.actionTimeoutMs });
|
|
18009
|
-
return;
|
|
18010
|
-
case 'wait':
|
|
18011
|
-
if (action.milliseconds > timeouts.actionTimeoutMs) {
|
|
18012
|
-
throw runBrowserErrorHandling.createRunBrowserActionError({
|
|
18013
|
-
message: `Action ${actionIndex}: \`wait\` exceeds action timeout (${timeouts.actionTimeoutMs}ms).`,
|
|
18014
|
-
debug: {
|
|
18015
|
-
actionIndex,
|
|
18016
|
-
action,
|
|
18017
|
-
actionTimeoutMs: timeouts.actionTimeoutMs,
|
|
18018
|
-
},
|
|
18019
|
-
});
|
|
18020
|
-
}
|
|
18021
|
-
await page.waitForTimeout(action.milliseconds);
|
|
18022
|
-
return;
|
|
18023
|
-
case 'scroll':
|
|
18024
|
-
if (action.selector) {
|
|
18025
|
-
await page
|
|
18026
|
-
.locator(action.selector)
|
|
18027
|
-
.first()
|
|
18028
|
-
.scrollIntoViewIfNeeded({ timeout: timeouts.actionTimeoutMs });
|
|
18029
|
-
}
|
|
18030
|
-
await page.mouse.wheel(0, action.pixels);
|
|
18031
|
-
return;
|
|
18032
|
-
}
|
|
18033
|
-
}
|
|
18034
|
-
catch (error) {
|
|
18035
|
-
if (runBrowserErrorHandling.isTaggedRunBrowserError(error)) {
|
|
18036
|
-
throw error;
|
|
18037
|
-
}
|
|
18038
|
-
if (action.type === 'navigate') {
|
|
18039
|
-
throw runBrowserErrorHandling.createRunBrowserNavigationError({
|
|
18040
|
-
message: `Action ${actionIndex}: failed to navigate to \`${action.url}\`.`,
|
|
18041
|
-
debug: {
|
|
18042
|
-
actionIndex,
|
|
18043
|
-
action,
|
|
18044
|
-
navigationTimeoutMs: timeouts.navigationTimeoutMs,
|
|
18045
|
-
},
|
|
18046
|
-
cause: error,
|
|
18047
|
-
});
|
|
18048
|
-
}
|
|
18049
|
-
throw runBrowserErrorHandling.createRunBrowserActionError({
|
|
18050
|
-
message: `Action ${actionIndex}: failed to execute \`${action.type}\`.`,
|
|
18051
|
-
debug: {
|
|
18052
|
-
actionIndex,
|
|
18053
|
-
action,
|
|
18054
|
-
actionTimeoutMs: timeouts.actionTimeoutMs,
|
|
18055
|
-
},
|
|
18056
|
-
cause: error,
|
|
18057
|
-
});
|
|
18058
|
-
}
|
|
18059
|
-
},
|
|
18060
|
-
};
|
|
18061
|
-
|
|
18062
|
-
/**
|
|
18063
|
-
* Summarizes one normalized browser action in user-facing language.
|
|
18064
|
-
*/
|
|
18065
|
-
function formatRunBrowserActionSummary(action) {
|
|
18066
|
-
switch (action.type) {
|
|
18067
|
-
case 'navigate':
|
|
18068
|
-
return `Navigate to ${action.url}`;
|
|
18069
|
-
case 'click':
|
|
18070
|
-
return `Click ${action.selector}`;
|
|
18071
|
-
case 'type':
|
|
18072
|
-
return `Type into ${action.selector}`;
|
|
18073
|
-
case 'wait':
|
|
18074
|
-
return `Wait ${action.milliseconds}ms`;
|
|
18075
|
-
case 'scroll':
|
|
18076
|
-
return action.selector ? `Scroll ${action.pixels}px in ${action.selector}` : `Scroll ${action.pixels}px on page`;
|
|
18077
|
-
}
|
|
18078
|
-
}
|
|
18079
|
-
/**
|
|
18080
|
-
* Emits one incremental browser-tool update when a hidden chat-progress listener is attached.
|
|
18081
|
-
*/
|
|
18082
|
-
function emitRunBrowserProgress(args, update) {
|
|
18083
|
-
emitToolCallProgressFromToolArgs(args, update);
|
|
18084
|
-
}
|
|
18085
|
-
/**
|
|
18086
|
-
* Returns the current timestamp in the branded ISO-8601 format used by tool-call logs.
|
|
18087
|
-
*/
|
|
18088
|
-
function createRunBrowserLogTimestamp() {
|
|
18089
|
-
return new Date().toISOString();
|
|
18090
|
-
}
|
|
18091
|
-
/**
|
|
18092
|
-
* Executes non-graphical fallback scraping.
|
|
18093
|
-
*/
|
|
18094
|
-
async function runFallbackScrape(url) {
|
|
18095
|
-
return await fetchUrlContent(url);
|
|
18096
|
-
}
|
|
18097
|
-
/**
|
|
18098
|
-
* Runs interactive browser automation through Playwright.
|
|
18099
|
-
*
|
|
18100
|
-
* @param args Tool arguments provided by the model.
|
|
18101
|
-
* @param internalOptions Optional runtime options for cancellation.
|
|
18102
|
-
* @returns Markdown summary with structured playback payload.
|
|
18103
|
-
*/
|
|
18104
|
-
async function run_browser(args, internalOptions = {}) {
|
|
18105
|
-
runBrowserObservability.incrementTotalRuns();
|
|
18106
|
-
const startedAt = Date.now();
|
|
18107
|
-
const sessionId = runBrowserRuntime.createRunBrowserSessionId();
|
|
18108
|
-
const initialUrl = String(args.url || '').trim();
|
|
18109
|
-
const mode = runBrowserRuntime.resolveExecutionMode();
|
|
18110
|
-
const timeoutConfiguration = runBrowserRuntime.resolveTimeoutConfiguration(args.timeouts);
|
|
18111
|
-
let page = null;
|
|
18112
|
-
let connectDurationMs = null;
|
|
18113
|
-
let initialNavigationDurationMs = null;
|
|
18114
|
-
let timeToFirstByteMs = null;
|
|
18115
|
-
try {
|
|
18116
|
-
if (!initialUrl) {
|
|
18117
|
-
throw runBrowserErrorHandling.createRunBrowserValidationError({
|
|
18118
|
-
message: 'Missing required `url` argument.',
|
|
18119
|
-
debug: {
|
|
18120
|
-
field: 'url',
|
|
18121
|
-
},
|
|
18122
|
-
});
|
|
18123
|
-
}
|
|
18124
|
-
const normalizedActions = runBrowserWorkflow.normalizeActions(args.actions);
|
|
18125
|
-
runBrowserErrorHandling.assertNotAborted(internalOptions.signal, sessionId);
|
|
18126
|
-
const openedPage = await runBrowserWorkflow.openPageWithUrl({
|
|
18127
|
-
url: initialUrl,
|
|
18128
|
-
sessionId,
|
|
18129
|
-
timeouts: timeoutConfiguration,
|
|
18130
|
-
signal: internalOptions.signal,
|
|
18131
|
-
});
|
|
18132
|
-
page = openedPage.page;
|
|
18133
|
-
connectDurationMs = openedPage.connectDurationMs;
|
|
18134
|
-
initialNavigationDurationMs = openedPage.initialNavigationDurationMs;
|
|
18135
|
-
timeToFirstByteMs = openedPage.timeToFirstByteMs;
|
|
18136
|
-
emitRunBrowserProgress(args, {
|
|
18137
|
-
state: 'PARTIAL',
|
|
18138
|
-
log: {
|
|
18139
|
-
createdAt: createRunBrowserLogTimestamp(),
|
|
18140
|
-
kind: 'browser-session',
|
|
18141
|
-
title: 'Browser ready',
|
|
18142
|
-
message: 'Opened the initial page and started the browser session.',
|
|
18143
|
-
payload: {
|
|
18144
|
-
sessionId,
|
|
18145
|
-
initialUrl,
|
|
18146
|
-
connectDurationMs,
|
|
18147
|
-
initialNavigationDurationMs,
|
|
18148
|
-
timeToFirstByteMs,
|
|
18149
|
-
},
|
|
18150
|
-
},
|
|
18151
|
-
});
|
|
18152
|
-
const artifacts = [];
|
|
18153
|
-
const initialArtifact = await runBrowserArtifacts.captureSnapshotArtifact({
|
|
18154
|
-
page,
|
|
18155
|
-
sessionId,
|
|
18156
|
-
label: 'Initial page',
|
|
18157
|
-
fileSuffix: 'initial',
|
|
18158
|
-
});
|
|
18159
|
-
if (initialArtifact) {
|
|
18160
|
-
artifacts.push(initialArtifact);
|
|
18161
|
-
}
|
|
18162
|
-
for (const [index, action] of normalizedActions.entries()) {
|
|
18163
|
-
runBrowserErrorHandling.assertNotAborted(internalOptions.signal, sessionId);
|
|
18164
|
-
emitRunBrowserProgress(args, {
|
|
18165
|
-
state: 'PARTIAL',
|
|
18166
|
-
log: {
|
|
18167
|
-
createdAt: createRunBrowserLogTimestamp(),
|
|
18168
|
-
kind: 'browser-action',
|
|
18169
|
-
title: `Action ${index + 1} running`,
|
|
18170
|
-
message: formatRunBrowserActionSummary(action),
|
|
18171
|
-
payload: {
|
|
18172
|
-
actionIndex: index + 1,
|
|
18173
|
-
action,
|
|
18174
|
-
phase: 'running',
|
|
18175
|
-
},
|
|
18176
|
-
},
|
|
18177
|
-
});
|
|
18178
|
-
await runBrowserWorkflow.executeAction({
|
|
18179
|
-
page,
|
|
18180
|
-
action,
|
|
18181
|
-
actionIndex: index + 1,
|
|
18182
|
-
timeouts: timeoutConfiguration,
|
|
18183
|
-
signal: internalOptions.signal,
|
|
18184
|
-
});
|
|
18185
|
-
emitRunBrowserProgress(args, {
|
|
18186
|
-
state: 'PARTIAL',
|
|
18187
|
-
log: {
|
|
18188
|
-
createdAt: createRunBrowserLogTimestamp(),
|
|
18189
|
-
kind: 'browser-action',
|
|
18190
|
-
title: `Action ${index + 1} finished`,
|
|
18191
|
-
message: formatRunBrowserActionSummary(action),
|
|
18192
|
-
payload: {
|
|
18193
|
-
actionIndex: index + 1,
|
|
18194
|
-
action,
|
|
18195
|
-
phase: 'complete',
|
|
18196
|
-
},
|
|
18197
|
-
},
|
|
18198
|
-
});
|
|
18199
|
-
const actionArtifact = await runBrowserArtifacts.captureSnapshotArtifact({
|
|
18200
|
-
page,
|
|
18201
|
-
sessionId,
|
|
18202
|
-
label: `After action ${index + 1}`,
|
|
18203
|
-
fileSuffix: `action-${String(index + 1).padStart(3, '0')}-${action.type}`,
|
|
18204
|
-
actionIndex: index + 1,
|
|
18205
|
-
action,
|
|
18206
|
-
});
|
|
18207
|
-
if (actionArtifact) {
|
|
18208
|
-
artifacts.push(actionArtifact);
|
|
18209
|
-
}
|
|
18210
|
-
}
|
|
18211
|
-
const snapshotPath = await runBrowserArtifacts.captureSnapshot(page, sessionId);
|
|
18212
|
-
const finalUrl = page.url();
|
|
18213
|
-
const finalTitle = await runBrowserArtifacts.getPageTitle(page);
|
|
18214
|
-
if (snapshotPath) {
|
|
18215
|
-
artifacts.push({
|
|
18216
|
-
kind: 'screenshot',
|
|
18217
|
-
label: 'Final page',
|
|
18218
|
-
path: snapshotPath,
|
|
18219
|
-
capturedAt: new Date().toISOString(),
|
|
18220
|
-
url: finalUrl,
|
|
18221
|
-
title: finalTitle,
|
|
18222
|
-
});
|
|
16351
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
16352
|
+
const runBrowserModule = require('../../../apps/agents-server/src/tools/run_browser');
|
|
16353
|
+
if (typeof runBrowserModule.run_browser !== 'function') {
|
|
16354
|
+
throw new Error('run_browser value is not a function but ' + typeof runBrowserModule.run_browser);
|
|
18223
16355
|
}
|
|
18224
|
-
|
|
18225
|
-
|
|
18226
|
-
mode,
|
|
18227
|
-
modeUsed: 'remote-browser',
|
|
18228
|
-
initialUrl,
|
|
18229
|
-
finalUrl,
|
|
18230
|
-
finalTitle,
|
|
18231
|
-
executedActions: normalizedActions,
|
|
18232
|
-
artifacts,
|
|
18233
|
-
warning: null,
|
|
18234
|
-
error: null,
|
|
18235
|
-
fallbackContent: null,
|
|
18236
|
-
timing: {
|
|
18237
|
-
connectDurationMs,
|
|
18238
|
-
initialNavigationDurationMs,
|
|
18239
|
-
timeToFirstByteMs,
|
|
18240
|
-
totalDurationMs: Date.now() - startedAt,
|
|
18241
|
-
},
|
|
18242
|
-
});
|
|
18243
|
-
runBrowserObservability.logRunBrowserMetric({
|
|
18244
|
-
event: 'run_browser_success',
|
|
18245
|
-
sessionId,
|
|
18246
|
-
mode: 'remote-browser',
|
|
18247
|
-
payload: {
|
|
18248
|
-
actions: normalizedActions.length,
|
|
18249
|
-
connectDurationMs,
|
|
18250
|
-
initialNavigationDurationMs,
|
|
18251
|
-
timeToFirstByteMs,
|
|
18252
|
-
},
|
|
18253
|
-
});
|
|
18254
|
-
return runBrowserResultFormatting.formatSuccessResult({
|
|
18255
|
-
payload,
|
|
18256
|
-
snapshotPath,
|
|
18257
|
-
});
|
|
16356
|
+
cachedRunBrowserTool = runBrowserModule.run_browser;
|
|
16357
|
+
return cachedRunBrowserTool;
|
|
18258
16358
|
}
|
|
18259
16359
|
catch (error) {
|
|
18260
|
-
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
mode,
|
|
18264
|
-
});
|
|
18265
|
-
const errorCodeCount = runBrowserObservability.incrementRunBrowserErrorCodeCounter(toolError.code);
|
|
18266
|
-
if (runBrowserErrorHandling.isRemoteBrowserUnavailableCode(toolError.code) && initialUrl) {
|
|
18267
|
-
const fallbackContent = await runFallbackScrape(initialUrl);
|
|
18268
|
-
const { fallbackRuns, fallbackRate } = runBrowserObservability.incrementFallbackRunsAndGetMetrics();
|
|
18269
|
-
emitRunBrowserProgress(args, {
|
|
18270
|
-
state: 'PARTIAL',
|
|
18271
|
-
log: {
|
|
18272
|
-
createdAt: createRunBrowserLogTimestamp(),
|
|
18273
|
-
kind: 'warning',
|
|
18274
|
-
level: 'warning',
|
|
18275
|
-
title: 'Fallback enabled',
|
|
18276
|
-
message: 'Remote browser was unavailable, so fallback scraping was used instead.',
|
|
18277
|
-
payload: {
|
|
18278
|
-
errorCode: toolError.code,
|
|
18279
|
-
initialUrl,
|
|
18280
|
-
},
|
|
18281
|
-
},
|
|
18282
|
-
});
|
|
18283
|
-
const payload = runBrowserResultFormatting.createResultPayload({
|
|
18284
|
-
sessionId,
|
|
18285
|
-
mode,
|
|
18286
|
-
modeUsed: 'fallback',
|
|
18287
|
-
initialUrl,
|
|
18288
|
-
finalUrl: null,
|
|
18289
|
-
finalTitle: null,
|
|
18290
|
-
executedActions: [],
|
|
18291
|
-
artifacts: [],
|
|
18292
|
-
warning: runBrowserConstants.fallbackDynamicContentWarning,
|
|
18293
|
-
error: toolError,
|
|
18294
|
-
fallbackContent,
|
|
18295
|
-
timing: {
|
|
18296
|
-
connectDurationMs,
|
|
18297
|
-
initialNavigationDurationMs,
|
|
18298
|
-
timeToFirstByteMs,
|
|
18299
|
-
totalDurationMs: Date.now() - startedAt,
|
|
18300
|
-
},
|
|
18301
|
-
});
|
|
18302
|
-
runBrowserObservability.logRunBrowserMetric({
|
|
18303
|
-
event: 'run_browser_fallback_used',
|
|
18304
|
-
sessionId,
|
|
18305
|
-
mode: 'fallback',
|
|
18306
|
-
payload: {
|
|
18307
|
-
errorCode: toolError.code,
|
|
18308
|
-
errorCodeCount,
|
|
18309
|
-
fallbackRuns,
|
|
18310
|
-
totalRuns: runBrowserObservability.getTotalRuns(),
|
|
18311
|
-
fallbackRate,
|
|
18312
|
-
},
|
|
18313
|
-
});
|
|
18314
|
-
return runBrowserResultFormatting.formatFallbackResult({
|
|
18315
|
-
payload,
|
|
18316
|
-
fallbackContent,
|
|
18317
|
-
requestedActions: Array.isArray(args.actions) ? args.actions.length : 0,
|
|
18318
|
-
});
|
|
18319
|
-
}
|
|
18320
|
-
emitRunBrowserProgress(args, {
|
|
18321
|
-
state: 'ERROR',
|
|
18322
|
-
log: {
|
|
18323
|
-
createdAt: createRunBrowserLogTimestamp(),
|
|
18324
|
-
kind: 'error',
|
|
18325
|
-
level: 'error',
|
|
18326
|
-
title: 'Browser run failed',
|
|
18327
|
-
message: toolError.message,
|
|
18328
|
-
payload: {
|
|
18329
|
-
code: toolError.code,
|
|
18330
|
-
debug: toolError.debug,
|
|
18331
|
-
},
|
|
18332
|
-
},
|
|
18333
|
-
});
|
|
18334
|
-
const payload = runBrowserResultFormatting.createResultPayload({
|
|
18335
|
-
sessionId,
|
|
18336
|
-
mode,
|
|
18337
|
-
modeUsed: 'remote-browser',
|
|
18338
|
-
initialUrl,
|
|
18339
|
-
finalUrl: page ? page.url() : null,
|
|
18340
|
-
finalTitle: page ? await runBrowserArtifacts.getPageTitle(page) : null,
|
|
18341
|
-
executedActions: [],
|
|
18342
|
-
artifacts: [],
|
|
18343
|
-
warning: null,
|
|
18344
|
-
error: toolError,
|
|
18345
|
-
fallbackContent: null,
|
|
18346
|
-
timing: {
|
|
18347
|
-
connectDurationMs,
|
|
18348
|
-
initialNavigationDurationMs,
|
|
18349
|
-
timeToFirstByteMs,
|
|
18350
|
-
totalDurationMs: Date.now() - startedAt,
|
|
18351
|
-
},
|
|
18352
|
-
});
|
|
18353
|
-
runBrowserObservability.logRunBrowserMetric({
|
|
18354
|
-
event: 'run_browser_failed',
|
|
18355
|
-
sessionId,
|
|
18356
|
-
mode: 'remote-browser',
|
|
18357
|
-
payload: {
|
|
18358
|
-
errorCode: toolError.code,
|
|
18359
|
-
errorCodeCount,
|
|
18360
|
-
connectDurationMs,
|
|
18361
|
-
initialNavigationDurationMs,
|
|
18362
|
-
timeToFirstByteMs,
|
|
18363
|
-
},
|
|
18364
|
-
});
|
|
18365
|
-
return runBrowserResultFormatting.formatErrorResult({
|
|
18366
|
-
payload,
|
|
18367
|
-
});
|
|
18368
|
-
}
|
|
18369
|
-
finally {
|
|
18370
|
-
await runBrowserArtifacts.cleanupPage(page, sessionId);
|
|
16360
|
+
assertsError(error);
|
|
16361
|
+
cachedRunBrowserToolError = error;
|
|
16362
|
+
throw error;
|
|
18371
16363
|
}
|
|
18372
16364
|
}
|
|
18373
|
-
|
|
18374
16365
|
/**
|
|
18375
16366
|
* Resolves the server-side implementation of the `run_browser` tool for Node.js environments.
|
|
18376
16367
|
*
|
|
18377
|
-
* This uses lazy
|
|
16368
|
+
* This uses fully lazy resolution to keep CLI startup independent from optional browser tooling.
|
|
18378
16369
|
* When the server tool cannot be resolved, the fallback implementation throws a helpful error.
|
|
18379
16370
|
*
|
|
18380
16371
|
* @private internal utility for USE BROWSER commitment
|
|
18381
16372
|
*/
|
|
18382
16373
|
function resolveRunBrowserToolForNode() {
|
|
18383
|
-
|
|
18384
|
-
|
|
18385
|
-
|
|
18386
|
-
|
|
18387
|
-
throw new Error('run_browser value is not a function but ' + typeof run_browser);
|
|
16374
|
+
return async (args) => {
|
|
16375
|
+
try {
|
|
16376
|
+
const runBrowserTool = loadRunBrowserToolForNode();
|
|
16377
|
+
return await runBrowserTool(args);
|
|
18388
16378
|
}
|
|
18389
|
-
|
|
18390
|
-
|
|
18391
|
-
catch (error) {
|
|
18392
|
-
assertsError(error);
|
|
18393
|
-
return async () => {
|
|
16379
|
+
catch (error) {
|
|
16380
|
+
assertsError(error);
|
|
18394
16381
|
throw new EnvironmentMismatchError(spaceTrim$1((block) => `
|
|
18395
16382
|
\`run_browser\` tool is not available in this environment.
|
|
18396
16383
|
This commitment requires the Agents Server browser runtime with Playwright CLI.
|
|
@@ -18398,8 +16385,8 @@ function resolveRunBrowserToolForNode() {
|
|
|
18398
16385
|
${error.name}:
|
|
18399
16386
|
${block(error.message)}
|
|
18400
16387
|
`));
|
|
18401
|
-
}
|
|
18402
|
-
}
|
|
16388
|
+
}
|
|
16389
|
+
};
|
|
18403
16390
|
}
|
|
18404
16391
|
|
|
18405
16392
|
/**
|
|
@@ -20234,6 +18221,110 @@ const parseMemoryToolArgs = {
|
|
|
20234
18221
|
},
|
|
20235
18222
|
};
|
|
20236
18223
|
|
|
18224
|
+
/**
|
|
18225
|
+
* Prompt parameter key used to pass hidden runtime context to tool execution.
|
|
18226
|
+
*
|
|
18227
|
+
* @private internal runtime wiring for commitment tools
|
|
18228
|
+
*/
|
|
18229
|
+
const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
|
|
18230
|
+
/**
|
|
18231
|
+
* Hidden argument key used to pass runtime context into individual tool calls.
|
|
18232
|
+
*
|
|
18233
|
+
* @private internal runtime wiring for commitment tools
|
|
18234
|
+
*/
|
|
18235
|
+
const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
|
|
18236
|
+
/**
|
|
18237
|
+
* Prompt parameter key used to pass a hidden tool-progress listener token into script execution.
|
|
18238
|
+
*
|
|
18239
|
+
* @private internal runtime wiring for commitment tools
|
|
18240
|
+
*/
|
|
18241
|
+
const TOOL_PROGRESS_TOKEN_PARAMETER = 'promptbookToolProgressToken';
|
|
18242
|
+
/**
|
|
18243
|
+
* Hidden argument key used to pass a tool-progress listener token into individual tool calls.
|
|
18244
|
+
*
|
|
18245
|
+
* @private internal runtime wiring for commitment tools
|
|
18246
|
+
*/
|
|
18247
|
+
const TOOL_PROGRESS_TOKEN_ARGUMENT = '__promptbookToolProgressToken';
|
|
18248
|
+
/**
|
|
18249
|
+
* Monotonic counter used for hidden progress-listener tokens.
|
|
18250
|
+
*
|
|
18251
|
+
* @private internal runtime wiring for commitment tools
|
|
18252
|
+
*/
|
|
18253
|
+
let toolCallProgressListenerCounter = 0;
|
|
18254
|
+
/**
|
|
18255
|
+
* Active tool-progress listeners keyed by hidden execution token.
|
|
18256
|
+
*
|
|
18257
|
+
* @private internal runtime wiring for commitment tools
|
|
18258
|
+
*/
|
|
18259
|
+
const toolCallProgressListeners = new Map();
|
|
18260
|
+
/**
|
|
18261
|
+
* Parses unknown runtime context payload into a normalized object.
|
|
18262
|
+
*
|
|
18263
|
+
* @private internal runtime wiring for commitment tools
|
|
18264
|
+
*/
|
|
18265
|
+
function parseToolRuntimeContext(rawValue) {
|
|
18266
|
+
if (!rawValue) {
|
|
18267
|
+
return null;
|
|
18268
|
+
}
|
|
18269
|
+
let parsed = rawValue;
|
|
18270
|
+
if (typeof rawValue === 'string') {
|
|
18271
|
+
try {
|
|
18272
|
+
parsed = JSON.parse(rawValue);
|
|
18273
|
+
}
|
|
18274
|
+
catch (_a) {
|
|
18275
|
+
return null;
|
|
18276
|
+
}
|
|
18277
|
+
}
|
|
18278
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
18279
|
+
return null;
|
|
18280
|
+
}
|
|
18281
|
+
return parsed;
|
|
18282
|
+
}
|
|
18283
|
+
/**
|
|
18284
|
+
* Reads runtime context attached to tool call arguments.
|
|
18285
|
+
*
|
|
18286
|
+
* @private internal runtime wiring for commitment tools
|
|
18287
|
+
*/
|
|
18288
|
+
function readToolRuntimeContextFromToolArgs(args) {
|
|
18289
|
+
return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
|
|
18290
|
+
}
|
|
18291
|
+
/**
|
|
18292
|
+
* Serializes runtime context for prompt parameters.
|
|
18293
|
+
*
|
|
18294
|
+
* @private internal runtime wiring for commitment tools
|
|
18295
|
+
*/
|
|
18296
|
+
function serializeToolRuntimeContext(context) {
|
|
18297
|
+
return JSON.stringify(context);
|
|
18298
|
+
}
|
|
18299
|
+
/**
|
|
18300
|
+
* Registers one in-memory listener that receives progress updates emitted by a running tool.
|
|
18301
|
+
*
|
|
18302
|
+
* The returned token is passed into script execution as a hidden argument so tool implementations
|
|
18303
|
+
* can stream progress without exposing extra parameters to the model.
|
|
18304
|
+
*
|
|
18305
|
+
* @param listener - Listener notified about tool progress.
|
|
18306
|
+
* @returns Hidden token used to route progress updates.
|
|
18307
|
+
* @private internal runtime wiring for commitment tools
|
|
18308
|
+
*/
|
|
18309
|
+
function registerToolCallProgressListener(listener) {
|
|
18310
|
+
toolCallProgressListenerCounter += 1;
|
|
18311
|
+
const token = `tool-progress:${Date.now()}:${toolCallProgressListenerCounter}`;
|
|
18312
|
+
toolCallProgressListeners.set(token, listener);
|
|
18313
|
+
return token;
|
|
18314
|
+
}
|
|
18315
|
+
/**
|
|
18316
|
+
* Unregisters one in-memory progress listener.
|
|
18317
|
+
*
|
|
18318
|
+
* @param token - Token previously created by `registerToolCallProgressListener`.
|
|
18319
|
+
* @private internal runtime wiring for commitment tools
|
|
18320
|
+
*/
|
|
18321
|
+
function unregisterToolCallProgressListener(token) {
|
|
18322
|
+
toolCallProgressListeners.delete(token);
|
|
18323
|
+
}
|
|
18324
|
+
/**
|
|
18325
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
18326
|
+
*/
|
|
18327
|
+
|
|
20237
18328
|
/**
|
|
20238
18329
|
* Resolves runtime context from hidden tool arguments.
|
|
20239
18330
|
*
|
|
@@ -27942,9 +26033,9 @@ function createTimeoutSystemMessage(extraInstructions) {
|
|
|
27942
26033
|
return spaceTrim$1((block) => `
|
|
27943
26034
|
Timeout scheduling:
|
|
27944
26035
|
- Use "set_timeout" to wake this same chat thread in the future.
|
|
27945
|
-
-
|
|
26036
|
+
- Use "list_timeouts" to review timeouts across all chats for the same user+agent scope.
|
|
26037
|
+
- "cancel_timeout" accepts a timeout id from any chat in this same user+agent scope.
|
|
27946
26038
|
- 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\`.
|
|
27947
|
-
- Use "cancel_timeout" when a previously scheduled timeout is no longer relevant.
|
|
27948
26039
|
- Do not claim a timer was set or cancelled unless the tool confirms it.
|
|
27949
26040
|
${block(extraInstructions)}
|
|
27950
26041
|
`);
|
|
@@ -28005,13 +26096,6 @@ function parseToolExecutionEnvelope(rawValue) {
|
|
|
28005
26096
|
* @private internal utility of USE TIMEOUT
|
|
28006
26097
|
*/
|
|
28007
26098
|
function createDisabledTimeoutResult(action, message) {
|
|
28008
|
-
if (action === 'set') {
|
|
28009
|
-
return {
|
|
28010
|
-
action,
|
|
28011
|
-
status: 'disabled',
|
|
28012
|
-
message,
|
|
28013
|
-
};
|
|
28014
|
-
}
|
|
28015
26099
|
return {
|
|
28016
26100
|
action,
|
|
28017
26101
|
status: 'disabled',
|
|
@@ -28038,6 +26122,18 @@ function getTimeoutToolRuntimeAdapterOrDisabledResult(action, runtimeContext) {
|
|
|
28038
26122
|
}
|
|
28039
26123
|
}
|
|
28040
26124
|
|
|
26125
|
+
/**
|
|
26126
|
+
* Default number of rows returned by `list_timeouts`.
|
|
26127
|
+
*
|
|
26128
|
+
* @private internal USE TIMEOUT constant
|
|
26129
|
+
*/
|
|
26130
|
+
const DEFAULT_LIST_TIMEOUTS_LIMIT = 20;
|
|
26131
|
+
/**
|
|
26132
|
+
* Hard cap for `list_timeouts` page size.
|
|
26133
|
+
*
|
|
26134
|
+
* @private internal USE TIMEOUT constant
|
|
26135
|
+
*/
|
|
26136
|
+
const MAX_LIST_TIMEOUTS_LIMIT = 100;
|
|
28041
26137
|
/**
|
|
28042
26138
|
* Parses and validates `USE TIMEOUT` tool arguments.
|
|
28043
26139
|
*
|
|
@@ -28072,6 +26168,31 @@ const parseTimeoutToolArgs = {
|
|
|
28072
26168
|
}
|
|
28073
26169
|
return { timeoutId };
|
|
28074
26170
|
},
|
|
26171
|
+
/**
|
|
26172
|
+
* Parses `list_timeouts` input.
|
|
26173
|
+
*/
|
|
26174
|
+
list(args) {
|
|
26175
|
+
if (args.includeFinished !== undefined && typeof args.includeFinished !== 'boolean') {
|
|
26176
|
+
throw new PipelineExecutionError(spaceTrim$1(`
|
|
26177
|
+
Timeout \`includeFinished\` must be a boolean when provided.
|
|
26178
|
+
`));
|
|
26179
|
+
}
|
|
26180
|
+
const parsedLimit = args.limit === undefined ? DEFAULT_LIST_TIMEOUTS_LIMIT : Math.floor(Number(args.limit));
|
|
26181
|
+
if (!Number.isFinite(parsedLimit) || parsedLimit <= 0) {
|
|
26182
|
+
throw new PipelineExecutionError(spaceTrim$1(`
|
|
26183
|
+
Timeout \`limit\` must be a positive number.
|
|
26184
|
+
`));
|
|
26185
|
+
}
|
|
26186
|
+
if (parsedLimit > MAX_LIST_TIMEOUTS_LIMIT) {
|
|
26187
|
+
throw new PipelineExecutionError(spaceTrim$1(`
|
|
26188
|
+
Timeout \`limit\` must be at most \`${MAX_LIST_TIMEOUTS_LIMIT}\`.
|
|
26189
|
+
`));
|
|
26190
|
+
}
|
|
26191
|
+
return {
|
|
26192
|
+
includeFinished: args.includeFinished === true,
|
|
26193
|
+
limit: parsedLimit,
|
|
26194
|
+
};
|
|
26195
|
+
},
|
|
28075
26196
|
};
|
|
28076
26197
|
|
|
28077
26198
|
/**
|
|
@@ -28082,6 +26203,7 @@ const parseTimeoutToolArgs = {
|
|
|
28082
26203
|
const TimeoutToolNames = {
|
|
28083
26204
|
set: 'set_timeout',
|
|
28084
26205
|
cancel: 'cancel_timeout',
|
|
26206
|
+
list: 'list_timeouts',
|
|
28085
26207
|
};
|
|
28086
26208
|
|
|
28087
26209
|
/**
|
|
@@ -28181,6 +26303,35 @@ function createTimeoutToolFunctions() {
|
|
|
28181
26303
|
return JSON.stringify(result);
|
|
28182
26304
|
}
|
|
28183
26305
|
},
|
|
26306
|
+
async [TimeoutToolNames.list](args) {
|
|
26307
|
+
const runtimeContext = resolveTimeoutRuntimeContext(args);
|
|
26308
|
+
const { adapter, disabledResult } = getTimeoutToolRuntimeAdapterOrDisabledResult('list', runtimeContext);
|
|
26309
|
+
if (!adapter || disabledResult) {
|
|
26310
|
+
return JSON.stringify(disabledResult);
|
|
26311
|
+
}
|
|
26312
|
+
try {
|
|
26313
|
+
const parsedArgs = parseTimeoutToolArgs.list(args);
|
|
26314
|
+
const listedTimeouts = await adapter.listTimeouts(parsedArgs, runtimeContext);
|
|
26315
|
+
const result = {
|
|
26316
|
+
action: 'list',
|
|
26317
|
+
status: 'listed',
|
|
26318
|
+
items: listedTimeouts.items,
|
|
26319
|
+
total: listedTimeouts.total,
|
|
26320
|
+
};
|
|
26321
|
+
return createToolExecutionEnvelope({
|
|
26322
|
+
assistantMessage: listedTimeouts.total === 1 ? 'Found 1 timeout.' : `Found ${listedTimeouts.total} timeouts.`,
|
|
26323
|
+
toolResult: result,
|
|
26324
|
+
});
|
|
26325
|
+
}
|
|
26326
|
+
catch (error) {
|
|
26327
|
+
const result = {
|
|
26328
|
+
action: 'list',
|
|
26329
|
+
status: 'error',
|
|
26330
|
+
message: error instanceof Error ? error.message : String(error),
|
|
26331
|
+
};
|
|
26332
|
+
return JSON.stringify(result);
|
|
26333
|
+
}
|
|
26334
|
+
},
|
|
28184
26335
|
};
|
|
28185
26336
|
}
|
|
28186
26337
|
|
|
@@ -28214,26 +26365,45 @@ function createTimeoutTools(existingTools = []) {
|
|
|
28214
26365
|
if (!tools.some((tool) => tool.name === TimeoutToolNames.cancel)) {
|
|
28215
26366
|
tools.push({
|
|
28216
26367
|
name: TimeoutToolNames.cancel,
|
|
28217
|
-
description: 'Cancel one previously scheduled timeout
|
|
26368
|
+
description: 'Cancel one previously scheduled timeout within the same user+agent scope, even if it was set in another chat.',
|
|
28218
26369
|
parameters: {
|
|
28219
26370
|
type: 'object',
|
|
28220
26371
|
properties: {
|
|
28221
26372
|
timeoutId: {
|
|
28222
26373
|
type: 'string',
|
|
28223
|
-
description: 'Identifier returned earlier by `set_timeout`.',
|
|
26374
|
+
description: 'Identifier returned earlier by `set_timeout` or `list_timeouts`.',
|
|
28224
26375
|
},
|
|
28225
26376
|
},
|
|
28226
26377
|
required: ['timeoutId'],
|
|
28227
26378
|
},
|
|
28228
26379
|
});
|
|
28229
26380
|
}
|
|
26381
|
+
if (!tools.some((tool) => tool.name === TimeoutToolNames.list)) {
|
|
26382
|
+
tools.push({
|
|
26383
|
+
name: TimeoutToolNames.list,
|
|
26384
|
+
description: 'List scheduled timeouts across all chats for this same user+agent scope so they can be reviewed or cancelled.',
|
|
26385
|
+
parameters: {
|
|
26386
|
+
type: 'object',
|
|
26387
|
+
properties: {
|
|
26388
|
+
includeFinished: {
|
|
26389
|
+
type: 'boolean',
|
|
26390
|
+
description: 'When true, include completed, failed, and cancelled rows in addition to active timeouts.',
|
|
26391
|
+
},
|
|
26392
|
+
limit: {
|
|
26393
|
+
type: 'number',
|
|
26394
|
+
description: 'Maximum number of rows to return (default 20, max 100).',
|
|
26395
|
+
},
|
|
26396
|
+
},
|
|
26397
|
+
},
|
|
26398
|
+
});
|
|
26399
|
+
}
|
|
28230
26400
|
return tools;
|
|
28231
26401
|
}
|
|
28232
26402
|
|
|
28233
26403
|
/**
|
|
28234
26404
|
* `USE TIMEOUT` commitment definition.
|
|
28235
26405
|
*
|
|
28236
|
-
* The `USE TIMEOUT` commitment enables
|
|
26406
|
+
* The `USE TIMEOUT` commitment enables timeout wake-ups and scoped timeout management.
|
|
28237
26407
|
*
|
|
28238
26408
|
* @private [🪔] Maybe export the commitments through some package
|
|
28239
26409
|
*/
|
|
@@ -28248,7 +26418,7 @@ class UseTimeoutCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
28248
26418
|
* Short one-line description of `USE TIMEOUT`.
|
|
28249
26419
|
*/
|
|
28250
26420
|
get description() {
|
|
28251
|
-
return 'Enable
|
|
26421
|
+
return 'Enable timeout wake-ups plus scoped timeout listing/cancellation across chats.';
|
|
28252
26422
|
}
|
|
28253
26423
|
/**
|
|
28254
26424
|
* Icon for this commitment.
|
|
@@ -28263,14 +26433,15 @@ class UseTimeoutCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
28263
26433
|
return spaceTrim$1(`
|
|
28264
26434
|
# USE TIMEOUT
|
|
28265
26435
|
|
|
28266
|
-
Enables
|
|
26436
|
+
Enables timeout wake-ups and timeout management for the same user+agent scope.
|
|
28267
26437
|
|
|
28268
26438
|
## Key aspects
|
|
28269
26439
|
|
|
28270
26440
|
- The agent uses \`set_timeout\` to schedule a future wake-up in the same chat thread.
|
|
28271
26441
|
- The tool returns immediately while the timeout is stored and executed by the runtime later.
|
|
28272
26442
|
- The wake-up arrives as a new user-like timeout message in the same conversation.
|
|
28273
|
-
- The agent can
|
|
26443
|
+
- The agent can inspect known timeouts via \`list_timeouts\`.
|
|
26444
|
+
- The agent can cancel an existing timeout by \`timeoutId\` via \`cancel_timeout\`, including timeouts created in another chat.
|
|
28274
26445
|
- Commitment content is treated as optional timeout policy instructions.
|
|
28275
26446
|
|
|
28276
26447
|
## Examples
|
|
@@ -28299,6 +26470,7 @@ class UseTimeoutCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
28299
26470
|
return {
|
|
28300
26471
|
[TimeoutToolNames.set]: 'Set timer',
|
|
28301
26472
|
[TimeoutToolNames.cancel]: 'Cancel timer',
|
|
26473
|
+
[TimeoutToolNames.list]: 'List timers',
|
|
28302
26474
|
};
|
|
28303
26475
|
}
|
|
28304
26476
|
/**
|
|
@@ -29230,7 +27402,7 @@ class JavascriptEvalExecutionTools {
|
|
|
29230
27402
|
}
|
|
29231
27403
|
// Note: [💎]
|
|
29232
27404
|
// Note: Using direct eval, following variables are in same scope as eval call so they are accessible from inside the evaluated script:
|
|
29233
|
-
const spaceTrim = (_) =>
|
|
27405
|
+
const spaceTrim = (_) => _spaceTrim(_);
|
|
29234
27406
|
$preserve(spaceTrim);
|
|
29235
27407
|
const removeQuotes$1 = removeQuotes;
|
|
29236
27408
|
$preserve(removeQuotes$1);
|
|
@@ -29321,7 +27493,7 @@ class JavascriptEvalExecutionTools {
|
|
|
29321
27493
|
.join('\n');
|
|
29322
27494
|
// script = templateParameters(script, parameters);
|
|
29323
27495
|
// <- TODO: [🧠][🥳] Should be this is one of two variants how to use parameters in script
|
|
29324
|
-
const statementToEvaluate =
|
|
27496
|
+
const statementToEvaluate = _spaceTrim((block) => `
|
|
29325
27497
|
|
|
29326
27498
|
// Build-in functions:
|
|
29327
27499
|
${block(buildinFunctionsStatement)}
|
|
@@ -29336,7 +27508,7 @@ class JavascriptEvalExecutionTools {
|
|
|
29336
27508
|
(async ()=>{ ${script} })()
|
|
29337
27509
|
`);
|
|
29338
27510
|
if (this.options.isVerbose) {
|
|
29339
|
-
console.info(
|
|
27511
|
+
console.info(_spaceTrim((block) => `
|
|
29340
27512
|
🚀 Evaluating ${scriptLanguage} script:
|
|
29341
27513
|
|
|
29342
27514
|
${block(statementToEvaluate)}`));
|
|
@@ -29345,7 +27517,7 @@ class JavascriptEvalExecutionTools {
|
|
|
29345
27517
|
try {
|
|
29346
27518
|
result = await eval(statementToEvaluate);
|
|
29347
27519
|
if (this.options.isVerbose) {
|
|
29348
|
-
console.info(
|
|
27520
|
+
console.info(_spaceTrim((block) => `
|
|
29349
27521
|
🚀 Script evaluated successfully, result:
|
|
29350
27522
|
${block(valueToString(result))}
|
|
29351
27523
|
`));
|
|
@@ -29364,7 +27536,7 @@ class JavascriptEvalExecutionTools {
|
|
|
29364
27536
|
To: [PipelineExecutionError: Parameter `{thing}` is not defined],
|
|
29365
27537
|
*/
|
|
29366
27538
|
if (!statementToEvaluate.includes(undefinedName + '(')) {
|
|
29367
|
-
throw new PipelineExecutionError(
|
|
27539
|
+
throw new PipelineExecutionError(_spaceTrim((block) => `
|
|
29368
27540
|
|
|
29369
27541
|
Parameter \`{${undefinedName}}\` is not defined
|
|
29370
27542
|
|
|
@@ -29386,7 +27558,7 @@ class JavascriptEvalExecutionTools {
|
|
|
29386
27558
|
`));
|
|
29387
27559
|
}
|
|
29388
27560
|
else {
|
|
29389
|
-
throw new PipelineExecutionError(
|
|
27561
|
+
throw new PipelineExecutionError(_spaceTrim((block) => `
|
|
29390
27562
|
Function ${undefinedName}() is not defined
|
|
29391
27563
|
|
|
29392
27564
|
- Make sure that the function is one of built-in functions
|
|
@@ -29639,7 +27811,7 @@ async function createPipelineCollectionFromDirectory(rootPath, tools, options) {
|
|
|
29639
27811
|
catch (error) {
|
|
29640
27812
|
assertsError(error);
|
|
29641
27813
|
// TODO: [7] DRY
|
|
29642
|
-
const wrappedErrorMessage = spaceTrim$
|
|
27814
|
+
const wrappedErrorMessage = spaceTrim$1((block) => `
|
|
29643
27815
|
${error.name} in pipeline ${fileName.split('\\').join('/')}:
|
|
29644
27816
|
|
|
29645
27817
|
Original error message:
|
|
@@ -29674,7 +27846,7 @@ async function createPipelineCollectionFromDirectory(rootPath, tools, options) {
|
|
|
29674
27846
|
pipeline = { ...pipeline, pipelineUrl };
|
|
29675
27847
|
}
|
|
29676
27848
|
else if (!pipeline.pipelineUrl.startsWith(rootUrl)) {
|
|
29677
|
-
throw new PipelineUrlError(spaceTrim$
|
|
27849
|
+
throw new PipelineUrlError(spaceTrim$1(`
|
|
29678
27850
|
Pipeline with URL ${pipeline.pipelineUrl} is not a child of the root URL ${rootUrl} 🍏
|
|
29679
27851
|
|
|
29680
27852
|
File:
|
|
@@ -29712,7 +27884,7 @@ async function createPipelineCollectionFromDirectory(rootPath, tools, options) {
|
|
|
29712
27884
|
}
|
|
29713
27885
|
else {
|
|
29714
27886
|
const existing = collection.get(pipeline.pipelineUrl);
|
|
29715
|
-
throw new PipelineUrlError(spaceTrim$
|
|
27887
|
+
throw new PipelineUrlError(spaceTrim$1(`
|
|
29716
27888
|
Pipeline with URL ${pipeline.pipelineUrl} is already in the collection 🍏
|
|
29717
27889
|
|
|
29718
27890
|
Conflicting files:
|
|
@@ -29730,7 +27902,7 @@ async function createPipelineCollectionFromDirectory(rootPath, tools, options) {
|
|
|
29730
27902
|
catch (error) {
|
|
29731
27903
|
assertsError(error);
|
|
29732
27904
|
// TODO: [7] DRY
|
|
29733
|
-
const wrappedErrorMessage = spaceTrim$
|
|
27905
|
+
const wrappedErrorMessage = spaceTrim$1((block) => `
|
|
29734
27906
|
${error.name} in pipeline ${fileName.split('\\').join('/')}:
|
|
29735
27907
|
|
|
29736
27908
|
Original error message:
|
|
@@ -29865,7 +28037,7 @@ function usageToHuman(usage) {
|
|
|
29865
28037
|
// Note: For negligible usage, we report at least something
|
|
29866
28038
|
reportItems.push('Negligible');
|
|
29867
28039
|
}
|
|
29868
|
-
return spaceTrim$
|
|
28040
|
+
return spaceTrim$1((block) => `
|
|
29869
28041
|
Usage:
|
|
29870
28042
|
${block(reportItems.map((item) => `- ${item}`).join('\n'))}
|
|
29871
28043
|
`);
|
|
@@ -29905,7 +28077,7 @@ async function $provideScriptingForNode(options) {
|
|
|
29905
28077
|
*/
|
|
29906
28078
|
function $initializeMakeCommand(program) {
|
|
29907
28079
|
const makeCommand = program.command('make');
|
|
29908
|
-
makeCommand.description(spaceTrim$
|
|
28080
|
+
makeCommand.description(spaceTrim$1(`
|
|
29909
28081
|
Makes a new pipeline collection in given folder
|
|
29910
28082
|
`));
|
|
29911
28083
|
makeCommand.alias('compile');
|
|
@@ -29917,7 +28089,7 @@ function $initializeMakeCommand(program) {
|
|
|
29917
28089
|
'Path to promptbook collection directory', DEFAULT_BOOKS_DIRNAME);
|
|
29918
28090
|
makeCommand.option('--project-name', `Name of the project for whom collection is`, 'Untitled Promptbook project');
|
|
29919
28091
|
makeCommand.option('--root-url <url>', `Root URL of all pipelines to make`, undefined);
|
|
29920
|
-
makeCommand.option('-f, --format <format>', spaceTrim$
|
|
28092
|
+
makeCommand.option('-f, --format <format>', spaceTrim$1(`
|
|
29921
28093
|
Output format of builded collection "bookc", "javascript", "typescript" or "json"
|
|
29922
28094
|
|
|
29923
28095
|
Note: You can use multiple formats separated by comma
|
|
@@ -29925,14 +28097,14 @@ function $initializeMakeCommand(program) {
|
|
|
29925
28097
|
makeCommand.option('--no-validation', `Do not validate logic of pipelines in collection`, true);
|
|
29926
28098
|
makeCommand.option('--validation', `Types of validations separated by comma (options "logic","imports")`, 'logic,imports');
|
|
29927
28099
|
makeCommand.option('-r, --reload', `Call LLM models even if same prompt with result is in the cache`, false);
|
|
29928
|
-
makeCommand.option('-o, --output <path>', spaceTrim$
|
|
28100
|
+
makeCommand.option('-o, --output <path>', spaceTrim$1(`
|
|
29929
28101
|
Where to save the builded collection
|
|
29930
28102
|
|
|
29931
28103
|
Note: If you keep it "${DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME}" it will be saved in the root of the promptbook directory
|
|
29932
28104
|
If you set it to a path, it will be saved in that path
|
|
29933
28105
|
BUT you can use only one format and set correct extension
|
|
29934
28106
|
`), DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME);
|
|
29935
|
-
makeCommand.option('-fn, --function-name <functionName>', spaceTrim$
|
|
28107
|
+
makeCommand.option('-fn, --function-name <functionName>', spaceTrim$1(`
|
|
29936
28108
|
Name of the function to get pipeline collection
|
|
29937
28109
|
|
|
29938
28110
|
Note: This can be used only with "javascript" or "typescript" format
|
|
@@ -30015,7 +28187,7 @@ function $initializeMakeCommand(program) {
|
|
|
30015
28187
|
if (lastChar !== ']') {
|
|
30016
28188
|
throw new UnexpectedError(`Last character of serialized collection should be "]" not "${lastChar}"`);
|
|
30017
28189
|
}
|
|
30018
|
-
return spaceTrim$
|
|
28190
|
+
return spaceTrim$1(collectionJsonString.substring(1, collectionJsonString.length - 1));
|
|
30019
28191
|
})();
|
|
30020
28192
|
const saveFile = async (extension, content) => {
|
|
30021
28193
|
const filename = output !== DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME
|
|
@@ -30046,7 +28218,7 @@ function $initializeMakeCommand(program) {
|
|
|
30046
28218
|
}
|
|
30047
28219
|
if (formats.includes('javascript') || formats.includes('js')) {
|
|
30048
28220
|
formats = formats.filter((format) => format !== 'javascript' && format !== 'js');
|
|
30049
|
-
(await saveFile('js', spaceTrim$
|
|
28221
|
+
(await saveFile('js', spaceTrim$1((block) => `
|
|
30050
28222
|
// ${block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI)}
|
|
30051
28223
|
|
|
30052
28224
|
import { createPipelineCollectionFromJson } from '@promptbook/core';
|
|
@@ -30083,7 +28255,7 @@ function $initializeMakeCommand(program) {
|
|
|
30083
28255
|
}
|
|
30084
28256
|
if (formats.includes('typescript') || formats.includes('ts')) {
|
|
30085
28257
|
formats = formats.filter((format) => format !== 'typescript' && format !== 'ts');
|
|
30086
|
-
await saveFile('ts', spaceTrim$
|
|
28258
|
+
await saveFile('ts', spaceTrim$1((block) => `
|
|
30087
28259
|
// ${block(GENERATOR_WARNING_BY_PROMPTBOOK_CLI)}
|
|
30088
28260
|
|
|
30089
28261
|
import { createPipelineCollectionFromJson } from '@promptbook/core';
|
|
@@ -30228,7 +28400,7 @@ async function prettifyPipelineString(pipelineString, options) {
|
|
|
30228
28400
|
*/
|
|
30229
28401
|
function $initializePrettifyCommand(program) {
|
|
30230
28402
|
const prettifyCommand = program.command('prettify');
|
|
30231
|
-
prettifyCommand.description(spaceTrim$
|
|
28403
|
+
prettifyCommand.description(spaceTrim$1(`
|
|
30232
28404
|
Iterates over \`.book.md\` files and does multiple enhancing operations on them:
|
|
30233
28405
|
|
|
30234
28406
|
1) Adds Mermaid graph
|
|
@@ -30684,7 +28856,7 @@ async function $getCompiledBook(tools, pipelineSource, options) {
|
|
|
30684
28856
|
// console.log(`Strategy 3️⃣`);
|
|
30685
28857
|
const response = await fetch(pipelineSource);
|
|
30686
28858
|
if (response.status >= 300) {
|
|
30687
|
-
throw new NotFoundError(spaceTrim$
|
|
28859
|
+
throw new NotFoundError(spaceTrim$1((block) => `
|
|
30688
28860
|
Book not found on URL:
|
|
30689
28861
|
${block(pipelineSource)}
|
|
30690
28862
|
|
|
@@ -30694,7 +28866,7 @@ async function $getCompiledBook(tools, pipelineSource, options) {
|
|
|
30694
28866
|
const pipelineString = await response.text();
|
|
30695
28867
|
// console.log({ pipelineString });
|
|
30696
28868
|
if (!isValidPipelineString(pipelineString)) {
|
|
30697
|
-
throw new NotFoundError(spaceTrim$
|
|
28869
|
+
throw new NotFoundError(spaceTrim$1((block) => `
|
|
30698
28870
|
Book not found on URL:
|
|
30699
28871
|
${block(pipelineSource)}
|
|
30700
28872
|
|
|
@@ -30716,7 +28888,7 @@ async function $getCompiledBook(tools, pipelineSource, options) {
|
|
|
30716
28888
|
});
|
|
30717
28889
|
return pipelineJson;
|
|
30718
28890
|
} /* not else */
|
|
30719
|
-
throw new NotFoundError(spaceTrim$
|
|
28891
|
+
throw new NotFoundError(spaceTrim$1((block) => `
|
|
30720
28892
|
Book not found:
|
|
30721
28893
|
${block(pipelineSource)}
|
|
30722
28894
|
|
|
@@ -30763,7 +28935,7 @@ async function runInteractiveChatbot(options) {
|
|
|
30763
28935
|
const initialMessage = (((_a = pipeline.parameters.find(({ name }) => name === 'chatbotResponse')) === null || _a === void 0 ? void 0 : _a.exampleValues) || [])[0];
|
|
30764
28936
|
if (initialMessage) {
|
|
30765
28937
|
console.info(`\n`);
|
|
30766
|
-
console.info(spaceTrim$
|
|
28938
|
+
console.info(spaceTrim$1((block) => `
|
|
30767
28939
|
|
|
30768
28940
|
${colors.bold(colors.green('Chatbot:'))}
|
|
30769
28941
|
${block(colors.green(initialMessage))}
|
|
@@ -30786,7 +28958,7 @@ async function runInteractiveChatbot(options) {
|
|
|
30786
28958
|
type: 'text',
|
|
30787
28959
|
name: 'userMessage',
|
|
30788
28960
|
message: 'User message',
|
|
30789
|
-
hint: spaceTrim$
|
|
28961
|
+
hint: spaceTrim$1((block) => `
|
|
30790
28962
|
Type "exit" to exit,
|
|
30791
28963
|
|
|
30792
28964
|
previousTitle
|
|
@@ -30802,7 +28974,7 @@ async function runInteractiveChatbot(options) {
|
|
|
30802
28974
|
return process.exit(0);
|
|
30803
28975
|
}
|
|
30804
28976
|
console.info(`\n`);
|
|
30805
|
-
console.info(spaceTrim$
|
|
28977
|
+
console.info(spaceTrim$1((block) => `
|
|
30806
28978
|
|
|
30807
28979
|
${colors.bold(colors.blue('User:'))}
|
|
30808
28980
|
${block(colors.blue(userMessage))}
|
|
@@ -30815,7 +28987,7 @@ async function runInteractiveChatbot(options) {
|
|
|
30815
28987
|
};
|
|
30816
28988
|
const result = await pipelineExecutor(inputParameters).asPromise({ isCrashedOnError: true });
|
|
30817
28989
|
console.info(`\n`);
|
|
30818
|
-
console.info(spaceTrim$
|
|
28990
|
+
console.info(spaceTrim$1((block) => `
|
|
30819
28991
|
|
|
30820
28992
|
${colors.bold(colors.green('Chatbot:'))}
|
|
30821
28993
|
${block(colors.green(result.outputParameters.chatbotResponse))}
|
|
@@ -30846,7 +29018,7 @@ async function runInteractiveChatbot(options) {
|
|
|
30846
29018
|
*/
|
|
30847
29019
|
function $initializeRunCommand(program) {
|
|
30848
29020
|
const runCommand = program.command('run', { isDefault: true });
|
|
30849
|
-
runCommand.description(spaceTrim$
|
|
29021
|
+
runCommand.description(spaceTrim$1(`
|
|
30850
29022
|
Runs a pipeline
|
|
30851
29023
|
`));
|
|
30852
29024
|
runCommand.alias('execute');
|
|
@@ -30889,7 +29061,7 @@ function $initializeRunCommand(program) {
|
|
|
30889
29061
|
if (!error.message.includes('No LLM tools')) {
|
|
30890
29062
|
throw error;
|
|
30891
29063
|
}
|
|
30892
|
-
console.error(colors.red(spaceTrim$
|
|
29064
|
+
console.error(colors.red(spaceTrim$1((block) => `
|
|
30893
29065
|
You need to configure LLM tools first
|
|
30894
29066
|
|
|
30895
29067
|
1) Create .env file at the root of your project
|
|
@@ -30957,7 +29129,7 @@ function $initializeRunCommand(program) {
|
|
|
30957
29129
|
if (!(error instanceof ParseError)) {
|
|
30958
29130
|
throw error;
|
|
30959
29131
|
}
|
|
30960
|
-
console.error(colors.red(spaceTrim$
|
|
29132
|
+
console.error(colors.red(spaceTrim$1((block) => `
|
|
30961
29133
|
${block(error.message)}
|
|
30962
29134
|
|
|
30963
29135
|
in ${pipelineSource}
|
|
@@ -31009,7 +29181,7 @@ function $initializeRunCommand(program) {
|
|
|
31009
29181
|
};
|
|
31010
29182
|
});
|
|
31011
29183
|
if (isInteractive === false && questions.length !== 0) {
|
|
31012
|
-
console.error(colors.red(spaceTrim$
|
|
29184
|
+
console.error(colors.red(spaceTrim$1((block) => `
|
|
31013
29185
|
When using --no-interactive you need to pass all the input parameters through --json
|
|
31014
29186
|
|
|
31015
29187
|
You are missing:
|
|
@@ -31141,7 +29313,7 @@ function $initializeStartAgentsServerCommand(program) {
|
|
|
31141
29313
|
'Path to agents directory', DEFAULT_AGENTS_DIRNAME);
|
|
31142
29314
|
startServerCommand.option('--port <port>', `Port to start the server on`, '4440');
|
|
31143
29315
|
startServerCommand.option('-r, --reload', `Call LLM models even if same prompt with result is in the cache`, false);
|
|
31144
|
-
startServerCommand.description(spaceTrim$
|
|
29316
|
+
startServerCommand.description(spaceTrim$1(`
|
|
31145
29317
|
Starts a Promptbook agents server
|
|
31146
29318
|
`));
|
|
31147
29319
|
startServerCommand.alias('start');
|
|
@@ -32448,7 +30620,7 @@ function $initializeStartPipelinesServerCommand(program) {
|
|
|
32448
30620
|
// <- TODO: [🧟♂️] Unite path to promptbook collection argument
|
|
32449
30621
|
'Path to promptbook collection directory', DEFAULT_BOOKS_DIRNAME);
|
|
32450
30622
|
startServerCommand.option('--port <port>', `Port to start the server on`, '4460');
|
|
32451
|
-
startServerCommand.option('-u, --url <url>', spaceTrim$
|
|
30623
|
+
startServerCommand.option('-u, --url <url>', spaceTrim$1(`
|
|
32452
30624
|
Public root url of the server
|
|
32453
30625
|
It is used for following purposes:
|
|
32454
30626
|
|
|
@@ -32458,7 +30630,7 @@ function $initializeStartPipelinesServerCommand(program) {
|
|
|
32458
30630
|
startServerCommand.option('--allow-anonymous', `Is anonymous mode allowed`, false);
|
|
32459
30631
|
startServerCommand.option('-r, --reload', `Call LLM models even if same prompt with result is in the cache`, false);
|
|
32460
30632
|
startServerCommand.option('--no-rich-ui', `Disable rich UI`, true);
|
|
32461
|
-
startServerCommand.description(spaceTrim$
|
|
30633
|
+
startServerCommand.description(spaceTrim$1(`
|
|
32462
30634
|
Starts a remote server to execute books
|
|
32463
30635
|
|
|
32464
30636
|
Note: You want probably to use "ptbk start-agents-server" to start agents server instead of pipelines server
|
|
@@ -32549,7 +30721,7 @@ function $initializeStartPipelinesServerCommand(program) {
|
|
|
32549
30721
|
*/
|
|
32550
30722
|
function $initializeTestCommand(program) {
|
|
32551
30723
|
const testCommand = program.command('test');
|
|
32552
|
-
testCommand.description(spaceTrim$
|
|
30724
|
+
testCommand.description(spaceTrim$1(`
|
|
32553
30725
|
Iterates over \`.book.md\` and \`.bookc\` and checks if they are parsable and logically valid
|
|
32554
30726
|
`));
|
|
32555
30727
|
testCommand.argument('<filesGlob>',
|
|
@@ -32789,7 +30961,7 @@ function pricing(value) {
|
|
|
32789
30961
|
/**
|
|
32790
30962
|
* List of available Anthropic Claude models with pricing
|
|
32791
30963
|
*
|
|
32792
|
-
* Note: Synced with official API docs at
|
|
30964
|
+
* Note: Synced with official API docs at 2026-03-22
|
|
32793
30965
|
*
|
|
32794
30966
|
* @see https://docs.anthropic.com/en/docs/models-overview
|
|
32795
30967
|
* @public exported from `@promptbook/anthropic-claude`
|
|
@@ -32797,6 +30969,26 @@ function pricing(value) {
|
|
|
32797
30969
|
const ANTHROPIC_CLAUDE_MODELS = exportJson({
|
|
32798
30970
|
name: 'ANTHROPIC_CLAUDE_MODELS',
|
|
32799
30971
|
value: [
|
|
30972
|
+
{
|
|
30973
|
+
modelVariant: 'CHAT',
|
|
30974
|
+
modelTitle: 'Claude Opus 4.6',
|
|
30975
|
+
modelName: 'claude-opus-4-6',
|
|
30976
|
+
modelDescription: "Anthropic's most capable model for advanced coding, complex reasoning, and agentic workflows with 1M token context window.",
|
|
30977
|
+
pricing: {
|
|
30978
|
+
prompt: pricing(`$5.00 / 1M tokens`),
|
|
30979
|
+
output: pricing(`$25.00 / 1M tokens`),
|
|
30980
|
+
},
|
|
30981
|
+
},
|
|
30982
|
+
{
|
|
30983
|
+
modelVariant: 'CHAT',
|
|
30984
|
+
modelTitle: 'Claude Sonnet 4.6',
|
|
30985
|
+
modelName: 'claude-sonnet-4-6',
|
|
30986
|
+
modelDescription: 'Best speed and intelligence balance for production-ready workloads with 1M token context window. Ideal for high-performance, lower-latency applications.',
|
|
30987
|
+
pricing: {
|
|
30988
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
30989
|
+
output: pricing(`$15.00 / 1M tokens`),
|
|
30990
|
+
},
|
|
30991
|
+
},
|
|
32800
30992
|
{
|
|
32801
30993
|
modelVariant: 'CHAT',
|
|
32802
30994
|
modelTitle: 'Claude Sonnet 4.5',
|
|
@@ -33198,7 +31390,7 @@ class AnthropicClaudeExecutionTools {
|
|
|
33198
31390
|
getDefaultModel(defaultModelName) {
|
|
33199
31391
|
const model = ANTHROPIC_CLAUDE_MODELS.find(({ modelName }) => modelName.startsWith(defaultModelName));
|
|
33200
31392
|
if (model === undefined) {
|
|
33201
|
-
throw new UnexpectedError(spaceTrim$
|
|
31393
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
33202
31394
|
Cannot find model in Anthropic Claude models with name "${defaultModelName}" which should be used as default.
|
|
33203
31395
|
|
|
33204
31396
|
Available models:
|
|
@@ -33355,7 +31547,7 @@ const _AzureOpenAiMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
33355
31547
|
/**
|
|
33356
31548
|
* List of available OpenAI models with pricing
|
|
33357
31549
|
*
|
|
33358
|
-
* Note: Synced with official API docs at
|
|
31550
|
+
* Note: Synced with official API docs at 2026-03-22
|
|
33359
31551
|
*
|
|
33360
31552
|
* @see https://platform.openai.com/docs/models/
|
|
33361
31553
|
* @see https://openai.com/api/pricing/
|
|
@@ -33477,8 +31669,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
33477
31669
|
modelName: 'gpt-4.1',
|
|
33478
31670
|
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.',
|
|
33479
31671
|
pricing: {
|
|
33480
|
-
prompt: pricing(`$
|
|
33481
|
-
output: pricing(`$
|
|
31672
|
+
prompt: pricing(`$2.00 / 1M tokens`),
|
|
31673
|
+
output: pricing(`$8.00 / 1M tokens`),
|
|
33482
31674
|
},
|
|
33483
31675
|
},
|
|
33484
31676
|
/**/
|
|
@@ -33489,8 +31681,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
33489
31681
|
modelName: 'gpt-4.1-mini',
|
|
33490
31682
|
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.',
|
|
33491
31683
|
pricing: {
|
|
33492
|
-
prompt: pricing(`$0.
|
|
33493
|
-
output: pricing(`$
|
|
31684
|
+
prompt: pricing(`$0.40 / 1M tokens`),
|
|
31685
|
+
output: pricing(`$1.60 / 1M tokens`),
|
|
33494
31686
|
},
|
|
33495
31687
|
},
|
|
33496
31688
|
/**/
|
|
@@ -33501,8 +31693,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
33501
31693
|
modelName: 'gpt-4.1-nano',
|
|
33502
31694
|
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.',
|
|
33503
31695
|
pricing: {
|
|
33504
|
-
prompt: pricing(`$0.
|
|
33505
|
-
output: pricing(`$0.
|
|
31696
|
+
prompt: pricing(`$0.10 / 1M tokens`),
|
|
31697
|
+
output: pricing(`$0.40 / 1M tokens`),
|
|
33506
31698
|
},
|
|
33507
31699
|
},
|
|
33508
31700
|
/**/
|
|
@@ -33513,8 +31705,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
33513
31705
|
modelName: 'o3',
|
|
33514
31706
|
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.',
|
|
33515
31707
|
pricing: {
|
|
33516
|
-
prompt: pricing(`$
|
|
33517
|
-
output: pricing(`$
|
|
31708
|
+
prompt: pricing(`$2.00 / 1M tokens`),
|
|
31709
|
+
output: pricing(`$8.00 / 1M tokens`),
|
|
33518
31710
|
},
|
|
33519
31711
|
},
|
|
33520
31712
|
/**/
|
|
@@ -33525,8 +31717,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
33525
31717
|
modelName: 'o3-pro',
|
|
33526
31718
|
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.',
|
|
33527
31719
|
pricing: {
|
|
33528
|
-
prompt: pricing(`$
|
|
33529
|
-
output: pricing(`$
|
|
31720
|
+
prompt: pricing(`$20.00 / 1M tokens`),
|
|
31721
|
+
output: pricing(`$80.00 / 1M tokens`),
|
|
33530
31722
|
},
|
|
33531
31723
|
},
|
|
33532
31724
|
/**/
|
|
@@ -33537,8 +31729,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
33537
31729
|
modelName: 'o4-mini',
|
|
33538
31730
|
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.',
|
|
33539
31731
|
pricing: {
|
|
33540
|
-
prompt: pricing(`$
|
|
33541
|
-
output: pricing(`$
|
|
31732
|
+
prompt: pricing(`$1.10 / 1M tokens`),
|
|
31733
|
+
output: pricing(`$4.40 / 1M tokens`),
|
|
33542
31734
|
},
|
|
33543
31735
|
},
|
|
33544
31736
|
/**/
|
|
@@ -33896,8 +32088,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
33896
32088
|
modelName: 'gpt-4o-2024-05-13',
|
|
33897
32089
|
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.',
|
|
33898
32090
|
pricing: {
|
|
33899
|
-
prompt: pricing(`$
|
|
33900
|
-
output: pricing(`$
|
|
32091
|
+
prompt: pricing(`$2.50 / 1M tokens`),
|
|
32092
|
+
output: pricing(`$10.00 / 1M tokens`),
|
|
33901
32093
|
},
|
|
33902
32094
|
},
|
|
33903
32095
|
/**/
|
|
@@ -33908,8 +32100,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
33908
32100
|
modelName: 'gpt-4o',
|
|
33909
32101
|
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.",
|
|
33910
32102
|
pricing: {
|
|
33911
|
-
prompt: pricing(`$
|
|
33912
|
-
output: pricing(`$
|
|
32103
|
+
prompt: pricing(`$2.50 / 1M tokens`),
|
|
32104
|
+
output: pricing(`$10.00 / 1M tokens`),
|
|
33913
32105
|
},
|
|
33914
32106
|
},
|
|
33915
32107
|
/**/
|
|
@@ -33980,8 +32172,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
33980
32172
|
modelName: 'o3-mini',
|
|
33981
32173
|
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.',
|
|
33982
32174
|
pricing: {
|
|
33983
|
-
prompt: pricing(`$
|
|
33984
|
-
output: pricing(`$
|
|
32175
|
+
prompt: pricing(`$1.10 / 1M tokens`),
|
|
32176
|
+
output: pricing(`$4.40 / 1M tokens`),
|
|
33985
32177
|
},
|
|
33986
32178
|
},
|
|
33987
32179
|
/**/
|
|
@@ -34496,7 +32688,7 @@ function createExecutionToolsFromVercelProvider(options) {
|
|
|
34496
32688
|
const modelName = modelRequirements.modelName ||
|
|
34497
32689
|
((_a = availableModels.find(({ modelVariant }) => modelVariant === 'CHAT')) === null || _a === void 0 ? void 0 : _a.modelName);
|
|
34498
32690
|
if (!modelName) {
|
|
34499
|
-
throw new PipelineExecutionError(spaceTrim$
|
|
32691
|
+
throw new PipelineExecutionError(spaceTrim$1(`
|
|
34500
32692
|
Can not determine which model to use.
|
|
34501
32693
|
|
|
34502
32694
|
You need to provide at least one of:
|
|
@@ -34611,7 +32803,7 @@ function createExecutionToolsFromVercelProvider(options) {
|
|
|
34611
32803
|
/**
|
|
34612
32804
|
* List of available Deepseek models with descriptions
|
|
34613
32805
|
*
|
|
34614
|
-
* Note: Synced with official API docs at
|
|
32806
|
+
* Note: Synced with official API docs at 2026-03-22
|
|
34615
32807
|
*
|
|
34616
32808
|
* @see https://www.deepseek.com/models
|
|
34617
32809
|
* @public exported from `@promptbook/deepseek`
|
|
@@ -34625,8 +32817,8 @@ const DEEPSEEK_MODELS = exportJson({
|
|
|
34625
32817
|
modelName: 'deepseek-chat',
|
|
34626
32818
|
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.',
|
|
34627
32819
|
pricing: {
|
|
34628
|
-
prompt: pricing(`$0.
|
|
34629
|
-
output: pricing(`$0.
|
|
32820
|
+
prompt: pricing(`$0.28 / 1M tokens`),
|
|
32821
|
+
output: pricing(`$0.42 / 1M tokens`),
|
|
34630
32822
|
},
|
|
34631
32823
|
},
|
|
34632
32824
|
{
|
|
@@ -34892,7 +33084,7 @@ const _GoogleMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
34892
33084
|
/**
|
|
34893
33085
|
* List of available Google models with descriptions
|
|
34894
33086
|
*
|
|
34895
|
-
* Note: Synced with official API docs at
|
|
33087
|
+
* Note: Synced with official API docs at 2026-03-22
|
|
34896
33088
|
*
|
|
34897
33089
|
* @see https://ai.google.dev/models/gemini
|
|
34898
33090
|
* @public exported from `@promptbook/google`
|
|
@@ -34913,8 +33105,8 @@ const GOOGLE_MODELS = exportJson({
|
|
|
34913
33105
|
modelName: 'gemini-2.5-pro',
|
|
34914
33106
|
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.',
|
|
34915
33107
|
pricing: {
|
|
34916
|
-
prompt: pricing(`$
|
|
34917
|
-
output: pricing(`$
|
|
33108
|
+
prompt: pricing(`$1.25 / 1M tokens`),
|
|
33109
|
+
output: pricing(`$10.00 / 1M tokens`),
|
|
34918
33110
|
},
|
|
34919
33111
|
},
|
|
34920
33112
|
{
|
|
@@ -34923,8 +33115,8 @@ const GOOGLE_MODELS = exportJson({
|
|
|
34923
33115
|
modelName: 'gemini-2.5-flash',
|
|
34924
33116
|
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.',
|
|
34925
33117
|
pricing: {
|
|
34926
|
-
prompt: pricing(`$0.
|
|
34927
|
-
output: pricing(`$
|
|
33118
|
+
prompt: pricing(`$0.30 / 1M tokens`),
|
|
33119
|
+
output: pricing(`$2.50 / 1M tokens`),
|
|
34928
33120
|
},
|
|
34929
33121
|
},
|
|
34930
33122
|
{
|
|
@@ -34933,8 +33125,8 @@ const GOOGLE_MODELS = exportJson({
|
|
|
34933
33125
|
modelName: 'gemini-2.5-flash-lite',
|
|
34934
33126
|
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.',
|
|
34935
33127
|
pricing: {
|
|
34936
|
-
prompt: pricing(`$0.
|
|
34937
|
-
output: pricing(`$0.
|
|
33128
|
+
prompt: pricing(`$0.10 / 1M tokens`),
|
|
33129
|
+
output: pricing(`$0.40 / 1M tokens`),
|
|
34938
33130
|
},
|
|
34939
33131
|
},
|
|
34940
33132
|
{
|
|
@@ -35413,53 +33605,6 @@ resultContent, rawResponse, duration = ZERO_VALUE) {
|
|
|
35413
33605
|
* TODO: [🤝] DRY Maybe some common abstraction between `computeOpenAiUsage` and `computeAnthropicClaudeUsage`
|
|
35414
33606
|
*/
|
|
35415
33607
|
|
|
35416
|
-
/**
|
|
35417
|
-
* Maps Promptbook tools to OpenAI tools.
|
|
35418
|
-
*
|
|
35419
|
-
* @private
|
|
35420
|
-
*/
|
|
35421
|
-
function mapToolsToOpenAi(tools) {
|
|
35422
|
-
return tools.map((tool) => ({
|
|
35423
|
-
type: 'function',
|
|
35424
|
-
function: {
|
|
35425
|
-
name: tool.name,
|
|
35426
|
-
description: tool.description,
|
|
35427
|
-
parameters: tool.parameters,
|
|
35428
|
-
},
|
|
35429
|
-
}));
|
|
35430
|
-
}
|
|
35431
|
-
|
|
35432
|
-
/**
|
|
35433
|
-
* Builds a tool invocation script that injects hidden runtime context into tool args.
|
|
35434
|
-
*
|
|
35435
|
-
* @private utility of OpenAI tool execution wrappers
|
|
35436
|
-
*/
|
|
35437
|
-
function buildToolInvocationScript(options) {
|
|
35438
|
-
const { functionName, functionArgsExpression } = options;
|
|
35439
|
-
return `
|
|
35440
|
-
const args = ${functionArgsExpression};
|
|
35441
|
-
const runtimeContextRaw =
|
|
35442
|
-
typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
|
|
35443
|
-
? undefined
|
|
35444
|
-
: ${TOOL_RUNTIME_CONTEXT_PARAMETER};
|
|
35445
|
-
|
|
35446
|
-
if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
|
|
35447
|
-
args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
|
|
35448
|
-
}
|
|
35449
|
-
|
|
35450
|
-
const toolProgressTokenRaw =
|
|
35451
|
-
typeof ${TOOL_PROGRESS_TOKEN_PARAMETER} === 'undefined'
|
|
35452
|
-
? undefined
|
|
35453
|
-
: ${TOOL_PROGRESS_TOKEN_PARAMETER};
|
|
35454
|
-
|
|
35455
|
-
if (toolProgressTokenRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
|
|
35456
|
-
args.${TOOL_PROGRESS_TOKEN_ARGUMENT} = toolProgressTokenRaw;
|
|
35457
|
-
}
|
|
35458
|
-
|
|
35459
|
-
return await ${functionName}(args);
|
|
35460
|
-
`;
|
|
35461
|
-
}
|
|
35462
|
-
|
|
35463
33608
|
/**
|
|
35464
33609
|
* Parses an OpenAI error message to identify which parameter is unsupported
|
|
35465
33610
|
*
|
|
@@ -35516,6 +33661,53 @@ function isUnsupportedParameterError(error) {
|
|
|
35516
33661
|
errorMessage.includes('does not support'));
|
|
35517
33662
|
}
|
|
35518
33663
|
|
|
33664
|
+
/**
|
|
33665
|
+
* Builds a tool invocation script that injects hidden runtime context into tool args.
|
|
33666
|
+
*
|
|
33667
|
+
* @private utility of OpenAI tool execution wrappers
|
|
33668
|
+
*/
|
|
33669
|
+
function buildToolInvocationScript(options) {
|
|
33670
|
+
const { functionName, functionArgsExpression } = options;
|
|
33671
|
+
return `
|
|
33672
|
+
const args = ${functionArgsExpression};
|
|
33673
|
+
const runtimeContextRaw =
|
|
33674
|
+
typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
|
|
33675
|
+
? undefined
|
|
33676
|
+
: ${TOOL_RUNTIME_CONTEXT_PARAMETER};
|
|
33677
|
+
|
|
33678
|
+
if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
|
|
33679
|
+
args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
|
|
33680
|
+
}
|
|
33681
|
+
|
|
33682
|
+
const toolProgressTokenRaw =
|
|
33683
|
+
typeof ${TOOL_PROGRESS_TOKEN_PARAMETER} === 'undefined'
|
|
33684
|
+
? undefined
|
|
33685
|
+
: ${TOOL_PROGRESS_TOKEN_PARAMETER};
|
|
33686
|
+
|
|
33687
|
+
if (toolProgressTokenRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
|
|
33688
|
+
args.${TOOL_PROGRESS_TOKEN_ARGUMENT} = toolProgressTokenRaw;
|
|
33689
|
+
}
|
|
33690
|
+
|
|
33691
|
+
return await ${functionName}(args);
|
|
33692
|
+
`;
|
|
33693
|
+
}
|
|
33694
|
+
|
|
33695
|
+
/**
|
|
33696
|
+
* Maps Promptbook tools to OpenAI tools.
|
|
33697
|
+
*
|
|
33698
|
+
* @private
|
|
33699
|
+
*/
|
|
33700
|
+
function mapToolsToOpenAi(tools) {
|
|
33701
|
+
return tools.map((tool) => ({
|
|
33702
|
+
type: 'function',
|
|
33703
|
+
function: {
|
|
33704
|
+
name: tool.name,
|
|
33705
|
+
description: tool.description,
|
|
33706
|
+
parameters: tool.parameters,
|
|
33707
|
+
},
|
|
33708
|
+
}));
|
|
33709
|
+
}
|
|
33710
|
+
|
|
35519
33711
|
/**
|
|
35520
33712
|
* Provides access to the structured clone implementation when available.
|
|
35521
33713
|
*/
|
|
@@ -36482,7 +34674,7 @@ class OpenAiCompatibleExecutionTools {
|
|
|
36482
34674
|
// Note: Match exact or prefix for model families
|
|
36483
34675
|
const model = this.HARDCODED_MODELS.find(({ modelName }) => modelName === defaultModelName || modelName.startsWith(defaultModelName));
|
|
36484
34676
|
if (model === undefined) {
|
|
36485
|
-
throw new PipelineExecutionError(spaceTrim$
|
|
34677
|
+
throw new PipelineExecutionError(spaceTrim$1((block) => `
|
|
36486
34678
|
Cannot find model in ${this.title} models with name "${defaultModelName}" which should be used as default.
|
|
36487
34679
|
|
|
36488
34680
|
Available models:
|
|
@@ -38239,7 +36431,7 @@ class OpenAiAssistantExecutionTools extends OpenAiVectorStoreHandler {
|
|
|
38239
36431
|
assertsError(error);
|
|
38240
36432
|
const serializedError = serializeError(error);
|
|
38241
36433
|
errors = [serializedError];
|
|
38242
|
-
functionResponse = spaceTrim$
|
|
36434
|
+
functionResponse = spaceTrim$1((block) => `
|
|
38243
36435
|
|
|
38244
36436
|
The invoked tool \`${functionName}\` failed with error:
|
|
38245
36437
|
|
|
@@ -38968,7 +37160,7 @@ class BoilerplateScraper {
|
|
|
38968
37160
|
await $execCommand(command);
|
|
38969
37161
|
// Note: [0]
|
|
38970
37162
|
if (!(await isFileExisting(cacheFilehandler.filename, this.tools.fs))) {
|
|
38971
|
-
throw new UnexpectedError(spaceTrim$
|
|
37163
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
38972
37164
|
File that was supposed to be created by Pandoc does not exist for unknown reason
|
|
38973
37165
|
|
|
38974
37166
|
Expected file:
|
|
@@ -39132,7 +37324,7 @@ class DocumentScraper {
|
|
|
39132
37324
|
await $execCommand(command);
|
|
39133
37325
|
// Note: [0]
|
|
39134
37326
|
if (!(await isFileExisting(cacheFilehandler.filename, this.tools.fs))) {
|
|
39135
|
-
throw new UnexpectedError(spaceTrim$
|
|
37327
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
39136
37328
|
File that was supposed to be created by Pandoc does not exist for unknown reason
|
|
39137
37329
|
|
|
39138
37330
|
Expected file:
|
|
@@ -39283,7 +37475,7 @@ class LegacyDocumentScraper {
|
|
|
39283
37475
|
await $execCommand(command);
|
|
39284
37476
|
const files = await readdir(documentSourceOutdirPathForLibreOffice);
|
|
39285
37477
|
if (files.length !== 1) {
|
|
39286
|
-
throw new UnexpectedError(spaceTrim$
|
|
37478
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
39287
37479
|
Expected exactly 1 file in the LibreOffice output directory, got ${files.length}
|
|
39288
37480
|
|
|
39289
37481
|
The temporary folder:
|
|
@@ -39297,7 +37489,7 @@ class LegacyDocumentScraper {
|
|
|
39297
37489
|
await rename(join(documentSourceOutdirPathForLibreOffice, file), cacheFilehandler.filename);
|
|
39298
37490
|
await rmdir(documentSourceOutdirPathForLibreOffice);
|
|
39299
37491
|
if (!(await isFileExisting(cacheFilehandler.filename, this.tools.fs))) {
|
|
39300
|
-
throw new UnexpectedError(spaceTrim$
|
|
37492
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
39301
37493
|
File that was supposed to be created by LibreOffice does not exist for unknown reason
|
|
39302
37494
|
|
|
39303
37495
|
Expected file:
|
|
@@ -40564,7 +38756,7 @@ function computeAgentHash(agentSource) {
|
|
|
40564
38756
|
* @public exported from `@promptbook/core`
|
|
40565
38757
|
*/
|
|
40566
38758
|
function normalizeAgentName(rawAgentName) {
|
|
40567
|
-
return titleToName(spaceTrim$
|
|
38759
|
+
return titleToName(spaceTrim$1(rawAgentName));
|
|
40568
38760
|
}
|
|
40569
38761
|
|
|
40570
38762
|
/**
|
|
@@ -40739,7 +38931,7 @@ function parseAgentSource(agentSource) {
|
|
|
40739
38931
|
continue;
|
|
40740
38932
|
}
|
|
40741
38933
|
if (commitment.type === 'FROM') {
|
|
40742
|
-
const content = spaceTrim$
|
|
38934
|
+
const content = spaceTrim$1(commitment.content).split(/\r?\n/)[0] || '';
|
|
40743
38935
|
if (content === 'Adam' || content === '' /* <- Note: Adam is implicit */) {
|
|
40744
38936
|
continue;
|
|
40745
38937
|
}
|
|
@@ -40762,7 +38954,7 @@ function parseAgentSource(agentSource) {
|
|
|
40762
38954
|
continue;
|
|
40763
38955
|
}
|
|
40764
38956
|
if (commitment.type === 'IMPORT') {
|
|
40765
|
-
const content = spaceTrim$
|
|
38957
|
+
const content = spaceTrim$1(commitment.content).split(/\r?\n/)[0] || '';
|
|
40766
38958
|
let label = content;
|
|
40767
38959
|
let iconName = 'ExternalLink'; // Import remote
|
|
40768
38960
|
try {
|
|
@@ -40800,7 +38992,7 @@ function parseAgentSource(agentSource) {
|
|
|
40800
38992
|
continue;
|
|
40801
38993
|
}
|
|
40802
38994
|
if (commitment.type === 'KNOWLEDGE') {
|
|
40803
|
-
const content = spaceTrim$
|
|
38995
|
+
const content = spaceTrim$1(commitment.content);
|
|
40804
38996
|
const extractedUrls = extractUrlsFromText(content);
|
|
40805
38997
|
let label = content;
|
|
40806
38998
|
let iconName = 'Book';
|
|
@@ -40859,7 +39051,7 @@ function parseAgentSource(agentSource) {
|
|
|
40859
39051
|
continue;
|
|
40860
39052
|
}
|
|
40861
39053
|
if (commitment.type === 'META LINK') {
|
|
40862
|
-
const linkValue = spaceTrim$
|
|
39054
|
+
const linkValue = spaceTrim$1(commitment.content);
|
|
40863
39055
|
links.push(linkValue);
|
|
40864
39056
|
meta.link = linkValue;
|
|
40865
39057
|
continue;
|
|
@@ -40869,11 +39061,11 @@ function parseAgentSource(agentSource) {
|
|
|
40869
39061
|
continue;
|
|
40870
39062
|
}
|
|
40871
39063
|
if (commitment.type === 'META IMAGE') {
|
|
40872
|
-
meta.image = spaceTrim$
|
|
39064
|
+
meta.image = spaceTrim$1(commitment.content);
|
|
40873
39065
|
continue;
|
|
40874
39066
|
}
|
|
40875
39067
|
if (commitment.type === 'META DESCRIPTION') {
|
|
40876
|
-
meta.description = spaceTrim$
|
|
39068
|
+
meta.description = spaceTrim$1(commitment.content);
|
|
40877
39069
|
continue;
|
|
40878
39070
|
}
|
|
40879
39071
|
if (commitment.type === 'META DISCLAIMER') {
|
|
@@ -40881,7 +39073,7 @@ function parseAgentSource(agentSource) {
|
|
|
40881
39073
|
continue;
|
|
40882
39074
|
}
|
|
40883
39075
|
if (commitment.type === 'META INPUT PLACEHOLDER') {
|
|
40884
|
-
meta.inputPlaceholder = spaceTrim$
|
|
39076
|
+
meta.inputPlaceholder = spaceTrim$1(commitment.content);
|
|
40885
39077
|
continue;
|
|
40886
39078
|
}
|
|
40887
39079
|
if (commitment.type === 'MESSAGE SUFFIX') {
|
|
@@ -40897,7 +39089,7 @@ function parseAgentSource(agentSource) {
|
|
|
40897
39089
|
continue;
|
|
40898
39090
|
}
|
|
40899
39091
|
if (commitment.type === 'META VOICE') {
|
|
40900
|
-
meta.voice = spaceTrim$
|
|
39092
|
+
meta.voice = spaceTrim$1(commitment.content);
|
|
40901
39093
|
continue;
|
|
40902
39094
|
}
|
|
40903
39095
|
if (commitment.type !== 'META') {
|
|
@@ -40906,10 +39098,10 @@ function parseAgentSource(agentSource) {
|
|
|
40906
39098
|
// Parse META commitments - format is "META TYPE content"
|
|
40907
39099
|
const metaTypeRaw = commitment.content.split(' ')[0] || 'NONE';
|
|
40908
39100
|
if (metaTypeRaw === 'LINK') {
|
|
40909
|
-
links.push(spaceTrim$
|
|
39101
|
+
links.push(spaceTrim$1(commitment.content.substring(metaTypeRaw.length)));
|
|
40910
39102
|
}
|
|
40911
39103
|
const metaType = normalizeTo_camelCase(metaTypeRaw);
|
|
40912
|
-
meta[metaType] = spaceTrim$
|
|
39104
|
+
meta[metaType] = spaceTrim$1(commitment.content.substring(metaTypeRaw.length));
|
|
40913
39105
|
}
|
|
40914
39106
|
// Generate fullname fallback if no meta fullname specified
|
|
40915
39107
|
if (!meta.fullname) {
|
|
@@ -40940,7 +39132,7 @@ function parseAgentSource(agentSource) {
|
|
|
40940
39132
|
* @returns The content with normalized separators
|
|
40941
39133
|
*/
|
|
40942
39134
|
function normalizeSeparator(content) {
|
|
40943
|
-
const trimmed = spaceTrim$
|
|
39135
|
+
const trimmed = spaceTrim$1(content);
|
|
40944
39136
|
if (trimmed.includes(',')) {
|
|
40945
39137
|
return trimmed;
|
|
40946
39138
|
}
|
|
@@ -40953,7 +39145,7 @@ function normalizeSeparator(content) {
|
|
|
40953
39145
|
* @returns Normalized domain or a trimmed fallback.
|
|
40954
39146
|
*/
|
|
40955
39147
|
function normalizeMetaDomain(content) {
|
|
40956
|
-
const trimmed = spaceTrim$
|
|
39148
|
+
const trimmed = spaceTrim$1(content);
|
|
40957
39149
|
return normalizeDomainForMatching(trimmed) || trimmed.toLowerCase();
|
|
40958
39150
|
}
|
|
40959
39151
|
/**
|
|
@@ -41091,7 +39283,7 @@ const OpenAiSdkTranspiler = {
|
|
|
41091
39283
|
}
|
|
41092
39284
|
const KNOWLEDGE_THRESHOLD = 1000;
|
|
41093
39285
|
if (directKnowledge.join('\n').length > KNOWLEDGE_THRESHOLD || knowledgeSources.length > 0) {
|
|
41094
|
-
return spaceTrim$
|
|
39286
|
+
return spaceTrim$1((block) => `
|
|
41095
39287
|
#!/usr/bin/env node
|
|
41096
39288
|
|
|
41097
39289
|
import * as dotenv from 'dotenv';
|
|
@@ -41166,7 +39358,7 @@ const OpenAiSdkTranspiler = {
|
|
|
41166
39358
|
|
|
41167
39359
|
if (context) {
|
|
41168
39360
|
question = spaceTrim(\`
|
|
41169
|
-
${block(spaceTrim$
|
|
39361
|
+
${block(spaceTrim$1(`
|
|
41170
39362
|
Here is some additional context to help you answer the question:
|
|
41171
39363
|
\${context}
|
|
41172
39364
|
|
|
@@ -41247,7 +39439,7 @@ const OpenAiSdkTranspiler = {
|
|
|
41247
39439
|
})();
|
|
41248
39440
|
`);
|
|
41249
39441
|
}
|
|
41250
|
-
const source = spaceTrim$
|
|
39442
|
+
const source = spaceTrim$1((block) => `
|
|
41251
39443
|
|
|
41252
39444
|
#!/usr/bin/env node
|
|
41253
39445
|
|
|
@@ -41437,12 +39629,7 @@ const EMOJIS_OF_SINGLE_PICTOGRAM = new Set(Array.from(EMOJIS).filter((emoji) =>
|
|
|
41437
39629
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
41438
39630
|
*/
|
|
41439
39631
|
|
|
41440
|
-
// find-fresh-emoji-
|
|
41441
|
-
dotenv.config({ path: '.env' });
|
|
41442
|
-
if (process.cwd() !== join(__dirname, '../..')) {
|
|
41443
|
-
console.error(colors.red(`CWD must be root of the project`));
|
|
41444
|
-
process.exit(1);
|
|
41445
|
-
}
|
|
39632
|
+
// find-fresh-emoji-tags.ts
|
|
41446
39633
|
// Note: When run as a standalone script, call the exported function
|
|
41447
39634
|
if (require.main === module) {
|
|
41448
39635
|
findFreshEmojiTag()
|
|
@@ -41455,12 +39642,31 @@ if (require.main === module) {
|
|
|
41455
39642
|
process.exit(0);
|
|
41456
39643
|
});
|
|
41457
39644
|
}
|
|
39645
|
+
/**
|
|
39646
|
+
* Initializes environment and validates repository context for this script.
|
|
39647
|
+
*
|
|
39648
|
+
* @private utility for `findFreshEmojiTag`
|
|
39649
|
+
*/
|
|
39650
|
+
function initializeFindFreshEmojiTagRun() {
|
|
39651
|
+
dotenv.config({ path: '.env' });
|
|
39652
|
+
if (process.cwd() !== join(__dirname, '../..')) {
|
|
39653
|
+
console.error(colors.red(spaceTrim$1(`
|
|
39654
|
+
CWD must be root of the project
|
|
39655
|
+
|
|
39656
|
+
Script: find-fresh-emoji-tag.ts
|
|
39657
|
+
Current CWD: ${process.cwd()}
|
|
39658
|
+
Expected CWD: ${join(__dirname, '../..')}
|
|
39659
|
+
`)));
|
|
39660
|
+
process.exit(1);
|
|
39661
|
+
}
|
|
39662
|
+
}
|
|
41458
39663
|
/**
|
|
41459
39664
|
* Finds fresh emoji tags that are not yet used in the codebase.
|
|
41460
39665
|
*
|
|
41461
39666
|
* @public exported from `@promptbook/cli`
|
|
41462
39667
|
*/
|
|
41463
39668
|
async function findFreshEmojiTag() {
|
|
39669
|
+
initializeFindFreshEmojiTagRun();
|
|
41464
39670
|
console.info(`🤪 Find fresh emoji tag`);
|
|
41465
39671
|
const allFiles = await glob('**/*.{ts,tsx,js,jsx,json,md,txt}', {
|
|
41466
39672
|
ignore: '**/node_modules/**', // <- TODO: [🚰] Ignore also hidden folders like *(`.promptbook`, `.next`, `.git`,...)*
|
|
@@ -41500,7 +39706,7 @@ async function findFreshEmojiTag() {
|
|
|
41500
39706
|
* Note: [🟡] Code in this file should never be published outside of `@promptbook/cli`
|
|
41501
39707
|
*/
|
|
41502
39708
|
|
|
41503
|
-
var
|
|
39709
|
+
var findFreshEmojiTags = /*#__PURE__*/Object.freeze({
|
|
41504
39710
|
__proto__: null,
|
|
41505
39711
|
findFreshEmojiTag: findFreshEmojiTag
|
|
41506
39712
|
});
|
|
@@ -41729,11 +39935,6 @@ const PROMPT_SLUG_MAX_LENGTH = 80;
|
|
|
41729
39935
|
* Note: [?] Code in this file should never be published in any package
|
|
41730
39936
|
*/
|
|
41731
39937
|
|
|
41732
|
-
dotenv.config({ path: '.env' });
|
|
41733
|
-
if (process.cwd() !== join(__dirname, '../..')) {
|
|
41734
|
-
console.error(colors.red(`CWD must be root of the project`));
|
|
41735
|
-
process.exit(1);
|
|
41736
|
-
}
|
|
41737
39938
|
if (require.main === module) {
|
|
41738
39939
|
findRefactorCandidates()
|
|
41739
39940
|
.catch((error) => {
|
|
@@ -41746,12 +39947,31 @@ if (require.main === module) {
|
|
|
41746
39947
|
process.exit(0);
|
|
41747
39948
|
});
|
|
41748
39949
|
}
|
|
39950
|
+
/**
|
|
39951
|
+
* Initializes environment and validates repository context for this script.
|
|
39952
|
+
*
|
|
39953
|
+
* @private utility for `findRefactorCandidates`
|
|
39954
|
+
*/
|
|
39955
|
+
function initializeFindRefactorCandidatesRun() {
|
|
39956
|
+
dotenv.config({ path: '.env' });
|
|
39957
|
+
if (process.cwd() !== join(__dirname, '../..')) {
|
|
39958
|
+
console.error(colors.red(spaceTrim$1(`
|
|
39959
|
+
CWD must be root of the project
|
|
39960
|
+
|
|
39961
|
+
Script: find-refactor-candidates.ts
|
|
39962
|
+
Current CWD: ${process.cwd()}
|
|
39963
|
+
Expected CWD: ${join(__dirname, '../..')}
|
|
39964
|
+
`)));
|
|
39965
|
+
process.exit(1);
|
|
39966
|
+
}
|
|
39967
|
+
}
|
|
41749
39968
|
/**
|
|
41750
39969
|
* Orchestrates scanning for refactor candidates and generating prompts.
|
|
41751
39970
|
*
|
|
41752
39971
|
* @public exported from `@promptbook/cli`
|
|
41753
39972
|
*/
|
|
41754
39973
|
async function findRefactorCandidates() {
|
|
39974
|
+
initializeFindRefactorCandidatesRun();
|
|
41755
39975
|
console.info(colors.cyan('?? Find refactor candidates'));
|
|
41756
39976
|
const rootDir = process.cwd();
|
|
41757
39977
|
const promptsDir = join(rootDir, PROMPTS_DIR_NAME);
|
|
@@ -41841,7 +40061,7 @@ async function findRefactorCandidates() {
|
|
|
41841
40061
|
function buildPromptContent(candidate, emojiTag) {
|
|
41842
40062
|
const fileName = basename(candidate.relativePath);
|
|
41843
40063
|
const guidanceLines = buildPromptGuidance(candidate);
|
|
41844
|
-
return spaceTrim$
|
|
40064
|
+
return spaceTrim$1((block) => `
|
|
41845
40065
|
|
|
41846
40066
|
[ ]
|
|
41847
40067
|
|
|
@@ -42731,7 +40951,7 @@ async function pushCommittedChanges(agentEnv) {
|
|
|
42731
40951
|
}
|
|
42732
40952
|
const currentBranch = await readCurrentBranchName(agentEnv);
|
|
42733
40953
|
if (currentBranch === 'HEAD') {
|
|
42734
|
-
throw new GitPushFailedError(spaceTrim$
|
|
40954
|
+
throw new GitPushFailedError(spaceTrim$1(`
|
|
42735
40955
|
Failed to push coding-agent commit because Git is in detached HEAD mode.
|
|
42736
40956
|
|
|
42737
40957
|
Actionable hint:
|
|
@@ -42811,7 +41031,7 @@ async function resolveDefaultRemoteName(currentBranch, agentEnv) {
|
|
|
42811
41031
|
return remotes[0];
|
|
42812
41032
|
}
|
|
42813
41033
|
if (remotes.length > 1) {
|
|
42814
|
-
throw new GitPushFailedError(spaceTrim$
|
|
41034
|
+
throw new GitPushFailedError(spaceTrim$1(`
|
|
42815
41035
|
Failed to push coding-agent commit because no default remote is configured.
|
|
42816
41036
|
|
|
42817
41037
|
Available remotes: ${remotes.join(', ')}
|
|
@@ -42820,7 +41040,7 @@ async function resolveDefaultRemoteName(currentBranch, agentEnv) {
|
|
|
42820
41040
|
- Configure \`remote.pushDefault\` or \`branch.${currentBranch}.remote\`, then rerun the coding script.
|
|
42821
41041
|
`));
|
|
42822
41042
|
}
|
|
42823
|
-
throw new GitPushFailedError(spaceTrim$
|
|
41043
|
+
throw new GitPushFailedError(spaceTrim$1(`
|
|
42824
41044
|
Failed to push coding-agent commit because no Git remote is configured.
|
|
42825
41045
|
|
|
42826
41046
|
Actionable hint:
|
|
@@ -42865,7 +41085,7 @@ function buildPushFailureMessage(command, error) {
|
|
|
42865
41085
|
const details = stringifyUnknownError(error).trim() || '(No Git output)';
|
|
42866
41086
|
const hints = buildPushFailureHints(details);
|
|
42867
41087
|
const hintsMarkdown = hints.map((hint) => `- ${hint}`).join('\n');
|
|
42868
|
-
return spaceTrim$
|
|
41088
|
+
return spaceTrim$1(`
|
|
42869
41089
|
Failed to push coding-agent commit to the remote repository.
|
|
42870
41090
|
|
|
42871
41091
|
Command:
|
|
@@ -42963,7 +41183,7 @@ async function isWorkingTreeClean(path) {
|
|
|
42963
41183
|
async function ensureWorkingTreeClean() {
|
|
42964
41184
|
const isClean = await isWorkingTreeClean(process.cwd());
|
|
42965
41185
|
if (!isClean) {
|
|
42966
|
-
throw new Error(spaceTrim$
|
|
41186
|
+
throw new Error(spaceTrim$1(`
|
|
42967
41187
|
Git working tree is not clean.
|
|
42968
41188
|
|
|
42969
41189
|
Please commit or stash your changes before running this script
|
|
@@ -43081,7 +41301,7 @@ const SERVER_REGISTRY_TABLE_NAME = '_Server';
|
|
|
43081
41301
|
function parseServerRecord(rawRow, label = 'row') {
|
|
43082
41302
|
const rawEnvironment = typeof rawRow.environment === 'string' ? rawRow.environment.trim().toUpperCase() : '';
|
|
43083
41303
|
if (!isServerEnvironment(rawEnvironment)) {
|
|
43084
|
-
throw new DatabaseError(spaceTrim$
|
|
41304
|
+
throw new DatabaseError(spaceTrim$1(`
|
|
43085
41305
|
Invalid \`${SERVER_REGISTRY_TABLE_NAME}\` ${label}.
|
|
43086
41306
|
|
|
43087
41307
|
Field \`environment\` must be one of \`${SERVER_ENVIRONMENT.PRODUCTION}\`, \`${SERVER_ENVIRONMENT.PREVIEW}\`, \`${SERVER_ENVIRONMENT.LTS}\` or \`${SERVER_ENVIRONMENT.LIVE}\`.
|
|
@@ -43090,7 +41310,7 @@ function parseServerRecord(rawRow, label = 'row') {
|
|
|
43090
41310
|
const domain = typeof rawRow.domain === 'string' ? rawRow.domain.trim().toLowerCase() : '';
|
|
43091
41311
|
const normalizedDomain = normalizeServerDomain(domain);
|
|
43092
41312
|
if (!normalizedDomain) {
|
|
43093
|
-
throw new DatabaseError(spaceTrim$
|
|
41313
|
+
throw new DatabaseError(spaceTrim$1(`
|
|
43094
41314
|
Invalid \`${SERVER_REGISTRY_TABLE_NAME}\` ${label}.
|
|
43095
41315
|
|
|
43096
41316
|
Field \`domain\` must contain a valid host or URL-like domain string.
|
|
@@ -43104,7 +41324,7 @@ function parseServerRecord(rawRow, label = 'row') {
|
|
|
43104
41324
|
const updatedAt = typeof rawRow.updatedAt === 'string' ? rawRow.updatedAt : '';
|
|
43105
41325
|
const id = typeof rawRow.id === 'number' ? rawRow.id : Number(rawRow.id);
|
|
43106
41326
|
if (!name || !hasTablePrefix /*|| !createdAt || !updatedAt ||*/ || !Number.isFinite(id)) {
|
|
43107
|
-
throw new DatabaseError(spaceTrim$
|
|
41327
|
+
throw new DatabaseError(spaceTrim$1(`
|
|
43108
41328
|
Invalid \`${SERVER_REGISTRY_TABLE_NAME}\` ${label}.
|
|
43109
41329
|
|
|
43110
41330
|
Fields \`id\`, \`name\`, \`tablePrefix\`, \`createdAt\`, and \`updatedAt\` are required.
|
|
@@ -43224,7 +41444,7 @@ async function listRegisteredServersFromDatabase(client) {
|
|
|
43224
41444
|
if (isMissingServerRegistryError(error)) {
|
|
43225
41445
|
return [];
|
|
43226
41446
|
}
|
|
43227
|
-
throw new DatabaseError(spaceTrim$
|
|
41447
|
+
throw new DatabaseError(spaceTrim$1((block) => `
|
|
43228
41448
|
Failed to query global server registry table \`_Server\`.
|
|
43229
41449
|
|
|
43230
41450
|
${block(error instanceof Error ? error.message : String(error))}
|
|
@@ -43409,7 +41629,7 @@ function selectPrefixesForMigration(configuredPrefixes, registeredServers, onlyT
|
|
|
43409
41629
|
invalidTargets.push(onlyTarget);
|
|
43410
41630
|
}
|
|
43411
41631
|
if (invalidTargets.length > 0) {
|
|
43412
|
-
throw new DatabaseError(spaceTrim$
|
|
41632
|
+
throw new DatabaseError(spaceTrim$1(`
|
|
43413
41633
|
Invalid migration targets specified in \`--only\`: ${invalidTargets
|
|
43414
41634
|
.map((target) => `\`${target}\``)
|
|
43415
41635
|
.join(', ')}.
|
|
@@ -43517,7 +41737,7 @@ const DATABASE_CONNECTION_ENV_NAMES = ['POSTGRES_URL', 'DATABASE_URL'];
|
|
|
43517
41737
|
async function resolveDatabaseMigrationRuntimeConfiguration(logger = console) {
|
|
43518
41738
|
const connectionString = resolveDatabaseMigrationConnectionStringFromEnvironment();
|
|
43519
41739
|
if (!connectionString) {
|
|
43520
|
-
throw new DatabaseError(spaceTrim$
|
|
41740
|
+
throw new DatabaseError(spaceTrim$1(`
|
|
43521
41741
|
${DATABASE_CONNECTION_ENV_NAMES.join(' or ')} is not defined.
|
|
43522
41742
|
`));
|
|
43523
41743
|
}
|
|
@@ -43879,7 +42099,7 @@ function createDestructiveAutoMigrationBlockedError(findings) {
|
|
|
43879
42099
|
.map((match) => `${getReadableRuleName(match.rule)}: ${createSqlStatementPreview(match.statement)}`)
|
|
43880
42100
|
.join(' | ')})`)
|
|
43881
42101
|
.join('\n');
|
|
43882
|
-
return new DatabaseError(spaceTrim$
|
|
42102
|
+
return new DatabaseError(spaceTrim$1((block) => `
|
|
43883
42103
|
Auto-migration blocked because pending testing-server migrations contain potentially destructive SQL.
|
|
43884
42104
|
|
|
43885
42105
|
Review these migration statements:
|
|
@@ -45643,7 +43863,7 @@ function getRunnerMetadata(options, actualModel) {
|
|
|
45643
43863
|
async function runCodexPrompts(providedOptions) {
|
|
45644
43864
|
const options = providedOptions !== null && providedOptions !== void 0 ? providedOptions : parseRunOptions(process.argv.slice(2));
|
|
45645
43865
|
if (options.allowDestructiveAutoMigrate && !options.autoMigrate) {
|
|
45646
|
-
throw new DatabaseError(spaceTrim$
|
|
43866
|
+
throw new DatabaseError(spaceTrim$1(`
|
|
45647
43867
|
Flag \`--allow-destructive-auto-migrate\` requires \`--auto-migrate\`.
|
|
45648
43868
|
`));
|
|
45649
43869
|
}
|
|
@@ -46297,7 +44517,7 @@ function validateBook(source) {
|
|
|
46297
44517
|
* @deprecated Use `$generateBookBoilerplate` instead
|
|
46298
44518
|
* @public exported from `@promptbook/core`
|
|
46299
44519
|
*/
|
|
46300
|
-
padBook(validateBook(spaceTrim$
|
|
44520
|
+
padBook(validateBook(spaceTrim$1(`
|
|
46301
44521
|
AI Avatar
|
|
46302
44522
|
|
|
46303
44523
|
PERSONA A friendly AI assistant that helps you with your tasks
|
|
@@ -46324,7 +44544,7 @@ function book(strings, ...values) {
|
|
|
46324
44544
|
const bookString = prompt(strings, ...values).toString();
|
|
46325
44545
|
if (!isValidPipelineString(bookString)) {
|
|
46326
44546
|
// TODO: Make the CustomError for this
|
|
46327
|
-
throw new Error(spaceTrim$
|
|
44547
|
+
throw new Error(spaceTrim$1(`
|
|
46328
44548
|
The string is not a valid pipeline string
|
|
46329
44549
|
|
|
46330
44550
|
book\`
|
|
@@ -46334,7 +44554,7 @@ function book(strings, ...values) {
|
|
|
46334
44554
|
}
|
|
46335
44555
|
if (!isValidBook(bookString)) {
|
|
46336
44556
|
// TODO: Make the CustomError for this
|
|
46337
|
-
throw new Error(spaceTrim$
|
|
44557
|
+
throw new Error(spaceTrim$1(`
|
|
46338
44558
|
The string is not a valid book
|
|
46339
44559
|
|
|
46340
44560
|
book\`
|
|
@@ -47260,7 +45480,7 @@ function promptbookifyAiText(text) {
|
|
|
47260
45480
|
* TODO: [🧠][✌️] Make some Promptbook-native token system
|
|
47261
45481
|
*/
|
|
47262
45482
|
|
|
47263
|
-
const DEFAULT_AGENT_KIT_MODEL_NAME = 'gpt-5-
|
|
45483
|
+
const DEFAULT_AGENT_KIT_MODEL_NAME = 'gpt-5.4-nano';
|
|
47264
45484
|
/**
|
|
47265
45485
|
* Creates one structured log entry for streamed tool-call updates.
|
|
47266
45486
|
*
|
|
@@ -47755,7 +45975,7 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
|
|
|
47755
45975
|
}),
|
|
47756
45976
|
],
|
|
47757
45977
|
};
|
|
47758
|
-
const errorMessage = spaceTrim$
|
|
45978
|
+
const errorMessage = spaceTrim$1((block) => `
|
|
47759
45979
|
|
|
47760
45980
|
The invoked tool \`${functionName}\` failed with error:
|
|
47761
45981
|
|
|
@@ -48705,7 +46925,7 @@ class SelfLearningManager {
|
|
|
48705
46925
|
if (isJsonSchemaResponseFormat(responseFormat)) {
|
|
48706
46926
|
const jsonSchema = responseFormat.json_schema;
|
|
48707
46927
|
const schemaJson = JSON.stringify(jsonSchema, null, 4);
|
|
48708
|
-
userMessageContent = spaceTrim$
|
|
46928
|
+
userMessageContent = spaceTrim$1((block) => `
|
|
48709
46929
|
${block(prompt.content)}
|
|
48710
46930
|
|
|
48711
46931
|
NOTE Request was made through OpenAI Compatible API with \`response_format\` of type \`json_schema\` with the following schema:
|
|
@@ -48736,12 +46956,12 @@ class SelfLearningManager {
|
|
|
48736
46956
|
const formattedAgentMessage = formatAgentMessageForJsonMode(result.content, usesJsonSchemaMode);
|
|
48737
46957
|
const teacherInstructions = extractOpenTeacherInstructions(agentSource);
|
|
48738
46958
|
const teacherInstructionsSection = teacherInstructions
|
|
48739
|
-
? spaceTrim$
|
|
46959
|
+
? spaceTrim$1((block) => `
|
|
48740
46960
|
**Teacher instructions:**
|
|
48741
46961
|
${block(teacherInstructions)}
|
|
48742
46962
|
`)
|
|
48743
46963
|
: '';
|
|
48744
|
-
const teacherPromptContent = spaceTrim$
|
|
46964
|
+
const teacherPromptContent = spaceTrim$1((block) => `
|
|
48745
46965
|
|
|
48746
46966
|
You are a teacher agent helping another agent to learn from its interactions.
|
|
48747
46967
|
|
|
@@ -48774,7 +46994,7 @@ class SelfLearningManager {
|
|
|
48774
46994
|
? '- This interaction used JSON mode, so the agent answer should stay as a formatted JSON code block.'
|
|
48775
46995
|
: ''}
|
|
48776
46996
|
${block(isInitialMessageMissing
|
|
48777
|
-
? spaceTrim$
|
|
46997
|
+
? spaceTrim$1(`
|
|
48778
46998
|
- The agent source does not have an INITIAL MESSAGE defined, generate one.
|
|
48779
46999
|
- 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.
|
|
48780
47000
|
- The quick option looks like \`[👋 Hello](?message=Hello, how are you?)\`
|
|
@@ -48817,7 +47037,7 @@ class SelfLearningManager {
|
|
|
48817
47037
|
*/
|
|
48818
47038
|
appendToAgentSource(section) {
|
|
48819
47039
|
const currentSource = this.options.getAgentSource();
|
|
48820
|
-
const newSource = padBook(validateBook(spaceTrim$
|
|
47040
|
+
const newSource = padBook(validateBook(spaceTrim$1(currentSource) + section));
|
|
48821
47041
|
this.options.updateAgentSource(newSource);
|
|
48822
47042
|
}
|
|
48823
47043
|
}
|
|
@@ -48845,13 +47065,13 @@ function formatAgentMessageForJsonMode(content, isJsonMode) {
|
|
|
48845
47065
|
}
|
|
48846
47066
|
const parsedJson = tryParseJson(content);
|
|
48847
47067
|
if (parsedJson === null) {
|
|
48848
|
-
return spaceTrim$
|
|
47068
|
+
return spaceTrim$1((block) => `
|
|
48849
47069
|
\`\`\`json
|
|
48850
47070
|
${block(content)}
|
|
48851
47071
|
\`\`\`
|
|
48852
47072
|
`);
|
|
48853
47073
|
}
|
|
48854
|
-
return spaceTrim$
|
|
47074
|
+
return spaceTrim$1((block) => `
|
|
48855
47075
|
\`\`\`json
|
|
48856
47076
|
${block(JSON.stringify(parsedJson, null, 4))}
|
|
48857
47077
|
\`\`\`
|
|
@@ -48883,7 +47103,7 @@ function formatSelfLearningSample(options) {
|
|
|
48883
47103
|
const internalMessagesSection = options.internalMessages
|
|
48884
47104
|
.map((internalMessage) => formatInternalLearningMessage(internalMessage))
|
|
48885
47105
|
.join('\n\n');
|
|
48886
|
-
return spaceTrim$
|
|
47106
|
+
return spaceTrim$1((block) => `
|
|
48887
47107
|
|
|
48888
47108
|
USER MESSAGE
|
|
48889
47109
|
${block(options.userMessageContent)}
|
|
@@ -48901,7 +47121,7 @@ function formatSelfLearningSample(options) {
|
|
|
48901
47121
|
* @private function of Agent
|
|
48902
47122
|
*/
|
|
48903
47123
|
function formatInternalLearningMessage(internalMessage) {
|
|
48904
|
-
return spaceTrim$
|
|
47124
|
+
return spaceTrim$1((block) => `
|
|
48905
47125
|
INTERNAL MESSAGE
|
|
48906
47126
|
${block(stringifyInternalLearningPayload(internalMessage))}
|
|
48907
47127
|
`);
|
|
@@ -49367,7 +47587,7 @@ function buildRemoteAgentSource(profile, meta) {
|
|
|
49367
47587
|
.filter((line) => Boolean(line))
|
|
49368
47588
|
.join('\n');
|
|
49369
47589
|
const personaBlock = profile.personaDescription
|
|
49370
|
-
? spaceTrim$
|
|
47590
|
+
? spaceTrim$1((block) => `
|
|
49371
47591
|
PERSONA
|
|
49372
47592
|
${block(profile.personaDescription || '')}
|
|
49373
47593
|
`)
|
|
@@ -49403,7 +47623,7 @@ class RemoteAgent extends Agent {
|
|
|
49403
47623
|
// <- TODO: [🐱🚀] What about closed-source agents?
|
|
49404
47624
|
// <- TODO: [🐱🚀] Maybe use promptbookFetch
|
|
49405
47625
|
if (!profileResponse.ok) {
|
|
49406
|
-
throw new Error(spaceTrim$
|
|
47626
|
+
throw new Error(spaceTrim$1((block) => `
|
|
49407
47627
|
Failed to fetch remote agent profile:
|
|
49408
47628
|
|
|
49409
47629
|
Agent URL:
|