@promptbook/cli 0.112.0 → 0.113.0-1
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/README.md +45 -29
- package/agents/default/developer.book +2 -1
- package/apps/agents-server/next.config.ts +21 -0
- package/apps/agents-server/src/app/admin/limits/LimitsClient.tsx +1 -1
- package/apps/agents-server/src/app/admin/task-manager/TaskManagerTaskRow.tsx +7 -2
- package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +52 -33
- package/apps/agents-server/src/app/api/agent-folders/[folderId]/visibility/route.ts +19 -7
- package/apps/agents-server/src/app/api/agents/[agentName]/route.ts +8 -18
- package/apps/agents-server/src/app/api/internal/agent-runner-limits/route.ts +1 -1
- package/apps/agents-server/src/app/api/page-preview/check/route.ts +5 -20
- package/apps/agents-server/src/app/api/page-preview/interact/route.ts +179 -0
- package/apps/agents-server/src/app/api/page-preview/live/route.ts +67 -0
- package/apps/agents-server/src/app/api/page-preview/screenshot/route.ts +13 -21
- package/apps/agents-server/src/app/api/v1/agents/[agentId]/route.ts +13 -8
- package/apps/agents-server/src/components/AgentProfile/AgentCapabilityChips.tsx +39 -5
- package/apps/agents-server/src/components/Homepage/AgentCard.tsx +7 -1
- package/apps/agents-server/src/components/Homepage/AgentsList.tsx +3 -0
- package/apps/agents-server/src/components/Homepage/AgentsListHeader.tsx +41 -0
- package/apps/agents-server/src/components/Homepage/hiddenFolders.ts +104 -0
- package/apps/agents-server/src/components/Homepage/useAgentsListQueryState.ts +35 -0
- package/apps/agents-server/src/components/Homepage/useAgentsListState.ts +24 -4
- package/apps/agents-server/src/constants/chatVisualMode.ts +1 -1
- package/apps/agents-server/src/constants/serverLimits.ts +19 -0
- package/apps/agents-server/src/constants/themeMode.ts +1 -1
- package/apps/agents-server/src/database/migrations/2026-05-2600-default-theme.sql +2 -2
- package/apps/agents-server/src/database/seedCoreAgents.ts +0 -2
- package/apps/agents-server/src/database/seedDefaultAgents.ts +0 -2
- package/apps/agents-server/src/tools/agent_progress.ts +4 -10
- package/apps/agents-server/src/utils/agentVisibility.ts +25 -62
- package/apps/agents-server/src/utils/chatTasksAdmin.ts +3 -1
- package/apps/agents-server/src/utils/createAgentWithDefaultVisibility.ts +3 -1
- package/apps/agents-server/src/utils/externalChatRunner/processExternalUserChatJob.ts +9 -17
- package/apps/agents-server/src/utils/getAdminChatTasksResponse/mapVpsSelfUpdateJobToAdminChatTask.ts +84 -0
- package/apps/agents-server/src/utils/getAdminChatTasksResponse.ts +195 -5
- package/apps/agents-server/src/utils/localChatRunner/LocalUserChatJobMetadata.ts +15 -5
- package/apps/agents-server/src/utils/localChatRunner/processLocalUserChatJob.ts +17 -26
- package/apps/agents-server/src/utils/pagePreview/livePagePreviewSessions.ts +365 -0
- package/apps/agents-server/src/utils/pagePreview/resolvePagePreviewRequestUrl.ts +74 -0
- package/apps/agents-server/src/utils/serverLimits.ts +2 -0
- package/apps/agents-server/src/utils/serverManagement/createManagedServer/seedServerCoreAgents.ts +2 -2
- package/apps/agents-server/src/utils/serverManagement/createManagedServer/seedServerDefaultAgents.ts +1 -1
- package/apps/agents-server/src/utils/userChat/createUserChatHarnessProgressCard.ts +0 -6
- package/apps/agents-server/src/utils/userChat/createUserChatRunnerProgressCard.ts +0 -6
- package/apps/agents-server/src/utils/userChat/userChatMessageLifecycle.ts +69 -0
- package/apps/agents-server/src/utils/userChat/userChatProgressCard.ts +0 -6
- package/apps/agents-server/src/utils/vpsSelfUpdate.ts +150 -24
- package/esm/apps/agents-server/src/constants/serverLimits.d.ts +17 -0
- package/esm/index.es.js +581 -93
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-agent-messages/main/runMultipleAgentMessages.d.ts +1 -0
- package/esm/scripts/run-agent-messages/main/tickAgentMessages.d.ts +1 -0
- package/esm/src/_packages/core.index.d.ts +22 -0
- package/esm/src/_packages/types.index.d.ts +2 -0
- package/esm/src/book-2.0/agent-source/AgentBasicInformation.d.ts +2 -0
- package/esm/src/book-2.0/agent-source/agentSourceVisibility.d.ts +97 -0
- package/esm/src/book-2.0/agent-source/agentSourceVisibility.test.d.ts +1 -0
- package/esm/src/book-components/BookEditor/BookEditorMonacoTokenization.d.ts +1 -0
- package/esm/src/book-components/Chat/Chat/CitationIframePreview.d.ts +2 -2
- package/esm/src/book-components/Chat/utils/livePagePreviewConstants.d.ts +12 -0
- package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +6 -0
- package/esm/src/collection/agent-collection/CreateAgentInput.d.ts +2 -1
- package/esm/src/collection/agent-collection/constructors/agent-collection-in-supabase/prepareAgentSourceForPersistence.d.ts +21 -1
- package/esm/src/commitments/META_VISIBILITY/META_VISIBILITY.d.ts +27 -0
- package/esm/src/commitments/index.d.ts +2 -1
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/_packages/core.index.ts +22 -0
- package/src/_packages/types.index.ts +2 -0
- package/src/book-2.0/agent-source/AgentBasicInformation.ts +2 -0
- package/src/book-2.0/agent-source/agentSourceVisibility.ts +214 -0
- package/src/book-2.0/agent-source/parseAgentSource/applyMetaCommitment.ts +17 -0
- package/src/book-2.0/book-language-documentation/createStandaloneBookLanguageMarkdown.ts +1 -0
- package/src/book-components/BookEditor/BookEditorMonacoTokenization.ts +11 -0
- package/src/book-components/BookEditor/useBookEditorMonacoLanguage.ts +7 -3
- package/src/book-components/Chat/Chat/Chat.module.css +14 -5
- package/src/book-components/Chat/Chat/CitationIframePreview.tsx +197 -22
- package/src/book-components/Chat/utils/livePagePreviewConstants.ts +17 -0
- package/src/cli/cli-commands/agents-server/buildAgentsServer.ts +144 -16
- package/src/cli/cli-commands/agents-server/startAgentsServer.ts +22 -2
- package/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.ts +1 -1
- package/src/cli/cli-commands/coder/run.ts +30 -0
- package/src/collection/agent-collection/CreateAgentInput.ts +10 -5
- package/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.ts +7 -3
- package/src/collection/agent-collection/constructors/agent-collection-in-supabase/createAgentPersistenceRecords.ts +7 -4
- package/src/collection/agent-collection/constructors/agent-collection-in-supabase/prepareAgentSourceForPersistence.ts +44 -8
- package/src/commitments/META_VISIBILITY/META_VISIBILITY.ts +78 -0
- package/src/commitments/index.ts +2 -0
- package/src/other/templates/getTemplatesPipelineCollection.ts +826 -650
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -0
- package/umd/apps/agents-server/src/constants/serverLimits.d.ts +17 -0
- package/umd/index.umd.js +581 -93
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-agent-messages/main/runMultipleAgentMessages.d.ts +1 -0
- package/umd/scripts/run-agent-messages/main/tickAgentMessages.d.ts +1 -0
- package/umd/src/_packages/core.index.d.ts +22 -0
- package/umd/src/_packages/types.index.d.ts +2 -0
- package/umd/src/book-2.0/agent-source/AgentBasicInformation.d.ts +2 -0
- package/umd/src/book-2.0/agent-source/agentSourceVisibility.d.ts +97 -0
- package/umd/src/book-2.0/agent-source/agentSourceVisibility.test.d.ts +1 -0
- package/umd/src/book-components/BookEditor/BookEditorMonacoTokenization.d.ts +1 -0
- package/umd/src/book-components/Chat/Chat/CitationIframePreview.d.ts +2 -2
- package/umd/src/book-components/Chat/utils/livePagePreviewConstants.d.ts +12 -0
- package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +6 -0
- package/umd/src/collection/agent-collection/CreateAgentInput.d.ts +2 -1
- package/umd/src/collection/agent-collection/constructors/agent-collection-in-supabase/prepareAgentSourceForPersistence.d.ts +21 -1
- package/umd/src/commitments/META_VISIBILITY/META_VISIBILITY.d.ts +27 -0
- package/umd/src/commitments/index.d.ts +2 -1
- package/umd/src/version.d.ts +1 -1
package/esm/index.es.js
CHANGED
|
@@ -59,7 +59,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
59
59
|
* @generated
|
|
60
60
|
* @see https://github.com/webgptorg/promptbook
|
|
61
61
|
*/
|
|
62
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.
|
|
62
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.113.0-1';
|
|
63
63
|
/**
|
|
64
64
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
65
65
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -3299,6 +3299,28 @@ const DEFAULT_AGENTS_SERVER_NEXT_DIST_DIRECTORY_NAME = '.next';
|
|
|
3299
3299
|
* @private internal constant of `ptbk agents-server`
|
|
3300
3300
|
*/
|
|
3301
3301
|
const AGENTS_SERVER_BUILD_MAX_OLD_SPACE_MIB = 4096;
|
|
3302
|
+
/**
|
|
3303
|
+
* Conservative Next.js build worker count used by CLI-owned Agents Server production builds.
|
|
3304
|
+
*
|
|
3305
|
+
* Standalone VPS self-updates build the replacement server while the current pm2 process is
|
|
3306
|
+
* still serving traffic. Keeping Next's static workers serial avoids CPU-count-based memory
|
|
3307
|
+
* spikes that can make the OS kill the build child with no normal exit code.
|
|
3308
|
+
*
|
|
3309
|
+
* @private internal constant of `ptbk agents-server`
|
|
3310
|
+
*/
|
|
3311
|
+
const AGENTS_SERVER_BUILD_WORKER_COUNT = 1;
|
|
3312
|
+
/**
|
|
3313
|
+
* Maximum attempts for a Next.js build that was killed by the operating system.
|
|
3314
|
+
*
|
|
3315
|
+
* @private internal constant of `ptbk agents-server`
|
|
3316
|
+
*/
|
|
3317
|
+
const AGENTS_SERVER_BUILD_MAX_ATTEMPTS = 2;
|
|
3318
|
+
/**
|
|
3319
|
+
* Signals that indicate the Next.js build may have been terminated by resource pressure.
|
|
3320
|
+
*
|
|
3321
|
+
* @private internal constant of `ptbk agents-server`
|
|
3322
|
+
*/
|
|
3323
|
+
const RETRYABLE_NEXT_BUILD_SIGNALS = new Set(['SIGKILL', null]);
|
|
3302
3324
|
/**
|
|
3303
3325
|
* Environment variable passed to the bundled Next app so webpack can resolve dependencies
|
|
3304
3326
|
* installed beside `ptbk` even when the app sources are materialized into a project cache.
|
|
@@ -3306,6 +3328,12 @@ const AGENTS_SERVER_BUILD_MAX_OLD_SPACE_MIB = 4096;
|
|
|
3306
3328
|
* @private internal constant of `ptbk agents-server`
|
|
3307
3329
|
*/
|
|
3308
3330
|
const PTBK_AGENTS_SERVER_NODE_MODULES_PATH_ENV = 'PTBK_AGENTS_SERVER_NODE_MODULES_PATH';
|
|
3331
|
+
/**
|
|
3332
|
+
* Environment variable consumed by `apps/agents-server/next.config.ts` to throttle build workers.
|
|
3333
|
+
*
|
|
3334
|
+
* @private internal constant of `ptbk agents-server`
|
|
3335
|
+
*/
|
|
3336
|
+
const PTBK_AGENTS_SERVER_BUILD_WORKER_COUNT_ENV = 'PTBK_AGENTS_SERVER_BUILD_WORKER_COUNT';
|
|
3309
3337
|
/**
|
|
3310
3338
|
* Environment variable used only by the CLI-owned production build.
|
|
3311
3339
|
*
|
|
@@ -3506,6 +3534,7 @@ function createAgentsServerRuntimeEnvironment(environment, nodeModulesPath, opti
|
|
|
3506
3534
|
...environment,
|
|
3507
3535
|
NODE_PATH: mergeNodePath(nodeModulesPath, environment.NODE_PATH),
|
|
3508
3536
|
[PTBK_AGENTS_SERVER_NODE_MODULES_PATH_ENV]: nodeModulesPath,
|
|
3537
|
+
[PTBK_AGENTS_SERVER_BUILD_WORKER_COUNT_ENV]: environment[PTBK_AGENTS_SERVER_BUILD_WORKER_COUNT_ENV] || String(AGENTS_SERVER_BUILD_WORKER_COUNT),
|
|
3509
3538
|
...(options.isNextValidationIgnored
|
|
3510
3539
|
? {
|
|
3511
3540
|
[PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION_ENV]: 'true',
|
|
@@ -3692,14 +3721,27 @@ async function writeAgentsServerMaterializedRuntimeCache(materializedRuntimeRoot
|
|
|
3692
3721
|
* Runs the finite Next production build used by local Agents Server commands.
|
|
3693
3722
|
*/
|
|
3694
3723
|
async function runNextBuild(options) {
|
|
3695
|
-
|
|
3724
|
+
for (let attempt = 1; attempt <= AGENTS_SERVER_BUILD_MAX_ATTEMPTS; attempt++) {
|
|
3725
|
+
const exitStatus = await runNextBuildAttempt(options);
|
|
3726
|
+
if (exitStatus.code === 0) {
|
|
3727
|
+
return;
|
|
3728
|
+
}
|
|
3729
|
+
if (attempt < AGENTS_SERVER_BUILD_MAX_ATTEMPTS && isNextBuildTerminationRetryable(exitStatus)) {
|
|
3730
|
+
forwardBuildOutput(createNextBuildRetryMessage(exitStatus, attempt + 1), options.onBuildOutput);
|
|
3731
|
+
continue;
|
|
3732
|
+
}
|
|
3733
|
+
throw createNextBuildExitError(exitStatus, attempt);
|
|
3734
|
+
}
|
|
3735
|
+
}
|
|
3736
|
+
/**
|
|
3737
|
+
* Runs one Next.js production build attempt and returns its exit status.
|
|
3738
|
+
*/
|
|
3739
|
+
async function runNextBuildAttempt(options) {
|
|
3740
|
+
return await new Promise((resolveBuild, rejectBuild) => {
|
|
3696
3741
|
var _a, _b;
|
|
3697
3742
|
const buildProcess = spawn(process.execPath, [options.nextCliPath, 'build'], {
|
|
3698
3743
|
cwd: options.appPath,
|
|
3699
|
-
env:
|
|
3700
|
-
...options.environment,
|
|
3701
|
-
NODE_OPTIONS: mergeNodeOptionsWithHeapSize(options.environment.NODE_OPTIONS, AGENTS_SERVER_BUILD_MAX_OLD_SPACE_MIB),
|
|
3702
|
-
},
|
|
3744
|
+
env: createNextBuildProcessEnvironment(options.environment),
|
|
3703
3745
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
3704
3746
|
});
|
|
3705
3747
|
(_a = buildProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (chunk) => {
|
|
@@ -3708,16 +3750,70 @@ async function runNextBuild(options) {
|
|
|
3708
3750
|
(_b = buildProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (chunk) => {
|
|
3709
3751
|
forwardBuildOutput(chunk.toString(), options.onBuildOutput);
|
|
3710
3752
|
});
|
|
3711
|
-
buildProcess.once('error',
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
}
|
|
3717
|
-
rejectBuild(new Error(`next-build exited with code ${String(code)}.`));
|
|
3753
|
+
buildProcess.once('error', (error) => {
|
|
3754
|
+
rejectBuild(createNextBuildSpawnError(error));
|
|
3755
|
+
});
|
|
3756
|
+
buildProcess.once('close', (code, signal) => {
|
|
3757
|
+
resolveBuild({ code, signal });
|
|
3718
3758
|
});
|
|
3719
3759
|
});
|
|
3720
3760
|
}
|
|
3761
|
+
/**
|
|
3762
|
+
* Creates the environment passed to the spawned Next.js build process.
|
|
3763
|
+
*/
|
|
3764
|
+
function createNextBuildProcessEnvironment(environment) {
|
|
3765
|
+
return {
|
|
3766
|
+
...environment,
|
|
3767
|
+
NODE_OPTIONS: mergeNodeOptionsWithHeapSize(environment.NODE_OPTIONS, AGENTS_SERVER_BUILD_MAX_OLD_SPACE_MIB),
|
|
3768
|
+
};
|
|
3769
|
+
}
|
|
3770
|
+
/**
|
|
3771
|
+
* Returns true when one failed build attempt is worth retrying.
|
|
3772
|
+
*/
|
|
3773
|
+
function isNextBuildTerminationRetryable(exitStatus) {
|
|
3774
|
+
return exitStatus.code === null && RETRYABLE_NEXT_BUILD_SIGNALS.has(exitStatus.signal);
|
|
3775
|
+
}
|
|
3776
|
+
/**
|
|
3777
|
+
* Creates one visible retry message for a killed Next.js build attempt.
|
|
3778
|
+
*/
|
|
3779
|
+
function createNextBuildRetryMessage(exitStatus, nextAttempt) {
|
|
3780
|
+
return `\nAgents Server Next build was terminated by ${describeNextBuildExitStatus(exitStatus)}. Retrying attempt ${nextAttempt}/${AGENTS_SERVER_BUILD_MAX_ATTEMPTS}.\n`;
|
|
3781
|
+
}
|
|
3782
|
+
/**
|
|
3783
|
+
* Creates a branded error for a failed Next.js build child process.
|
|
3784
|
+
*/
|
|
3785
|
+
function createNextBuildExitError(exitStatus, attemptCount) {
|
|
3786
|
+
const lowMemoryHint = isNextBuildTerminationRetryable(exitStatus)
|
|
3787
|
+
? '\n\nThe build process was terminated by the operating system. On standalone VPS self-updates this usually means the host ran out of memory while Next.js was compiling or prerendering the app.'
|
|
3788
|
+
: '';
|
|
3789
|
+
return new NotAllowed(spaceTrim$1(`
|
|
3790
|
+
Agents Server Next production build failed.
|
|
3791
|
+
|
|
3792
|
+
- Exit code: \`${String(exitStatus.code)}\`
|
|
3793
|
+
- Signal: \`${String(exitStatus.signal)}\`
|
|
3794
|
+
- Attempts: \`${String(attemptCount)}\`
|
|
3795
|
+
${lowMemoryHint}
|
|
3796
|
+
`));
|
|
3797
|
+
}
|
|
3798
|
+
/**
|
|
3799
|
+
* Creates a branded error for failures to start the Next.js build child process.
|
|
3800
|
+
*/
|
|
3801
|
+
function createNextBuildSpawnError(error) {
|
|
3802
|
+
return new NotAllowed(spaceTrim$1(`
|
|
3803
|
+
Cannot start the Agents Server Next production build.
|
|
3804
|
+
|
|
3805
|
+
${error.message}
|
|
3806
|
+
`));
|
|
3807
|
+
}
|
|
3808
|
+
/**
|
|
3809
|
+
* Formats one Next.js build exit status for foreground logs.
|
|
3810
|
+
*/
|
|
3811
|
+
function describeNextBuildExitStatus(exitStatus) {
|
|
3812
|
+
if (exitStatus.signal) {
|
|
3813
|
+
return `signal \`${exitStatus.signal}\``;
|
|
3814
|
+
}
|
|
3815
|
+
return `exit code \`${String(exitStatus.code)}\``;
|
|
3816
|
+
}
|
|
3721
3817
|
/**
|
|
3722
3818
|
* Prepends `--max-old-space-size=<mib>` to `NODE_OPTIONS` unless the caller already set one.
|
|
3723
3819
|
*/
|
|
@@ -16448,6 +16544,70 @@ class MetaLinkCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
16448
16544
|
}
|
|
16449
16545
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
16450
16546
|
|
|
16547
|
+
/**
|
|
16548
|
+
* META VISIBILITY commitment definition.
|
|
16549
|
+
*
|
|
16550
|
+
* The `META VISIBILITY` commitment stores whether an agent is public, private, or unlisted.
|
|
16551
|
+
* Agents Server mirrors this value into the database for efficient filtering, but the book
|
|
16552
|
+
* commitment remains the editable source of truth.
|
|
16553
|
+
*
|
|
16554
|
+
* @private Metadata-only commitment used by Agents Server.
|
|
16555
|
+
*/
|
|
16556
|
+
class MetaVisibilityCommitmentDefinition extends BaseCommitmentDefinition {
|
|
16557
|
+
constructor() {
|
|
16558
|
+
super('META VISIBILITY');
|
|
16559
|
+
}
|
|
16560
|
+
/**
|
|
16561
|
+
* Short one-line description of META VISIBILITY.
|
|
16562
|
+
*/
|
|
16563
|
+
get description() {
|
|
16564
|
+
return 'Set whether the agent is private, unlisted, or public.';
|
|
16565
|
+
}
|
|
16566
|
+
/**
|
|
16567
|
+
* Icon for this commitment.
|
|
16568
|
+
*/
|
|
16569
|
+
get icon() {
|
|
16570
|
+
return '👁️';
|
|
16571
|
+
}
|
|
16572
|
+
/**
|
|
16573
|
+
* Markdown documentation for META VISIBILITY commitment.
|
|
16574
|
+
*/
|
|
16575
|
+
get documentation() {
|
|
16576
|
+
return spaceTrim$1(`
|
|
16577
|
+
# META VISIBILITY
|
|
16578
|
+
|
|
16579
|
+
Sets the agent visibility used by Agents Server.
|
|
16580
|
+
|
|
16581
|
+
## Allowed values
|
|
16582
|
+
|
|
16583
|
+
- \`PRIVATE\` - accessible only to signed-in users with access.
|
|
16584
|
+
- \`UNLISTED\` - accessible by direct link but hidden from public listings.
|
|
16585
|
+
- \`PUBLIC\` - visible in public listings and accessible by anyone.
|
|
16586
|
+
|
|
16587
|
+
## Key aspects
|
|
16588
|
+
|
|
16589
|
+
- Does not modify the agent's behavior, system message, or tools.
|
|
16590
|
+
- Whitespace and letter case are normalized when persisted.
|
|
16591
|
+
- If multiple \`META VISIBILITY\` commitments are present, persistence keeps one normalized value.
|
|
16592
|
+
- Agents Server mirrors the value into the database for filtering, but the book is the source of truth.
|
|
16593
|
+
|
|
16594
|
+
## Example
|
|
16595
|
+
|
|
16596
|
+
\`\`\`book
|
|
16597
|
+
Helpful Assistant
|
|
16598
|
+
|
|
16599
|
+
GOAL Be helpful and friendly.
|
|
16600
|
+
META VISIBILITY PUBLIC
|
|
16601
|
+
\`\`\`
|
|
16602
|
+
`);
|
|
16603
|
+
}
|
|
16604
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
16605
|
+
// META VISIBILITY is metadata only and does not alter model requirements.
|
|
16606
|
+
return requirements;
|
|
16607
|
+
}
|
|
16608
|
+
}
|
|
16609
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
16610
|
+
|
|
16451
16611
|
/**
|
|
16452
16612
|
* META VOICE commitment definition
|
|
16453
16613
|
*
|
|
@@ -22943,31 +23103,65 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
22943
23103
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
22944
23104
|
|
|
22945
23105
|
/**
|
|
22946
|
-
* This error
|
|
23106
|
+
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
22947
23107
|
*
|
|
22948
23108
|
* @public exported from `@promptbook/core`
|
|
22949
23109
|
*/
|
|
22950
|
-
class
|
|
23110
|
+
class ParseError extends Error {
|
|
22951
23111
|
constructor(message) {
|
|
22952
23112
|
super(message);
|
|
22953
|
-
this.name = '
|
|
22954
|
-
Object.setPrototypeOf(this,
|
|
23113
|
+
this.name = 'ParseError';
|
|
23114
|
+
Object.setPrototypeOf(this, ParseError.prototype);
|
|
22955
23115
|
}
|
|
22956
23116
|
}
|
|
23117
|
+
// TODO: Maybe split `ParseError` and `ApplyError`
|
|
22957
23118
|
|
|
22958
23119
|
/**
|
|
22959
|
-
*
|
|
23120
|
+
* Supported visibility states for persisted agents.
|
|
22960
23121
|
*
|
|
22961
23122
|
* @public exported from `@promptbook/core`
|
|
22962
23123
|
*/
|
|
22963
|
-
|
|
23124
|
+
const AGENT_VISIBILITY_VALUES = ['PRIVATE', 'UNLISTED', 'PUBLIC'];
|
|
23125
|
+
/**
|
|
23126
|
+
* Returns `true` when the value is one of supported visibility states.
|
|
23127
|
+
*
|
|
23128
|
+
* @param value - Raw value to validate.
|
|
23129
|
+
* @returns Whether the value is a valid `AgentVisibility`.
|
|
23130
|
+
*
|
|
23131
|
+
* @public exported from `@promptbook/core`
|
|
23132
|
+
*/
|
|
23133
|
+
function isAgentVisibility(value) {
|
|
23134
|
+
return typeof value === 'string' && AGENT_VISIBILITY_VALUES.includes(value);
|
|
23135
|
+
}
|
|
23136
|
+
/**
|
|
23137
|
+
* Normalizes raw visibility text into a supported value.
|
|
23138
|
+
*
|
|
23139
|
+
* @param value - Raw visibility value.
|
|
23140
|
+
* @returns Normalized visibility, or `null` when invalid.
|
|
23141
|
+
*
|
|
23142
|
+
* @public exported from `@promptbook/core`
|
|
23143
|
+
*/
|
|
23144
|
+
function normalizeAgentVisibility(value) {
|
|
23145
|
+
if (typeof value !== 'string') {
|
|
23146
|
+
return null;
|
|
23147
|
+
}
|
|
23148
|
+
const normalized = value.trim().toUpperCase();
|
|
23149
|
+
return isAgentVisibility(normalized) ? normalized : null;
|
|
23150
|
+
}
|
|
23151
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
23152
|
+
|
|
23153
|
+
/**
|
|
23154
|
+
* This error type indicates that some limit was reached
|
|
23155
|
+
*
|
|
23156
|
+
* @public exported from `@promptbook/core`
|
|
23157
|
+
*/
|
|
23158
|
+
class LimitReachedError extends Error {
|
|
22964
23159
|
constructor(message) {
|
|
22965
23160
|
super(message);
|
|
22966
|
-
this.name = '
|
|
22967
|
-
Object.setPrototypeOf(this,
|
|
23161
|
+
this.name = 'LimitReachedError';
|
|
23162
|
+
Object.setPrototypeOf(this, LimitReachedError.prototype);
|
|
22968
23163
|
}
|
|
22969
23164
|
}
|
|
22970
|
-
// TODO: Maybe split `ParseError` and `ApplyError`
|
|
22971
23165
|
|
|
22972
23166
|
/**
|
|
22973
23167
|
* Maximum allowed source length for create-agent payloads.
|
|
@@ -25302,6 +25496,7 @@ const COMMITMENT_REGISTRY = [
|
|
|
25302
25496
|
new MetaDomainCommitmentDefinition(),
|
|
25303
25497
|
new MetaDisclaimerCommitmentDefinition(),
|
|
25304
25498
|
new MetaInputPlaceholderCommitmentDefinition(),
|
|
25499
|
+
new MetaVisibilityCommitmentDefinition(),
|
|
25305
25500
|
new MetaCommitmentDefinition(),
|
|
25306
25501
|
new MetaVoiceCommitmentDefinition(),
|
|
25307
25502
|
new NoteCommitmentDefinition('NOTE'),
|
|
@@ -25753,6 +25948,7 @@ const META_COMMITMENT_APPLIERS = {
|
|
|
25753
25948
|
'META COLOR': applyMetaColorContent,
|
|
25754
25949
|
'META FONT': applyMetaFontContent,
|
|
25755
25950
|
'META VOICE': applyMetaVoiceContent,
|
|
25951
|
+
'META VISIBILITY': applyMetaVisibilityContent,
|
|
25756
25952
|
};
|
|
25757
25953
|
/**
|
|
25758
25954
|
* Applies META-style commitments that mutate parsed profile metadata.
|
|
@@ -25782,6 +25978,10 @@ function applyGenericMetaCommitment(state, content) {
|
|
|
25782
25978
|
applyMetaAvatarContent(state, metaValue);
|
|
25783
25979
|
return;
|
|
25784
25980
|
}
|
|
25981
|
+
if (metaTypeRaw.toUpperCase() === 'VISIBILITY') {
|
|
25982
|
+
applyMetaVisibilityContent(state, metaValue);
|
|
25983
|
+
return;
|
|
25984
|
+
}
|
|
25785
25985
|
const metaType = normalizeTo_camelCase(metaTypeRaw);
|
|
25786
25986
|
state.meta[metaType] = metaValue;
|
|
25787
25987
|
}
|
|
@@ -25858,6 +26058,15 @@ function applyMetaFontContent(state, content) {
|
|
|
25858
26058
|
function applyMetaVoiceContent(state, content) {
|
|
25859
26059
|
state.meta.voice = spaceTrim$1(content);
|
|
25860
26060
|
}
|
|
26061
|
+
/**
|
|
26062
|
+
* Applies META VISIBILITY content into the normalized `meta.visibility` field.
|
|
26063
|
+
*/
|
|
26064
|
+
function applyMetaVisibilityContent(state, content) {
|
|
26065
|
+
const visibility = normalizeAgentVisibility(content);
|
|
26066
|
+
if (visibility) {
|
|
26067
|
+
state.meta.visibility = visibility;
|
|
26068
|
+
}
|
|
26069
|
+
}
|
|
25861
26070
|
/**
|
|
25862
26071
|
* Normalizes the separator in the content
|
|
25863
26072
|
*
|
|
@@ -37430,7 +37639,7 @@ async function tickAgentMessages(options, tickOptions = {}) {
|
|
|
37430
37639
|
validateAgentRunOptions(options);
|
|
37431
37640
|
const projectPath = tickOptions.projectPath || process.cwd();
|
|
37432
37641
|
let queueSnapshot = await loadAgentMessageQueueSnapshot(projectPath);
|
|
37433
|
-
let queuedMessage = queueSnapshot.
|
|
37642
|
+
let queuedMessage = resolveSelectedQueuedMessage(queueSnapshot, tickOptions.queuedMessage);
|
|
37434
37643
|
if (!queuedMessage) {
|
|
37435
37644
|
announceNoQueuedMessages(tickOptions);
|
|
37436
37645
|
return { isMessageProcessed: false };
|
|
@@ -37445,7 +37654,7 @@ async function tickAgentMessages(options, tickOptions = {}) {
|
|
|
37445
37654
|
});
|
|
37446
37655
|
if (autoPullTimestamp !== undefined) {
|
|
37447
37656
|
queueSnapshot = await loadAgentMessageQueueSnapshot(projectPath);
|
|
37448
|
-
queuedMessage = queueSnapshot.
|
|
37657
|
+
queuedMessage = resolveSelectedQueuedMessage(queueSnapshot, tickOptions.queuedMessage);
|
|
37449
37658
|
if (!queuedMessage) {
|
|
37450
37659
|
if (tickOptions.uiHandle && !((_b = tickOptions.uiPresentation) === null || _b === void 0 ? void 0 : _b.isSharedDashboard)) {
|
|
37451
37660
|
updateAgentRunUiForWatching(tickOptions.uiHandle, queueSnapshot);
|
|
@@ -37471,7 +37680,7 @@ async function tickAgentMessages(options, tickOptions = {}) {
|
|
|
37471
37680
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.updateProgress(((_e = tickOptions.uiPresentation) === null || _e === void 0 ? void 0 : _e.completedProgressStats) ||
|
|
37472
37681
|
createAgentQueueProgressSnapshot({
|
|
37473
37682
|
finishedMessageCount: queueSnapshot.finishedMessageCount + 1,
|
|
37474
|
-
queuedMessages: queueSnapshot
|
|
37683
|
+
queuedMessages: removeQueuedMessageFromSnapshot(queueSnapshot, queuedMessage),
|
|
37475
37684
|
}));
|
|
37476
37685
|
if ((_f = tickOptions.uiPresentation) === null || _f === void 0 ? void 0 : _f.completedAgentStatusLines) {
|
|
37477
37686
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setAgentStatusLines([...tickOptions.uiPresentation.completedAgentStatusLines]);
|
|
@@ -37483,7 +37692,9 @@ async function tickAgentMessages(options, tickOptions = {}) {
|
|
|
37483
37692
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setMessagePreviewLines([...tickOptions.uiPresentation.completedMessagePreviewLines]);
|
|
37484
37693
|
}
|
|
37485
37694
|
if ((_j = tickOptions.uiPresentation) === null || _j === void 0 ? void 0 : _j.completedMessagePreviewSections) {
|
|
37486
|
-
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setMessagePreviewSections([
|
|
37695
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setMessagePreviewSections([
|
|
37696
|
+
...tickOptions.uiPresentation.completedMessagePreviewSections,
|
|
37697
|
+
]);
|
|
37487
37698
|
}
|
|
37488
37699
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setStatusMessage('Message answered');
|
|
37489
37700
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setPhase('done');
|
|
@@ -37511,6 +37722,21 @@ async function tickAgentMessages(options, tickOptions = {}) {
|
|
|
37511
37722
|
printAgentGitIdentityTipAtProcessExitIfNeeded();
|
|
37512
37723
|
}
|
|
37513
37724
|
}
|
|
37725
|
+
/**
|
|
37726
|
+
* Resolves either the explicitly selected queued message or the first available queue item.
|
|
37727
|
+
*/
|
|
37728
|
+
function resolveSelectedQueuedMessage(queueSnapshot, selectedQueuedMessage) {
|
|
37729
|
+
if (!selectedQueuedMessage) {
|
|
37730
|
+
return queueSnapshot.queuedMessages[0];
|
|
37731
|
+
}
|
|
37732
|
+
return queueSnapshot.queuedMessages.find((queuedMessage) => queuedMessage.relativePath === selectedQueuedMessage.relativePath);
|
|
37733
|
+
}
|
|
37734
|
+
/**
|
|
37735
|
+
* Creates a progress queue list with the processed message removed from its original snapshot.
|
|
37736
|
+
*/
|
|
37737
|
+
function removeQueuedMessageFromSnapshot(queueSnapshot, processedQueuedMessage) {
|
|
37738
|
+
return queueSnapshot.queuedMessages.filter((queuedMessage) => queuedMessage.relativePath !== processedQueuedMessage.relativePath);
|
|
37739
|
+
}
|
|
37514
37740
|
/**
|
|
37515
37741
|
* Runs the selected coding runner for one message and finalizes the answered file.
|
|
37516
37742
|
*/
|
|
@@ -37631,7 +37857,9 @@ function seedAgentRunUiHandle(uiHandle, options, runner, actualRunnerModel, queu
|
|
|
37631
37857
|
return;
|
|
37632
37858
|
}
|
|
37633
37859
|
uiHandle.state.setCurrentPrompt(queuedMessage.relativePath);
|
|
37634
|
-
uiHandle.state.setMessagePreviewLines([
|
|
37860
|
+
uiHandle.state.setMessagePreviewLines([
|
|
37861
|
+
...((uiPresentation === null || uiPresentation === void 0 ? void 0 : uiPresentation.messagePreviewLines) || agentUiMetadata.latestUserMessageLines),
|
|
37862
|
+
]);
|
|
37635
37863
|
uiHandle.state.setPhase('loading');
|
|
37636
37864
|
uiHandle.state.setStatusMessage('Preparing message');
|
|
37637
37865
|
}
|
|
@@ -37910,12 +38138,16 @@ const LEGACY_STATUS_WIDTH = 9;
|
|
|
37910
38138
|
* Watches all direct child agent repositories from the current directory in one shared session.
|
|
37911
38139
|
*/
|
|
37912
38140
|
async function runMultipleAgentMessages(options, controls = {}) {
|
|
37913
|
-
var _a;
|
|
38141
|
+
var _a, _b;
|
|
37914
38142
|
validateAgentRunOptions(options);
|
|
37915
38143
|
validateAgentWatchOptions('ptbk agent-folder run-multiple', options);
|
|
37916
38144
|
const rootPath = process.cwd();
|
|
37917
38145
|
const shouldContinue = controls.shouldContinue || (() => just(true));
|
|
38146
|
+
const queuePollIntervalMs = (_a = controls.queuePollIntervalMs) !== null && _a !== void 0 ? _a : MULTI_AGENT_QUEUE_POLL_INTERVAL_MS;
|
|
37918
38147
|
const ignoreMatcher = createAgentIgnoreMatcher(options.ignorePatterns);
|
|
38148
|
+
const isParallelMessageLimitConfigured = options.maxParallelMessages !== undefined;
|
|
38149
|
+
const maxParallelMessageCount = normalizeMaxParallelMessageCount(options.maxParallelMessages);
|
|
38150
|
+
const activeMessageTasksByKey = new Map();
|
|
37919
38151
|
let githubSynchronizationTimestamp;
|
|
37920
38152
|
let githubIgnoredRepositoryCount = 0;
|
|
37921
38153
|
const autoPullTimestampsByProjectPath = new Map();
|
|
@@ -37930,7 +38162,7 @@ async function runMultipleAgentMessages(options, controls = {}) {
|
|
|
37930
38162
|
if (!isWatchSessionInitialized) {
|
|
37931
38163
|
uiHandle = await initializeMultipleAgentRunUi(options);
|
|
37932
38164
|
isWatchSessionInitialized = true;
|
|
37933
|
-
(
|
|
38165
|
+
(_b = controls.onUiInitialized) === null || _b === void 0 ? void 0 : _b.call(controls, uiHandle);
|
|
37934
38166
|
if (!uiHandle) {
|
|
37935
38167
|
console.info(colors.green('Watching direct child agent repositories for queued messages.'));
|
|
37936
38168
|
}
|
|
@@ -37953,14 +38185,19 @@ async function runMultipleAgentMessages(options, controls = {}) {
|
|
|
37953
38185
|
let projectSummaries = projectSummariesResult.projectSummaries;
|
|
37954
38186
|
lastObservedProjectCount = projectSummaries.length;
|
|
37955
38187
|
let ignoredAgentCount = projectSummariesResult.ignoredProjectCount + githubIgnoredRepositoryCount;
|
|
37956
|
-
const autoPullResult =
|
|
37957
|
-
|
|
37958
|
-
|
|
37959
|
-
|
|
37960
|
-
|
|
37961
|
-
|
|
37962
|
-
|
|
37963
|
-
|
|
38188
|
+
const autoPullResult = activeMessageTasksByKey.size === 0
|
|
38189
|
+
? await pullLatestChangesForLocalAgentRunnerProjectsIfNeeded({
|
|
38190
|
+
rootPath,
|
|
38191
|
+
runOptions: options,
|
|
38192
|
+
uiHandle,
|
|
38193
|
+
projectSummaries,
|
|
38194
|
+
ignoredAgentCount,
|
|
38195
|
+
autoPullTimestampsByProjectPath,
|
|
38196
|
+
})
|
|
38197
|
+
: {
|
|
38198
|
+
isAnyRepositoryPulled: false,
|
|
38199
|
+
pulledProjectPaths: new Set(),
|
|
38200
|
+
};
|
|
37964
38201
|
if (autoPullResult.isAnyRepositoryPulled) {
|
|
37965
38202
|
projectSummariesResult = await loadLocalAgentRunnerProjectSummaries(rootPath, {
|
|
37966
38203
|
includeMessagePreviews: Boolean(uiHandle),
|
|
@@ -37970,61 +38207,49 @@ async function runMultipleAgentMessages(options, controls = {}) {
|
|
|
37970
38207
|
lastObservedProjectCount = projectSummaries.length;
|
|
37971
38208
|
ignoredAgentCount = projectSummariesResult.ignoredProjectCount + githubIgnoredRepositoryCount;
|
|
37972
38209
|
}
|
|
37973
|
-
const
|
|
37974
|
-
|
|
38210
|
+
const availableParallelMessageSlots = Math.max(0, maxParallelMessageCount - activeMessageTasksByKey.size);
|
|
38211
|
+
const queuedWorkItems = availableParallelMessageSlots > 0
|
|
38212
|
+
? selectQueuedWorkItems({
|
|
38213
|
+
projectSummaries,
|
|
38214
|
+
activeMessageTasksByKey,
|
|
38215
|
+
availableParallelMessageSlots,
|
|
38216
|
+
isParallelMessageLimitConfigured,
|
|
38217
|
+
})
|
|
38218
|
+
: [];
|
|
38219
|
+
const answeringProjectPaths = createAnsweringProjectPaths(activeMessageTasksByKey, queuedWorkItems);
|
|
38220
|
+
if (queuedWorkItems.length === 0 && activeMessageTasksByKey.size === 0) {
|
|
37975
38221
|
updateMultipleAgentRunUiForWatching(uiHandle, options, rootPath, projectSummaries, ignoredAgentCount);
|
|
37976
|
-
await wait$3(
|
|
38222
|
+
await wait$3(queuePollIntervalMs);
|
|
38223
|
+
continue;
|
|
38224
|
+
}
|
|
38225
|
+
if (queuedWorkItems.length === 0) {
|
|
38226
|
+
updateMultipleAgentRunUiForAnswering(uiHandle, options, rootPath, projectSummaries, answeringProjectPaths, ignoredAgentCount, activeMessageTasksByKey.size);
|
|
38227
|
+
await waitForNextSchedulerTurn(activeMessageTasksByKey, queuePollIntervalMs);
|
|
37977
38228
|
continue;
|
|
37978
38229
|
}
|
|
37979
38230
|
if (!uiHandle) {
|
|
37980
|
-
for (const
|
|
37981
|
-
console.info(colors.blue(`Processing ${formatProjectPath(rootPath,
|
|
38231
|
+
for (const queuedWorkItem of queuedWorkItems) {
|
|
38232
|
+
console.info(colors.blue(`Processing ${formatProjectPath(rootPath, queuedWorkItem.projectSummary.project.projectPath)}/${queuedWorkItem.queuedMessage.relativePath} with ${queuedWorkItem.projectSummary.localAgentName}.`));
|
|
37982
38233
|
}
|
|
37983
38234
|
}
|
|
37984
|
-
|
|
37985
|
-
|
|
37986
|
-
|
|
37987
|
-
|
|
37988
|
-
|
|
37989
|
-
|
|
37990
|
-
|
|
37991
|
-
|
|
37992
|
-
|
|
37993
|
-
|
|
37994
|
-
|
|
37995
|
-
|
|
38235
|
+
updateMultipleAgentRunUiForAnswering(uiHandle, options, rootPath, projectSummaries, answeringProjectPaths, ignoredAgentCount, activeMessageTasksByKey.size + queuedWorkItems.length);
|
|
38236
|
+
for (const queuedWorkItem of queuedWorkItems) {
|
|
38237
|
+
startActiveAgentMessageTask({
|
|
38238
|
+
rootPath,
|
|
38239
|
+
options,
|
|
38240
|
+
queuedWorkItem,
|
|
38241
|
+
projectSummaries,
|
|
38242
|
+
answeringProjectPaths,
|
|
38243
|
+
ignoredAgentCount,
|
|
38244
|
+
autoPullResult,
|
|
38245
|
+
autoPullTimestampsByProjectPath,
|
|
38246
|
+
activeMessageTasksByKey,
|
|
38247
|
+
messageFailureTracker,
|
|
37996
38248
|
uiHandle,
|
|
37997
|
-
|
|
37998
|
-
? buildMultiAgentTickUiPresentation({
|
|
37999
|
-
rootPath,
|
|
38000
|
-
projectSummaries,
|
|
38001
|
-
answeringProjectPaths,
|
|
38002
|
-
ignoredAgentCount,
|
|
38003
|
-
})
|
|
38004
|
-
: undefined,
|
|
38005
|
-
});
|
|
38006
|
-
return {
|
|
38007
|
-
projectPath: queuedProject.project.projectPath,
|
|
38008
|
-
tickResult,
|
|
38009
|
-
};
|
|
38010
|
-
}));
|
|
38011
|
-
for (const tickResult of tickResults) {
|
|
38012
|
-
if (tickResult.status === 'fulfilled') {
|
|
38013
|
-
if (tickResult.value.tickResult.autoPullTimestamp !== undefined) {
|
|
38014
|
-
autoPullTimestampsByProjectPath.set(tickResult.value.projectPath, tickResult.value.tickResult.autoPullTimestamp);
|
|
38015
|
-
}
|
|
38016
|
-
if (tickResult.value.tickResult.isMessageProcessed) {
|
|
38017
|
-
messageFailureTracker.clearMessageFailure(tickResult.value.projectPath, tickResult.value.tickResult.queuedMessage);
|
|
38018
|
-
}
|
|
38019
|
-
continue;
|
|
38020
|
-
}
|
|
38021
|
-
await handleAgentWatchError({
|
|
38022
|
-
commandDisplayName: 'ptbk agent-folder run-multiple',
|
|
38023
|
-
logDirectoryPath: controls.watchErrorLogDirectoryPath || rootPath,
|
|
38024
|
-
error: tickResult.reason,
|
|
38249
|
+
watchErrorLogDirectoryPath: controls.watchErrorLogDirectoryPath || rootPath,
|
|
38025
38250
|
});
|
|
38026
|
-
await messageFailureTracker.recordFailure(tickResult.reason);
|
|
38027
38251
|
}
|
|
38252
|
+
await waitForNextSchedulerTurn(activeMessageTasksByKey, queuePollIntervalMs);
|
|
38028
38253
|
}
|
|
38029
38254
|
catch (error) {
|
|
38030
38255
|
await handleAgentWatchError({
|
|
@@ -38033,9 +38258,167 @@ async function runMultipleAgentMessages(options, controls = {}) {
|
|
|
38033
38258
|
error,
|
|
38034
38259
|
});
|
|
38035
38260
|
await messageFailureTracker.recordFailure(error);
|
|
38036
|
-
await wait$3(
|
|
38261
|
+
await wait$3(queuePollIntervalMs);
|
|
38262
|
+
}
|
|
38263
|
+
}
|
|
38264
|
+
await waitForActiveMessageTasksToSettle(activeMessageTasksByKey);
|
|
38265
|
+
}
|
|
38266
|
+
/**
|
|
38267
|
+
* Starts one selected queued-message harness task and records it until it settles.
|
|
38268
|
+
*/
|
|
38269
|
+
function startActiveAgentMessageTask(options) {
|
|
38270
|
+
const { queuedWorkItem } = options;
|
|
38271
|
+
const projectPath = queuedWorkItem.projectSummary.project.projectPath;
|
|
38272
|
+
const messageKey = createAgentMessageTaskKey(projectPath, queuedWorkItem.queuedMessage);
|
|
38273
|
+
const promise = runActiveAgentMessageTask({
|
|
38274
|
+
rootPath: options.rootPath,
|
|
38275
|
+
options: options.options,
|
|
38276
|
+
queuedWorkItem,
|
|
38277
|
+
projectSummaries: options.projectSummaries,
|
|
38278
|
+
answeringProjectPaths: options.answeringProjectPaths,
|
|
38279
|
+
ignoredAgentCount: options.ignoredAgentCount,
|
|
38280
|
+
autoPullResult: options.autoPullResult,
|
|
38281
|
+
autoPullTimestampsByProjectPath: options.autoPullTimestampsByProjectPath,
|
|
38282
|
+
messageFailureTracker: options.messageFailureTracker,
|
|
38283
|
+
uiHandle: options.uiHandle,
|
|
38284
|
+
watchErrorLogDirectoryPath: options.watchErrorLogDirectoryPath,
|
|
38285
|
+
}).finally(() => {
|
|
38286
|
+
options.activeMessageTasksByKey.delete(messageKey);
|
|
38287
|
+
});
|
|
38288
|
+
options.activeMessageTasksByKey.set(messageKey, {
|
|
38289
|
+
projectPath,
|
|
38290
|
+
queuedMessage: queuedWorkItem.queuedMessage,
|
|
38291
|
+
promise,
|
|
38292
|
+
});
|
|
38293
|
+
}
|
|
38294
|
+
/**
|
|
38295
|
+
* Runs one queued-message tick and folds its result back into shared watcher state.
|
|
38296
|
+
*/
|
|
38297
|
+
async function runActiveAgentMessageTask(options) {
|
|
38298
|
+
const projectPath = options.queuedWorkItem.projectSummary.project.projectPath;
|
|
38299
|
+
try {
|
|
38300
|
+
const tickRunOptions = createAgentRunOptionsForQueuedProjectTick({
|
|
38301
|
+
runOptions: options.options,
|
|
38302
|
+
isProjectPulledInCurrentIteration: options.autoPullResult.pulledProjectPaths.has(projectPath),
|
|
38303
|
+
});
|
|
38304
|
+
const tickResult = await tickAgentMessages(tickRunOptions, {
|
|
38305
|
+
isQuietWhenIdle: true,
|
|
38306
|
+
projectPath,
|
|
38307
|
+
queuedMessage: options.queuedWorkItem.queuedMessage,
|
|
38308
|
+
uiHandle: options.uiHandle,
|
|
38309
|
+
uiPresentation: options.uiHandle
|
|
38310
|
+
? buildMultiAgentTickUiPresentation({
|
|
38311
|
+
rootPath: options.rootPath,
|
|
38312
|
+
projectSummaries: options.projectSummaries,
|
|
38313
|
+
answeringProjectPaths: options.answeringProjectPaths,
|
|
38314
|
+
ignoredAgentCount: options.ignoredAgentCount,
|
|
38315
|
+
})
|
|
38316
|
+
: undefined,
|
|
38317
|
+
});
|
|
38318
|
+
if (tickResult.autoPullTimestamp !== undefined) {
|
|
38319
|
+
options.autoPullTimestampsByProjectPath.set(projectPath, tickResult.autoPullTimestamp);
|
|
38320
|
+
}
|
|
38321
|
+
if (tickResult.isMessageProcessed) {
|
|
38322
|
+
options.messageFailureTracker.clearMessageFailure(projectPath, tickResult.queuedMessage);
|
|
38323
|
+
}
|
|
38324
|
+
}
|
|
38325
|
+
catch (error) {
|
|
38326
|
+
await handleAgentWatchError({
|
|
38327
|
+
commandDisplayName: 'ptbk agent-folder run-multiple',
|
|
38328
|
+
logDirectoryPath: options.watchErrorLogDirectoryPath,
|
|
38329
|
+
error,
|
|
38330
|
+
});
|
|
38331
|
+
await options.messageFailureTracker.recordFailure(error);
|
|
38332
|
+
}
|
|
38333
|
+
}
|
|
38334
|
+
/**
|
|
38335
|
+
* Selects the next queued messages that can be started without exceeding active harness capacity.
|
|
38336
|
+
*/
|
|
38337
|
+
function selectQueuedWorkItems(options) {
|
|
38338
|
+
const activeProjectPaths = new Set(Array.from(options.activeMessageTasksByKey.values()).map((activeMessageTask) => activeMessageTask.projectPath));
|
|
38339
|
+
const queuedProjectSummaries = options.projectSummaries.filter((projectSummary) => {
|
|
38340
|
+
if (projectSummary.queuedMessageCount === 0) {
|
|
38341
|
+
return false;
|
|
38342
|
+
}
|
|
38343
|
+
return options.isParallelMessageLimitConfigured || !activeProjectPaths.has(projectSummary.project.projectPath);
|
|
38344
|
+
});
|
|
38345
|
+
if (!options.isParallelMessageLimitConfigured) {
|
|
38346
|
+
return queuedProjectSummaries
|
|
38347
|
+
.map((projectSummary) => selectFirstInactiveQueuedWorkItem(projectSummary, options.activeMessageTasksByKey))
|
|
38348
|
+
.filter((workItem) => workItem !== null);
|
|
38349
|
+
}
|
|
38350
|
+
const workItems = [];
|
|
38351
|
+
for (let messageIndex = 0; workItems.length < options.availableParallelMessageSlots; messageIndex++) {
|
|
38352
|
+
let isAnyMessageAtIndex = false;
|
|
38353
|
+
for (const projectSummary of queuedProjectSummaries) {
|
|
38354
|
+
const queuedMessage = projectSummary.queuedMessages[messageIndex];
|
|
38355
|
+
if (!queuedMessage) {
|
|
38356
|
+
continue;
|
|
38357
|
+
}
|
|
38358
|
+
isAnyMessageAtIndex = true;
|
|
38359
|
+
if (options.activeMessageTasksByKey.has(createAgentMessageTaskKey(projectSummary.project.projectPath, queuedMessage))) {
|
|
38360
|
+
continue;
|
|
38361
|
+
}
|
|
38362
|
+
workItems.push({ projectSummary, queuedMessage });
|
|
38363
|
+
if (workItems.length >= options.availableParallelMessageSlots) {
|
|
38364
|
+
return workItems;
|
|
38365
|
+
}
|
|
38366
|
+
}
|
|
38367
|
+
if (!isAnyMessageAtIndex) {
|
|
38368
|
+
return workItems;
|
|
38037
38369
|
}
|
|
38038
38370
|
}
|
|
38371
|
+
return workItems;
|
|
38372
|
+
}
|
|
38373
|
+
/**
|
|
38374
|
+
* Selects the first inactive queued message from a project while preserving legacy one-message-per-project behavior.
|
|
38375
|
+
*/
|
|
38376
|
+
function selectFirstInactiveQueuedWorkItem(projectSummary, activeMessageTasksByKey) {
|
|
38377
|
+
const queuedMessage = projectSummary.queuedMessages.find((message) => !activeMessageTasksByKey.has(createAgentMessageTaskKey(projectSummary.project.projectPath, message)));
|
|
38378
|
+
return queuedMessage ? { projectSummary, queuedMessage } : null;
|
|
38379
|
+
}
|
|
38380
|
+
/**
|
|
38381
|
+
* Builds the set of project paths currently represented by active or newly scheduled harness tasks.
|
|
38382
|
+
*/
|
|
38383
|
+
function createAnsweringProjectPaths(activeMessageTasksByKey, queuedWorkItems) {
|
|
38384
|
+
return new Set([
|
|
38385
|
+
...Array.from(activeMessageTasksByKey.values()).map((activeMessageTask) => activeMessageTask.projectPath),
|
|
38386
|
+
...queuedWorkItems.map((queuedWorkItem) => queuedWorkItem.projectSummary.project.projectPath),
|
|
38387
|
+
]);
|
|
38388
|
+
}
|
|
38389
|
+
/**
|
|
38390
|
+
* Creates a stable scheduler key for one queued message file.
|
|
38391
|
+
*/
|
|
38392
|
+
function createAgentMessageTaskKey(projectPath, queuedMessage) {
|
|
38393
|
+
return `${projectPath}\0${queuedMessage.relativePath}`;
|
|
38394
|
+
}
|
|
38395
|
+
/**
|
|
38396
|
+
* Normalizes the maximum number of parallel queued-message tasks.
|
|
38397
|
+
*/
|
|
38398
|
+
function normalizeMaxParallelMessageCount(rawValue) {
|
|
38399
|
+
const parsedValue = Number(rawValue);
|
|
38400
|
+
if (!Number.isFinite(parsedValue) || parsedValue <= 0) {
|
|
38401
|
+
return Number.POSITIVE_INFINITY;
|
|
38402
|
+
}
|
|
38403
|
+
return Math.floor(parsedValue);
|
|
38404
|
+
}
|
|
38405
|
+
/**
|
|
38406
|
+
* Waits for either one active task to finish or the next queue polling interval.
|
|
38407
|
+
*/
|
|
38408
|
+
async function waitForNextSchedulerTurn(activeMessageTasksByKey, queuePollIntervalMs) {
|
|
38409
|
+
if (activeMessageTasksByKey.size === 0) {
|
|
38410
|
+
return;
|
|
38411
|
+
}
|
|
38412
|
+
await Promise.race([
|
|
38413
|
+
...Array.from(activeMessageTasksByKey.values()).map((activeMessageTask) => activeMessageTask.promise),
|
|
38414
|
+
wait$3(queuePollIntervalMs),
|
|
38415
|
+
]);
|
|
38416
|
+
}
|
|
38417
|
+
/**
|
|
38418
|
+
* Preserves previous shutdown behavior by letting active harness tasks finish before returning.
|
|
38419
|
+
*/
|
|
38420
|
+
async function waitForActiveMessageTasksToSettle(activeMessageTasksByKey) {
|
|
38421
|
+
await Promise.allSettled(Array.from(activeMessageTasksByKey.values()).map((activeMessageTask) => activeMessageTask.promise));
|
|
38039
38422
|
}
|
|
38040
38423
|
/**
|
|
38041
38424
|
* Creates the shared multi-agent rich UI when the terminal supports it.
|
|
@@ -38181,6 +38564,7 @@ async function loadLocalAgentRunnerProjectSummaries(rootPath, options) {
|
|
|
38181
38564
|
project,
|
|
38182
38565
|
localAgentName: localAgentIdentity.localAgentName,
|
|
38183
38566
|
localAgentUrl: localAgentIdentity.localAgentUrl || formatProjectPath(rootPath, project.projectPath),
|
|
38567
|
+
queuedMessages: queueSnapshot.queuedMessages,
|
|
38184
38568
|
queuedMessageCount: queueSnapshot.queuedMessages.length,
|
|
38185
38569
|
finishedMessageCount: queueSnapshot.finishedMessageCount,
|
|
38186
38570
|
...(queuedMessagePreview ? { queuedMessagePreview } : {}),
|
|
@@ -38212,14 +38596,16 @@ function updateMultipleAgentRunUiForWatching(uiHandle, options, rootPath, projec
|
|
|
38212
38596
|
/**
|
|
38213
38597
|
* Updates the shared UI while one or more child repositories are answering queued messages.
|
|
38214
38598
|
*/
|
|
38215
|
-
function updateMultipleAgentRunUiForAnswering(uiHandle, options, rootPath, projectSummaries, answeringProjectPaths, ignoredAgentCount) {
|
|
38216
|
-
|
|
38599
|
+
function updateMultipleAgentRunUiForAnswering(uiHandle, options, rootPath, projectSummaries, answeringProjectPaths, ignoredAgentCount, activeMessageCount) {
|
|
38600
|
+
if (!uiHandle) {
|
|
38601
|
+
return;
|
|
38602
|
+
}
|
|
38217
38603
|
setMultipleAgentRunUiConfig(uiHandle, options, projectSummaries.length, ignoredAgentCount);
|
|
38218
38604
|
uiHandle.state.updateProgress(createMultiAgentQueueProgressSnapshot(projectSummaries));
|
|
38219
38605
|
uiHandle.state.setCurrentPrompt('');
|
|
38220
38606
|
uiHandle.state.setCurrentScriptPaths(buildMultiAgentScriptPaths(projectSummaries, answeringProjectPaths));
|
|
38221
38607
|
uiHandle.state.setPhase('running');
|
|
38222
|
-
uiHandle.state.setStatusMessage(`Answering ${
|
|
38608
|
+
uiHandle.state.setStatusMessage(`Answering ${activeMessageCount} queued message${activeMessageCount === 1 ? '' : 's'}`);
|
|
38223
38609
|
uiHandle.state.setDetailLines(buildMultiAgentAnsweringDetailLines(rootPath, projectSummaries, answeringProjectPaths));
|
|
38224
38610
|
uiHandle.state.setAgentStatusLines(buildMultiAgentStatusLines(rootPath, projectSummaries, answeringProjectPaths));
|
|
38225
38611
|
uiHandle.state.setAgentStatusTableRows(buildMultiAgentStatusTableRows(projectSummaries, answeringProjectPaths));
|
|
@@ -38521,6 +38907,12 @@ const DEFAULT_SPAWN_AGENT_RATE_LIMIT_WINDOW_MS = 10 * 60 * 1000;
|
|
|
38521
38907
|
* @private shared Agents Server constant
|
|
38522
38908
|
*/
|
|
38523
38909
|
const DEFAULT_LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS = 3;
|
|
38910
|
+
/**
|
|
38911
|
+
* Default maximum number of local runner harness instances allowed to answer queued messages at once.
|
|
38912
|
+
*
|
|
38913
|
+
* @private shared Agents Server constant
|
|
38914
|
+
*/
|
|
38915
|
+
const DEFAULT_LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES = 3;
|
|
38524
38916
|
/**
|
|
38525
38917
|
* Stable keys used by the dedicated server-limits table.
|
|
38526
38918
|
*
|
|
@@ -38535,6 +38927,7 @@ const SERVER_LIMIT_KEYS = {
|
|
|
38535
38927
|
SPAWN_AGENT_RATE_LIMIT_MAX: 'SPAWN_AGENT_RATE_LIMIT_MAX',
|
|
38536
38928
|
SPAWN_AGENT_RATE_LIMIT_WINDOW_MS: 'SPAWN_AGENT_RATE_LIMIT_WINDOW_MS',
|
|
38537
38929
|
LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS: 'LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS',
|
|
38930
|
+
LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES: 'LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES',
|
|
38538
38931
|
};
|
|
38539
38932
|
/**
|
|
38540
38933
|
* Shared metadata for all server limits exposed in the admin UI and runtime loaders.
|
|
@@ -38630,6 +39023,17 @@ const SERVER_LIMIT_DEFINITIONS = [
|
|
|
38630
39023
|
step: 1,
|
|
38631
39024
|
legacyMetadataKeys: [],
|
|
38632
39025
|
},
|
|
39026
|
+
{
|
|
39027
|
+
key: SERVER_LIMIT_KEYS.LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES,
|
|
39028
|
+
category: 'Local agent runner',
|
|
39029
|
+
title: 'Max parallel harness instances',
|
|
39030
|
+
description: 'Caps how many queued chat messages the local coding-agent harness may answer at the same time.',
|
|
39031
|
+
unit: 'count',
|
|
39032
|
+
defaultValue: DEFAULT_LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES,
|
|
39033
|
+
minimumValue: 1,
|
|
39034
|
+
step: 1,
|
|
39035
|
+
legacyMetadataKeys: [],
|
|
39036
|
+
},
|
|
38633
39037
|
];
|
|
38634
39038
|
/**
|
|
38635
39039
|
* Fast lookup map used by server-limit validators and UI helpers.
|
|
@@ -38991,6 +39395,7 @@ function createLocalAgentRunOptions(options, localAgentRunnerLimits) {
|
|
|
38991
39395
|
autoPull: false,
|
|
38992
39396
|
autoClone: false,
|
|
38993
39397
|
maxMessageProcessingFailures: localAgentRunnerLimits.maxFailedAttempts,
|
|
39398
|
+
maxParallelMessages: localAgentRunnerLimits.maxParallelMessages,
|
|
38994
39399
|
};
|
|
38995
39400
|
}
|
|
38996
39401
|
/**
|
|
@@ -39002,7 +39407,7 @@ async function waitForLocalAgentRunnerLimits(options) {
|
|
|
39002
39407
|
while (options.state.isContinuing && Date.now() - startedAt < INTERNAL_SERVER_LIMITS_STARTUP_TIMEOUT_MS) {
|
|
39003
39408
|
try {
|
|
39004
39409
|
const limits = await fetchLocalAgentRunnerLimits(options);
|
|
39005
|
-
logRunnerEvent(options.logStreams.runner, `Local agent runner
|
|
39410
|
+
logRunnerEvent(options.logStreams.runner, `Local agent runner limits: ${limits.maxFailedAttempts} failed attempt(s), ${limits.maxParallelMessages} parallel message(s).`);
|
|
39006
39411
|
return limits;
|
|
39007
39412
|
}
|
|
39008
39413
|
catch (error) {
|
|
@@ -39013,6 +39418,7 @@ async function waitForLocalAgentRunnerLimits(options) {
|
|
|
39013
39418
|
if (!options.state.isContinuing) {
|
|
39014
39419
|
return {
|
|
39015
39420
|
maxFailedAttempts: DEFAULT_LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS,
|
|
39421
|
+
maxParallelMessages: DEFAULT_LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES,
|
|
39016
39422
|
};
|
|
39017
39423
|
}
|
|
39018
39424
|
throw new NotAllowed(spaceTrim$1(`
|
|
@@ -39039,6 +39445,7 @@ async function fetchLocalAgentRunnerLimits(options) {
|
|
|
39039
39445
|
const payload = (await response.json());
|
|
39040
39446
|
return {
|
|
39041
39447
|
maxFailedAttempts: normalizeLocalAgentRunnerMaxFailedAttempts(payload.maxFailedAttempts),
|
|
39448
|
+
maxParallelMessages: normalizeLocalAgentRunnerMaxParallelMessages(payload.maxParallelMessages),
|
|
39042
39449
|
};
|
|
39043
39450
|
}
|
|
39044
39451
|
/**
|
|
@@ -39051,6 +39458,16 @@ function normalizeLocalAgentRunnerMaxFailedAttempts(rawValue) {
|
|
|
39051
39458
|
}
|
|
39052
39459
|
return Math.floor(parsedValue);
|
|
39053
39460
|
}
|
|
39461
|
+
/**
|
|
39462
|
+
* Normalizes the local runner parallel message cap returned by the internal server route.
|
|
39463
|
+
*/
|
|
39464
|
+
function normalizeLocalAgentRunnerMaxParallelMessages(rawValue) {
|
|
39465
|
+
const parsedValue = Number(rawValue);
|
|
39466
|
+
if (!Number.isFinite(parsedValue) || parsedValue <= 0) {
|
|
39467
|
+
return DEFAULT_LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES;
|
|
39468
|
+
}
|
|
39469
|
+
return Math.floor(parsedValue);
|
|
39470
|
+
}
|
|
39054
39471
|
/**
|
|
39055
39472
|
* Starts periodic internal worker calls that queue and reconcile local message-folder jobs.
|
|
39056
39473
|
*/
|
|
@@ -40305,7 +40722,7 @@ async function ensureCoderGitignoreFile(projectPath) {
|
|
|
40305
40722
|
*/
|
|
40306
40723
|
const DEFAULT_CODER_PACKAGE_JSON_SCRIPTS = {
|
|
40307
40724
|
'coder:generate-boilerplates': 'ptbk coder generate-boilerplates --template ./prompts/templates/common.md',
|
|
40308
|
-
'coder:run': 'ptbk coder run --harness openai-codex --model gpt-5.
|
|
40725
|
+
'coder:run': 'ptbk coder run --harness openai-codex --model gpt-5.5 --thinking-level xhigh --agent agents/developer.book --context AGENTS.md',
|
|
40309
40726
|
// 'coder:find-refactor-candidates': 'ptbk coder find-refactor-candidates',
|
|
40310
40727
|
'coder:verify': 'ptbk coder verify',
|
|
40311
40728
|
};
|
|
@@ -40785,6 +41202,7 @@ function $initializeCoderRunCommand(program) {
|
|
|
40785
41202
|
command.option('--preserve-logs', 'Keep generated temp prompt/log artifacts after successful rounds for debugging and analytics', false);
|
|
40786
41203
|
addPromptRunnerExecutionOptions(command);
|
|
40787
41204
|
command.option('--priority <minimum-priority>', 'Filter prompts by minimum priority level', parseIntOption$1, 0);
|
|
41205
|
+
command.option('--limit <run-count>', 'Stop after processing this many prompt runs', parsePositiveIntegerOption);
|
|
40788
41206
|
command.option('--wait-after-prompt <duration>', spaceTrim$1(`
|
|
40789
41207
|
Wait this long after each prompt has been implemented, verified and committed before starting the next prompt.
|
|
40790
41208
|
Accepts durations like 1h, 30m, 5s. Defaults to 0 (no wait).
|
|
@@ -40803,7 +41221,7 @@ function $initializeCoderRunCommand(program) {
|
|
|
40803
41221
|
command.option('--auto-migrate', 'Run testing-server database migrations automatically after each successfully processed prompt');
|
|
40804
41222
|
command.option('--allow-destructive-auto-migrate', 'Allow auto-migrate even when heuristic SQL safety check flags destructive pending migrations');
|
|
40805
41223
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
40806
|
-
const { dryRun, agent, context, test, preserveLogs, priority, waitAfterPrompt: waitAfterPromptValue, waitBetweenPrompts: waitBetweenPromptsValue, waitAfterError: waitAfterErrorValue, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
41224
|
+
const { dryRun, agent, context, test, preserveLogs, priority, limit, waitAfterPrompt: waitAfterPromptValue, waitBetweenPrompts: waitBetweenPromptsValue, waitAfterError: waitAfterErrorValue, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
40807
41225
|
const testCommand = normalizeCommandOptionValue$1(test);
|
|
40808
41226
|
const runnerOptions = normalizePromptRunnerCliOptions(cliOptions, {
|
|
40809
41227
|
isAgentRequired: !dryRun,
|
|
@@ -40836,6 +41254,7 @@ function $initializeCoderRunCommand(program) {
|
|
|
40836
41254
|
noUi: runnerOptions.noUi,
|
|
40837
41255
|
thinkingLevel: runnerOptions.thinkingLevel,
|
|
40838
41256
|
priority,
|
|
41257
|
+
limit,
|
|
40839
41258
|
normalizeLineEndings: runnerOptions.normalizeLineEndings,
|
|
40840
41259
|
allowCredits: runnerOptions.allowCredits,
|
|
40841
41260
|
autoMigrate,
|
|
@@ -40870,6 +41289,22 @@ function parseIntOption$1(value) {
|
|
|
40870
41289
|
}
|
|
40871
41290
|
return parsed;
|
|
40872
41291
|
}
|
|
41292
|
+
/**
|
|
41293
|
+
* Parses a positive integer option value.
|
|
41294
|
+
*
|
|
41295
|
+
* @private internal utility of `coder run` command
|
|
41296
|
+
*/
|
|
41297
|
+
function parsePositiveIntegerOption(value) {
|
|
41298
|
+
const parsed = Number(value);
|
|
41299
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
41300
|
+
throw new NotAllowed(spaceTrim$1(`
|
|
41301
|
+
Invalid value for \`--limit\`: \`${value}\`.
|
|
41302
|
+
|
|
41303
|
+
Use a positive integer.
|
|
41304
|
+
`));
|
|
41305
|
+
}
|
|
41306
|
+
return parsed;
|
|
41307
|
+
}
|
|
40873
41308
|
/**
|
|
40874
41309
|
* Joins one Commander option that may be parsed either as a single string or a variadic token array.
|
|
40875
41310
|
*
|
|
@@ -70285,7 +70720,7 @@ const DEFAULT_WAIT_AFTER_ERROR_MS = 10 * 60 * 1000;
|
|
|
70285
70720
|
/**
|
|
70286
70721
|
* CLI usage text for this script.
|
|
70287
70722
|
*/
|
|
70288
|
-
const USAGE = 'Usage: run-codex-prompts [--dry-run] [--harness <harness-name>] [--model <model>] [--context <context-or-file>] [--test <test-command...>] [--preserve-logs] [--no-ui] [--thinking-level <thinking-level>] [--priority <minimum-priority>] [--allow-credits] [--auto-migrate] [--allow-destructive-auto-migrate] [--wait-after-prompt <duration>] [--wait-between-prompts <duration>] [--wait-after-error <duration>] [--no-auto] [--no-commit] [--ignore-git-changes] [--no-normalize-line-endings] [--auto-push] [--auto-pull]';
|
|
70723
|
+
const USAGE = 'Usage: run-codex-prompts [--dry-run] [--harness <harness-name>] [--model <model>] [--context <context-or-file>] [--test <test-command...>] [--preserve-logs] [--no-ui] [--thinking-level <thinking-level>] [--priority <minimum-priority>] [--limit <run-count>] [--allow-credits] [--auto-migrate] [--allow-destructive-auto-migrate] [--wait-after-prompt <duration>] [--wait-between-prompts <duration>] [--wait-after-error <duration>] [--no-auto] [--no-commit] [--ignore-git-changes] [--no-normalize-line-endings] [--auto-push] [--auto-pull]';
|
|
70289
70724
|
/**
|
|
70290
70725
|
* Top-level flags supported by this command.
|
|
70291
70726
|
*/
|
|
@@ -70299,6 +70734,7 @@ const KNOWN_OPTION_FLAGS = new Set([
|
|
|
70299
70734
|
'--no-ui',
|
|
70300
70735
|
'--thinking-level',
|
|
70301
70736
|
'--priority',
|
|
70737
|
+
'--limit',
|
|
70302
70738
|
'--allow-credits',
|
|
70303
70739
|
'--auto-migrate',
|
|
70304
70740
|
'--allow-destructive-auto-migrate',
|
|
@@ -70335,6 +70771,8 @@ function parseRunOptions(args) {
|
|
|
70335
70771
|
const thinkingLevelValue = readOptionValue(args, '--thinking-level');
|
|
70336
70772
|
const hasPriorityFlag = args.includes('--priority');
|
|
70337
70773
|
const priority = parsePriority(readOptionValue(args, '--priority'), hasPriorityFlag);
|
|
70774
|
+
const hasLimitFlag = args.includes('--limit');
|
|
70775
|
+
const limit = parseLimit(readOptionValue(args, '--limit'), hasLimitFlag);
|
|
70338
70776
|
const noCommit = args.includes('--no-commit');
|
|
70339
70777
|
const ignoreGitChanges = args.includes('--ignore-git-changes');
|
|
70340
70778
|
const normalizeLineEndings = !args.includes('--no-normalize-line-endings');
|
|
@@ -70389,6 +70827,7 @@ function parseRunOptions(args) {
|
|
|
70389
70827
|
testCommand,
|
|
70390
70828
|
thinkingLevel,
|
|
70391
70829
|
priority,
|
|
70830
|
+
limit,
|
|
70392
70831
|
};
|
|
70393
70832
|
}
|
|
70394
70833
|
/**
|
|
@@ -70452,6 +70891,22 @@ function parsePriority(priorityValue, hasPriorityFlag) {
|
|
|
70452
70891
|
}
|
|
70453
70892
|
return priority;
|
|
70454
70893
|
}
|
|
70894
|
+
/**
|
|
70895
|
+
* Parses and validates the optional successful prompt-run limit.
|
|
70896
|
+
*/
|
|
70897
|
+
function parseLimit(limitValue, hasLimitFlag) {
|
|
70898
|
+
if (limitValue === undefined) {
|
|
70899
|
+
if (hasLimitFlag) {
|
|
70900
|
+
exitWithUsageError('Missing value for --limit. Use a positive integer.');
|
|
70901
|
+
}
|
|
70902
|
+
return undefined;
|
|
70903
|
+
}
|
|
70904
|
+
const limit = Number(limitValue);
|
|
70905
|
+
if (!Number.isInteger(limit) || limit <= 0) {
|
|
70906
|
+
exitWithUsageError(`Invalid value for --limit: "${limitValue}". Use a positive integer.`);
|
|
70907
|
+
}
|
|
70908
|
+
return limit;
|
|
70909
|
+
}
|
|
70455
70910
|
/**
|
|
70456
70911
|
* Prints an argument error with usage and exits the process.
|
|
70457
70912
|
*/
|
|
@@ -72561,11 +73016,12 @@ async function runPromptRound({ options, runner, runnerMetadata, nextPrompt, pro
|
|
|
72561
73016
|
// Prepend agent system message before the task so the harness sees agent instructions first
|
|
72562
73017
|
const promptWithAgent = resolvedAgentSystemMessage
|
|
72563
73018
|
? spaceTrim$1((block) => `
|
|
72564
|
-
|
|
72565
|
-
|
|
73019
|
+
|
|
72566
73020
|
## Your Task
|
|
72567
73021
|
|
|
72568
73022
|
${block(taskPrompt)}
|
|
73023
|
+
|
|
73024
|
+
${block(resolvedAgentSystemMessage.trim())}
|
|
72569
73025
|
`)
|
|
72570
73026
|
: taskPrompt;
|
|
72571
73027
|
const codexPrompt = appendCoderContext(promptWithAgent, resolvedCoderContext);
|
|
@@ -72888,6 +73344,7 @@ async function runCodexPrompts(providedOptions) {
|
|
|
72888
73344
|
let hasWaitedForStart = false;
|
|
72889
73345
|
let previousRoundStartTime;
|
|
72890
73346
|
let previousRoundEndTime;
|
|
73347
|
+
let completedRunCount = 0;
|
|
72891
73348
|
while (just(true)) {
|
|
72892
73349
|
if (options.autoPull && !options.dryRun) {
|
|
72893
73350
|
await waitForRequestedPause({
|
|
@@ -72973,6 +73430,15 @@ async function runCodexPrompts(providedOptions) {
|
|
|
72973
73430
|
});
|
|
72974
73431
|
previousRoundStartTime = currentRoundStartTime;
|
|
72975
73432
|
previousRoundEndTime = Date.now();
|
|
73433
|
+
completedRunCount += 1;
|
|
73434
|
+
if (isRunLimitReached({ completedRunCount, limit: options.limit })) {
|
|
73435
|
+
finishWhenRunLimitIsReached({
|
|
73436
|
+
completedRunCount,
|
|
73437
|
+
isRichUiEnabled,
|
|
73438
|
+
uiHandle,
|
|
73439
|
+
});
|
|
73440
|
+
return;
|
|
73441
|
+
}
|
|
72976
73442
|
}
|
|
72977
73443
|
}
|
|
72978
73444
|
finally {
|
|
@@ -73002,6 +73468,13 @@ function validateRunCodexPromptOptions(options) {
|
|
|
73002
73468
|
Auto-pull keeps the repository up to date between prompt rounds, which requires each successful round to end with a clean committed working tree.
|
|
73003
73469
|
`));
|
|
73004
73470
|
}
|
|
73471
|
+
if (options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit <= 0)) {
|
|
73472
|
+
throw new NotAllowed(spaceTrim$1(`
|
|
73473
|
+
Flag \`--limit\` expects a positive integer.
|
|
73474
|
+
|
|
73475
|
+
Received: \`${options.limit}\`
|
|
73476
|
+
`));
|
|
73477
|
+
}
|
|
73005
73478
|
}
|
|
73006
73479
|
/**
|
|
73007
73480
|
* Pulls the latest repository state before loading prompts when the feature is enabled.
|
|
@@ -73148,6 +73621,21 @@ function finishWhenNoPromptIsAvailable(promptQueueSnapshot, isRichUiEnabled, uiH
|
|
|
73148
73621
|
}
|
|
73149
73622
|
return true;
|
|
73150
73623
|
}
|
|
73624
|
+
/**
|
|
73625
|
+
* Checks whether the configured successful prompt-run limit has been reached.
|
|
73626
|
+
*/
|
|
73627
|
+
function isRunLimitReached(options) {
|
|
73628
|
+
const { completedRunCount, limit } = options;
|
|
73629
|
+
return limit !== undefined && completedRunCount >= limit;
|
|
73630
|
+
}
|
|
73631
|
+
/**
|
|
73632
|
+
* Updates UI and console output when a user-configured run limit stops the loop.
|
|
73633
|
+
*/
|
|
73634
|
+
function finishWhenRunLimitIsReached(options) {
|
|
73635
|
+
const { completedRunCount, isRichUiEnabled, uiHandle } = options;
|
|
73636
|
+
const runCountLabel = completedRunCount === 1 ? '1 prompt run' : `${completedRunCount} prompt runs`;
|
|
73637
|
+
announceRunCompletion(`Run limit reached after ${runCountLabel}.`, colors.green, isRichUiEnabled, uiHandle);
|
|
73638
|
+
}
|
|
73151
73639
|
/**
|
|
73152
73640
|
* Updates the UI status message while waiting for new prompts in keepAlive server mode.
|
|
73153
73641
|
*/
|