@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/umd/index.umd.js
CHANGED
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
* @generated
|
|
64
64
|
* @see https://github.com/webgptorg/promptbook
|
|
65
65
|
*/
|
|
66
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.
|
|
66
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.113.0-1';
|
|
67
67
|
/**
|
|
68
68
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
69
69
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -3303,6 +3303,28 @@
|
|
|
3303
3303
|
* @private internal constant of `ptbk agents-server`
|
|
3304
3304
|
*/
|
|
3305
3305
|
const AGENTS_SERVER_BUILD_MAX_OLD_SPACE_MIB = 4096;
|
|
3306
|
+
/**
|
|
3307
|
+
* Conservative Next.js build worker count used by CLI-owned Agents Server production builds.
|
|
3308
|
+
*
|
|
3309
|
+
* Standalone VPS self-updates build the replacement server while the current pm2 process is
|
|
3310
|
+
* still serving traffic. Keeping Next's static workers serial avoids CPU-count-based memory
|
|
3311
|
+
* spikes that can make the OS kill the build child with no normal exit code.
|
|
3312
|
+
*
|
|
3313
|
+
* @private internal constant of `ptbk agents-server`
|
|
3314
|
+
*/
|
|
3315
|
+
const AGENTS_SERVER_BUILD_WORKER_COUNT = 1;
|
|
3316
|
+
/**
|
|
3317
|
+
* Maximum attempts for a Next.js build that was killed by the operating system.
|
|
3318
|
+
*
|
|
3319
|
+
* @private internal constant of `ptbk agents-server`
|
|
3320
|
+
*/
|
|
3321
|
+
const AGENTS_SERVER_BUILD_MAX_ATTEMPTS = 2;
|
|
3322
|
+
/**
|
|
3323
|
+
* Signals that indicate the Next.js build may have been terminated by resource pressure.
|
|
3324
|
+
*
|
|
3325
|
+
* @private internal constant of `ptbk agents-server`
|
|
3326
|
+
*/
|
|
3327
|
+
const RETRYABLE_NEXT_BUILD_SIGNALS = new Set(['SIGKILL', null]);
|
|
3306
3328
|
/**
|
|
3307
3329
|
* Environment variable passed to the bundled Next app so webpack can resolve dependencies
|
|
3308
3330
|
* installed beside `ptbk` even when the app sources are materialized into a project cache.
|
|
@@ -3310,6 +3332,12 @@
|
|
|
3310
3332
|
* @private internal constant of `ptbk agents-server`
|
|
3311
3333
|
*/
|
|
3312
3334
|
const PTBK_AGENTS_SERVER_NODE_MODULES_PATH_ENV = 'PTBK_AGENTS_SERVER_NODE_MODULES_PATH';
|
|
3335
|
+
/**
|
|
3336
|
+
* Environment variable consumed by `apps/agents-server/next.config.ts` to throttle build workers.
|
|
3337
|
+
*
|
|
3338
|
+
* @private internal constant of `ptbk agents-server`
|
|
3339
|
+
*/
|
|
3340
|
+
const PTBK_AGENTS_SERVER_BUILD_WORKER_COUNT_ENV = 'PTBK_AGENTS_SERVER_BUILD_WORKER_COUNT';
|
|
3313
3341
|
/**
|
|
3314
3342
|
* Environment variable used only by the CLI-owned production build.
|
|
3315
3343
|
*
|
|
@@ -3510,6 +3538,7 @@
|
|
|
3510
3538
|
...environment,
|
|
3511
3539
|
NODE_PATH: mergeNodePath(nodeModulesPath, environment.NODE_PATH),
|
|
3512
3540
|
[PTBK_AGENTS_SERVER_NODE_MODULES_PATH_ENV]: nodeModulesPath,
|
|
3541
|
+
[PTBK_AGENTS_SERVER_BUILD_WORKER_COUNT_ENV]: environment[PTBK_AGENTS_SERVER_BUILD_WORKER_COUNT_ENV] || String(AGENTS_SERVER_BUILD_WORKER_COUNT),
|
|
3513
3542
|
...(options.isNextValidationIgnored
|
|
3514
3543
|
? {
|
|
3515
3544
|
[PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION_ENV]: 'true',
|
|
@@ -3696,14 +3725,27 @@
|
|
|
3696
3725
|
* Runs the finite Next production build used by local Agents Server commands.
|
|
3697
3726
|
*/
|
|
3698
3727
|
async function runNextBuild(options) {
|
|
3699
|
-
|
|
3728
|
+
for (let attempt = 1; attempt <= AGENTS_SERVER_BUILD_MAX_ATTEMPTS; attempt++) {
|
|
3729
|
+
const exitStatus = await runNextBuildAttempt(options);
|
|
3730
|
+
if (exitStatus.code === 0) {
|
|
3731
|
+
return;
|
|
3732
|
+
}
|
|
3733
|
+
if (attempt < AGENTS_SERVER_BUILD_MAX_ATTEMPTS && isNextBuildTerminationRetryable(exitStatus)) {
|
|
3734
|
+
forwardBuildOutput(createNextBuildRetryMessage(exitStatus, attempt + 1), options.onBuildOutput);
|
|
3735
|
+
continue;
|
|
3736
|
+
}
|
|
3737
|
+
throw createNextBuildExitError(exitStatus, attempt);
|
|
3738
|
+
}
|
|
3739
|
+
}
|
|
3740
|
+
/**
|
|
3741
|
+
* Runs one Next.js production build attempt and returns its exit status.
|
|
3742
|
+
*/
|
|
3743
|
+
async function runNextBuildAttempt(options) {
|
|
3744
|
+
return await new Promise((resolveBuild, rejectBuild) => {
|
|
3700
3745
|
var _a, _b;
|
|
3701
3746
|
const buildProcess = child_process.spawn(process.execPath, [options.nextCliPath, 'build'], {
|
|
3702
3747
|
cwd: options.appPath,
|
|
3703
|
-
env:
|
|
3704
|
-
...options.environment,
|
|
3705
|
-
NODE_OPTIONS: mergeNodeOptionsWithHeapSize(options.environment.NODE_OPTIONS, AGENTS_SERVER_BUILD_MAX_OLD_SPACE_MIB),
|
|
3706
|
-
},
|
|
3748
|
+
env: createNextBuildProcessEnvironment(options.environment),
|
|
3707
3749
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
3708
3750
|
});
|
|
3709
3751
|
(_a = buildProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (chunk) => {
|
|
@@ -3712,16 +3754,70 @@
|
|
|
3712
3754
|
(_b = buildProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (chunk) => {
|
|
3713
3755
|
forwardBuildOutput(chunk.toString(), options.onBuildOutput);
|
|
3714
3756
|
});
|
|
3715
|
-
buildProcess.once('error',
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
}
|
|
3721
|
-
rejectBuild(new Error(`next-build exited with code ${String(code)}.`));
|
|
3757
|
+
buildProcess.once('error', (error) => {
|
|
3758
|
+
rejectBuild(createNextBuildSpawnError(error));
|
|
3759
|
+
});
|
|
3760
|
+
buildProcess.once('close', (code, signal) => {
|
|
3761
|
+
resolveBuild({ code, signal });
|
|
3722
3762
|
});
|
|
3723
3763
|
});
|
|
3724
3764
|
}
|
|
3765
|
+
/**
|
|
3766
|
+
* Creates the environment passed to the spawned Next.js build process.
|
|
3767
|
+
*/
|
|
3768
|
+
function createNextBuildProcessEnvironment(environment) {
|
|
3769
|
+
return {
|
|
3770
|
+
...environment,
|
|
3771
|
+
NODE_OPTIONS: mergeNodeOptionsWithHeapSize(environment.NODE_OPTIONS, AGENTS_SERVER_BUILD_MAX_OLD_SPACE_MIB),
|
|
3772
|
+
};
|
|
3773
|
+
}
|
|
3774
|
+
/**
|
|
3775
|
+
* Returns true when one failed build attempt is worth retrying.
|
|
3776
|
+
*/
|
|
3777
|
+
function isNextBuildTerminationRetryable(exitStatus) {
|
|
3778
|
+
return exitStatus.code === null && RETRYABLE_NEXT_BUILD_SIGNALS.has(exitStatus.signal);
|
|
3779
|
+
}
|
|
3780
|
+
/**
|
|
3781
|
+
* Creates one visible retry message for a killed Next.js build attempt.
|
|
3782
|
+
*/
|
|
3783
|
+
function createNextBuildRetryMessage(exitStatus, nextAttempt) {
|
|
3784
|
+
return `\nAgents Server Next build was terminated by ${describeNextBuildExitStatus(exitStatus)}. Retrying attempt ${nextAttempt}/${AGENTS_SERVER_BUILD_MAX_ATTEMPTS}.\n`;
|
|
3785
|
+
}
|
|
3786
|
+
/**
|
|
3787
|
+
* Creates a branded error for a failed Next.js build child process.
|
|
3788
|
+
*/
|
|
3789
|
+
function createNextBuildExitError(exitStatus, attemptCount) {
|
|
3790
|
+
const lowMemoryHint = isNextBuildTerminationRetryable(exitStatus)
|
|
3791
|
+
? '\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.'
|
|
3792
|
+
: '';
|
|
3793
|
+
return new NotAllowed(_spaceTrim.spaceTrim(`
|
|
3794
|
+
Agents Server Next production build failed.
|
|
3795
|
+
|
|
3796
|
+
- Exit code: \`${String(exitStatus.code)}\`
|
|
3797
|
+
- Signal: \`${String(exitStatus.signal)}\`
|
|
3798
|
+
- Attempts: \`${String(attemptCount)}\`
|
|
3799
|
+
${lowMemoryHint}
|
|
3800
|
+
`));
|
|
3801
|
+
}
|
|
3802
|
+
/**
|
|
3803
|
+
* Creates a branded error for failures to start the Next.js build child process.
|
|
3804
|
+
*/
|
|
3805
|
+
function createNextBuildSpawnError(error) {
|
|
3806
|
+
return new NotAllowed(_spaceTrim.spaceTrim(`
|
|
3807
|
+
Cannot start the Agents Server Next production build.
|
|
3808
|
+
|
|
3809
|
+
${error.message}
|
|
3810
|
+
`));
|
|
3811
|
+
}
|
|
3812
|
+
/**
|
|
3813
|
+
* Formats one Next.js build exit status for foreground logs.
|
|
3814
|
+
*/
|
|
3815
|
+
function describeNextBuildExitStatus(exitStatus) {
|
|
3816
|
+
if (exitStatus.signal) {
|
|
3817
|
+
return `signal \`${exitStatus.signal}\``;
|
|
3818
|
+
}
|
|
3819
|
+
return `exit code \`${String(exitStatus.code)}\``;
|
|
3820
|
+
}
|
|
3725
3821
|
/**
|
|
3726
3822
|
* Prepends `--max-old-space-size=<mib>` to `NODE_OPTIONS` unless the caller already set one.
|
|
3727
3823
|
*/
|
|
@@ -16452,6 +16548,70 @@
|
|
|
16452
16548
|
}
|
|
16453
16549
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
16454
16550
|
|
|
16551
|
+
/**
|
|
16552
|
+
* META VISIBILITY commitment definition.
|
|
16553
|
+
*
|
|
16554
|
+
* The `META VISIBILITY` commitment stores whether an agent is public, private, or unlisted.
|
|
16555
|
+
* Agents Server mirrors this value into the database for efficient filtering, but the book
|
|
16556
|
+
* commitment remains the editable source of truth.
|
|
16557
|
+
*
|
|
16558
|
+
* @private Metadata-only commitment used by Agents Server.
|
|
16559
|
+
*/
|
|
16560
|
+
class MetaVisibilityCommitmentDefinition extends BaseCommitmentDefinition {
|
|
16561
|
+
constructor() {
|
|
16562
|
+
super('META VISIBILITY');
|
|
16563
|
+
}
|
|
16564
|
+
/**
|
|
16565
|
+
* Short one-line description of META VISIBILITY.
|
|
16566
|
+
*/
|
|
16567
|
+
get description() {
|
|
16568
|
+
return 'Set whether the agent is private, unlisted, or public.';
|
|
16569
|
+
}
|
|
16570
|
+
/**
|
|
16571
|
+
* Icon for this commitment.
|
|
16572
|
+
*/
|
|
16573
|
+
get icon() {
|
|
16574
|
+
return '👁️';
|
|
16575
|
+
}
|
|
16576
|
+
/**
|
|
16577
|
+
* Markdown documentation for META VISIBILITY commitment.
|
|
16578
|
+
*/
|
|
16579
|
+
get documentation() {
|
|
16580
|
+
return _spaceTrim.spaceTrim(`
|
|
16581
|
+
# META VISIBILITY
|
|
16582
|
+
|
|
16583
|
+
Sets the agent visibility used by Agents Server.
|
|
16584
|
+
|
|
16585
|
+
## Allowed values
|
|
16586
|
+
|
|
16587
|
+
- \`PRIVATE\` - accessible only to signed-in users with access.
|
|
16588
|
+
- \`UNLISTED\` - accessible by direct link but hidden from public listings.
|
|
16589
|
+
- \`PUBLIC\` - visible in public listings and accessible by anyone.
|
|
16590
|
+
|
|
16591
|
+
## Key aspects
|
|
16592
|
+
|
|
16593
|
+
- Does not modify the agent's behavior, system message, or tools.
|
|
16594
|
+
- Whitespace and letter case are normalized when persisted.
|
|
16595
|
+
- If multiple \`META VISIBILITY\` commitments are present, persistence keeps one normalized value.
|
|
16596
|
+
- Agents Server mirrors the value into the database for filtering, but the book is the source of truth.
|
|
16597
|
+
|
|
16598
|
+
## Example
|
|
16599
|
+
|
|
16600
|
+
\`\`\`book
|
|
16601
|
+
Helpful Assistant
|
|
16602
|
+
|
|
16603
|
+
GOAL Be helpful and friendly.
|
|
16604
|
+
META VISIBILITY PUBLIC
|
|
16605
|
+
\`\`\`
|
|
16606
|
+
`);
|
|
16607
|
+
}
|
|
16608
|
+
applyToAgentModelRequirements(requirements, content) {
|
|
16609
|
+
// META VISIBILITY is metadata only and does not alter model requirements.
|
|
16610
|
+
return requirements;
|
|
16611
|
+
}
|
|
16612
|
+
}
|
|
16613
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
16614
|
+
|
|
16455
16615
|
/**
|
|
16456
16616
|
* META VOICE commitment definition
|
|
16457
16617
|
*
|
|
@@ -22947,31 +23107,65 @@
|
|
|
22947
23107
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
22948
23108
|
|
|
22949
23109
|
/**
|
|
22950
|
-
* This error
|
|
23110
|
+
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
22951
23111
|
*
|
|
22952
23112
|
* @public exported from `@promptbook/core`
|
|
22953
23113
|
*/
|
|
22954
|
-
class
|
|
23114
|
+
class ParseError extends Error {
|
|
22955
23115
|
constructor(message) {
|
|
22956
23116
|
super(message);
|
|
22957
|
-
this.name = '
|
|
22958
|
-
Object.setPrototypeOf(this,
|
|
23117
|
+
this.name = 'ParseError';
|
|
23118
|
+
Object.setPrototypeOf(this, ParseError.prototype);
|
|
22959
23119
|
}
|
|
22960
23120
|
}
|
|
23121
|
+
// TODO: Maybe split `ParseError` and `ApplyError`
|
|
22961
23122
|
|
|
22962
23123
|
/**
|
|
22963
|
-
*
|
|
23124
|
+
* Supported visibility states for persisted agents.
|
|
22964
23125
|
*
|
|
22965
23126
|
* @public exported from `@promptbook/core`
|
|
22966
23127
|
*/
|
|
22967
|
-
|
|
23128
|
+
const AGENT_VISIBILITY_VALUES = ['PRIVATE', 'UNLISTED', 'PUBLIC'];
|
|
23129
|
+
/**
|
|
23130
|
+
* Returns `true` when the value is one of supported visibility states.
|
|
23131
|
+
*
|
|
23132
|
+
* @param value - Raw value to validate.
|
|
23133
|
+
* @returns Whether the value is a valid `AgentVisibility`.
|
|
23134
|
+
*
|
|
23135
|
+
* @public exported from `@promptbook/core`
|
|
23136
|
+
*/
|
|
23137
|
+
function isAgentVisibility(value) {
|
|
23138
|
+
return typeof value === 'string' && AGENT_VISIBILITY_VALUES.includes(value);
|
|
23139
|
+
}
|
|
23140
|
+
/**
|
|
23141
|
+
* Normalizes raw visibility text into a supported value.
|
|
23142
|
+
*
|
|
23143
|
+
* @param value - Raw visibility value.
|
|
23144
|
+
* @returns Normalized visibility, or `null` when invalid.
|
|
23145
|
+
*
|
|
23146
|
+
* @public exported from `@promptbook/core`
|
|
23147
|
+
*/
|
|
23148
|
+
function normalizeAgentVisibility(value) {
|
|
23149
|
+
if (typeof value !== 'string') {
|
|
23150
|
+
return null;
|
|
23151
|
+
}
|
|
23152
|
+
const normalized = value.trim().toUpperCase();
|
|
23153
|
+
return isAgentVisibility(normalized) ? normalized : null;
|
|
23154
|
+
}
|
|
23155
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
23156
|
+
|
|
23157
|
+
/**
|
|
23158
|
+
* This error type indicates that some limit was reached
|
|
23159
|
+
*
|
|
23160
|
+
* @public exported from `@promptbook/core`
|
|
23161
|
+
*/
|
|
23162
|
+
class LimitReachedError extends Error {
|
|
22968
23163
|
constructor(message) {
|
|
22969
23164
|
super(message);
|
|
22970
|
-
this.name = '
|
|
22971
|
-
Object.setPrototypeOf(this,
|
|
23165
|
+
this.name = 'LimitReachedError';
|
|
23166
|
+
Object.setPrototypeOf(this, LimitReachedError.prototype);
|
|
22972
23167
|
}
|
|
22973
23168
|
}
|
|
22974
|
-
// TODO: Maybe split `ParseError` and `ApplyError`
|
|
22975
23169
|
|
|
22976
23170
|
/**
|
|
22977
23171
|
* Maximum allowed source length for create-agent payloads.
|
|
@@ -25306,6 +25500,7 @@
|
|
|
25306
25500
|
new MetaDomainCommitmentDefinition(),
|
|
25307
25501
|
new MetaDisclaimerCommitmentDefinition(),
|
|
25308
25502
|
new MetaInputPlaceholderCommitmentDefinition(),
|
|
25503
|
+
new MetaVisibilityCommitmentDefinition(),
|
|
25309
25504
|
new MetaCommitmentDefinition(),
|
|
25310
25505
|
new MetaVoiceCommitmentDefinition(),
|
|
25311
25506
|
new NoteCommitmentDefinition('NOTE'),
|
|
@@ -25757,6 +25952,7 @@
|
|
|
25757
25952
|
'META COLOR': applyMetaColorContent,
|
|
25758
25953
|
'META FONT': applyMetaFontContent,
|
|
25759
25954
|
'META VOICE': applyMetaVoiceContent,
|
|
25955
|
+
'META VISIBILITY': applyMetaVisibilityContent,
|
|
25760
25956
|
};
|
|
25761
25957
|
/**
|
|
25762
25958
|
* Applies META-style commitments that mutate parsed profile metadata.
|
|
@@ -25786,6 +25982,10 @@
|
|
|
25786
25982
|
applyMetaAvatarContent(state, metaValue);
|
|
25787
25983
|
return;
|
|
25788
25984
|
}
|
|
25985
|
+
if (metaTypeRaw.toUpperCase() === 'VISIBILITY') {
|
|
25986
|
+
applyMetaVisibilityContent(state, metaValue);
|
|
25987
|
+
return;
|
|
25988
|
+
}
|
|
25789
25989
|
const metaType = normalizeTo_camelCase(metaTypeRaw);
|
|
25790
25990
|
state.meta[metaType] = metaValue;
|
|
25791
25991
|
}
|
|
@@ -25862,6 +26062,15 @@
|
|
|
25862
26062
|
function applyMetaVoiceContent(state, content) {
|
|
25863
26063
|
state.meta.voice = _spaceTrim.spaceTrim(content);
|
|
25864
26064
|
}
|
|
26065
|
+
/**
|
|
26066
|
+
* Applies META VISIBILITY content into the normalized `meta.visibility` field.
|
|
26067
|
+
*/
|
|
26068
|
+
function applyMetaVisibilityContent(state, content) {
|
|
26069
|
+
const visibility = normalizeAgentVisibility(content);
|
|
26070
|
+
if (visibility) {
|
|
26071
|
+
state.meta.visibility = visibility;
|
|
26072
|
+
}
|
|
26073
|
+
}
|
|
25865
26074
|
/**
|
|
25866
26075
|
* Normalizes the separator in the content
|
|
25867
26076
|
*
|
|
@@ -37434,7 +37643,7 @@
|
|
|
37434
37643
|
validateAgentRunOptions(options);
|
|
37435
37644
|
const projectPath = tickOptions.projectPath || process.cwd();
|
|
37436
37645
|
let queueSnapshot = await loadAgentMessageQueueSnapshot(projectPath);
|
|
37437
|
-
let queuedMessage = queueSnapshot.
|
|
37646
|
+
let queuedMessage = resolveSelectedQueuedMessage(queueSnapshot, tickOptions.queuedMessage);
|
|
37438
37647
|
if (!queuedMessage) {
|
|
37439
37648
|
announceNoQueuedMessages(tickOptions);
|
|
37440
37649
|
return { isMessageProcessed: false };
|
|
@@ -37449,7 +37658,7 @@
|
|
|
37449
37658
|
});
|
|
37450
37659
|
if (autoPullTimestamp !== undefined) {
|
|
37451
37660
|
queueSnapshot = await loadAgentMessageQueueSnapshot(projectPath);
|
|
37452
|
-
queuedMessage = queueSnapshot.
|
|
37661
|
+
queuedMessage = resolveSelectedQueuedMessage(queueSnapshot, tickOptions.queuedMessage);
|
|
37453
37662
|
if (!queuedMessage) {
|
|
37454
37663
|
if (tickOptions.uiHandle && !((_b = tickOptions.uiPresentation) === null || _b === void 0 ? void 0 : _b.isSharedDashboard)) {
|
|
37455
37664
|
updateAgentRunUiForWatching(tickOptions.uiHandle, queueSnapshot);
|
|
@@ -37475,7 +37684,7 @@
|
|
|
37475
37684
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.updateProgress(((_e = tickOptions.uiPresentation) === null || _e === void 0 ? void 0 : _e.completedProgressStats) ||
|
|
37476
37685
|
createAgentQueueProgressSnapshot({
|
|
37477
37686
|
finishedMessageCount: queueSnapshot.finishedMessageCount + 1,
|
|
37478
|
-
queuedMessages: queueSnapshot
|
|
37687
|
+
queuedMessages: removeQueuedMessageFromSnapshot(queueSnapshot, queuedMessage),
|
|
37479
37688
|
}));
|
|
37480
37689
|
if ((_f = tickOptions.uiPresentation) === null || _f === void 0 ? void 0 : _f.completedAgentStatusLines) {
|
|
37481
37690
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setAgentStatusLines([...tickOptions.uiPresentation.completedAgentStatusLines]);
|
|
@@ -37487,7 +37696,9 @@
|
|
|
37487
37696
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setMessagePreviewLines([...tickOptions.uiPresentation.completedMessagePreviewLines]);
|
|
37488
37697
|
}
|
|
37489
37698
|
if ((_j = tickOptions.uiPresentation) === null || _j === void 0 ? void 0 : _j.completedMessagePreviewSections) {
|
|
37490
|
-
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setMessagePreviewSections([
|
|
37699
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setMessagePreviewSections([
|
|
37700
|
+
...tickOptions.uiPresentation.completedMessagePreviewSections,
|
|
37701
|
+
]);
|
|
37491
37702
|
}
|
|
37492
37703
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setStatusMessage('Message answered');
|
|
37493
37704
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setPhase('done');
|
|
@@ -37515,6 +37726,21 @@
|
|
|
37515
37726
|
printAgentGitIdentityTipAtProcessExitIfNeeded();
|
|
37516
37727
|
}
|
|
37517
37728
|
}
|
|
37729
|
+
/**
|
|
37730
|
+
* Resolves either the explicitly selected queued message or the first available queue item.
|
|
37731
|
+
*/
|
|
37732
|
+
function resolveSelectedQueuedMessage(queueSnapshot, selectedQueuedMessage) {
|
|
37733
|
+
if (!selectedQueuedMessage) {
|
|
37734
|
+
return queueSnapshot.queuedMessages[0];
|
|
37735
|
+
}
|
|
37736
|
+
return queueSnapshot.queuedMessages.find((queuedMessage) => queuedMessage.relativePath === selectedQueuedMessage.relativePath);
|
|
37737
|
+
}
|
|
37738
|
+
/**
|
|
37739
|
+
* Creates a progress queue list with the processed message removed from its original snapshot.
|
|
37740
|
+
*/
|
|
37741
|
+
function removeQueuedMessageFromSnapshot(queueSnapshot, processedQueuedMessage) {
|
|
37742
|
+
return queueSnapshot.queuedMessages.filter((queuedMessage) => queuedMessage.relativePath !== processedQueuedMessage.relativePath);
|
|
37743
|
+
}
|
|
37518
37744
|
/**
|
|
37519
37745
|
* Runs the selected coding runner for one message and finalizes the answered file.
|
|
37520
37746
|
*/
|
|
@@ -37635,7 +37861,9 @@
|
|
|
37635
37861
|
return;
|
|
37636
37862
|
}
|
|
37637
37863
|
uiHandle.state.setCurrentPrompt(queuedMessage.relativePath);
|
|
37638
|
-
uiHandle.state.setMessagePreviewLines([
|
|
37864
|
+
uiHandle.state.setMessagePreviewLines([
|
|
37865
|
+
...((uiPresentation === null || uiPresentation === void 0 ? void 0 : uiPresentation.messagePreviewLines) || agentUiMetadata.latestUserMessageLines),
|
|
37866
|
+
]);
|
|
37639
37867
|
uiHandle.state.setPhase('loading');
|
|
37640
37868
|
uiHandle.state.setStatusMessage('Preparing message');
|
|
37641
37869
|
}
|
|
@@ -37914,12 +38142,16 @@
|
|
|
37914
38142
|
* Watches all direct child agent repositories from the current directory in one shared session.
|
|
37915
38143
|
*/
|
|
37916
38144
|
async function runMultipleAgentMessages(options, controls = {}) {
|
|
37917
|
-
var _a;
|
|
38145
|
+
var _a, _b;
|
|
37918
38146
|
validateAgentRunOptions(options);
|
|
37919
38147
|
validateAgentWatchOptions('ptbk agent-folder run-multiple', options);
|
|
37920
38148
|
const rootPath = process.cwd();
|
|
37921
38149
|
const shouldContinue = controls.shouldContinue || (() => just(true));
|
|
38150
|
+
const queuePollIntervalMs = (_a = controls.queuePollIntervalMs) !== null && _a !== void 0 ? _a : MULTI_AGENT_QUEUE_POLL_INTERVAL_MS;
|
|
37922
38151
|
const ignoreMatcher = createAgentIgnoreMatcher(options.ignorePatterns);
|
|
38152
|
+
const isParallelMessageLimitConfigured = options.maxParallelMessages !== undefined;
|
|
38153
|
+
const maxParallelMessageCount = normalizeMaxParallelMessageCount(options.maxParallelMessages);
|
|
38154
|
+
const activeMessageTasksByKey = new Map();
|
|
37923
38155
|
let githubSynchronizationTimestamp;
|
|
37924
38156
|
let githubIgnoredRepositoryCount = 0;
|
|
37925
38157
|
const autoPullTimestampsByProjectPath = new Map();
|
|
@@ -37934,7 +38166,7 @@
|
|
|
37934
38166
|
if (!isWatchSessionInitialized) {
|
|
37935
38167
|
uiHandle = await initializeMultipleAgentRunUi(options);
|
|
37936
38168
|
isWatchSessionInitialized = true;
|
|
37937
|
-
(
|
|
38169
|
+
(_b = controls.onUiInitialized) === null || _b === void 0 ? void 0 : _b.call(controls, uiHandle);
|
|
37938
38170
|
if (!uiHandle) {
|
|
37939
38171
|
console.info(colors__default["default"].green('Watching direct child agent repositories for queued messages.'));
|
|
37940
38172
|
}
|
|
@@ -37957,14 +38189,19 @@
|
|
|
37957
38189
|
let projectSummaries = projectSummariesResult.projectSummaries;
|
|
37958
38190
|
lastObservedProjectCount = projectSummaries.length;
|
|
37959
38191
|
let ignoredAgentCount = projectSummariesResult.ignoredProjectCount + githubIgnoredRepositoryCount;
|
|
37960
|
-
const autoPullResult =
|
|
37961
|
-
|
|
37962
|
-
|
|
37963
|
-
|
|
37964
|
-
|
|
37965
|
-
|
|
37966
|
-
|
|
37967
|
-
|
|
38192
|
+
const autoPullResult = activeMessageTasksByKey.size === 0
|
|
38193
|
+
? await pullLatestChangesForLocalAgentRunnerProjectsIfNeeded({
|
|
38194
|
+
rootPath,
|
|
38195
|
+
runOptions: options,
|
|
38196
|
+
uiHandle,
|
|
38197
|
+
projectSummaries,
|
|
38198
|
+
ignoredAgentCount,
|
|
38199
|
+
autoPullTimestampsByProjectPath,
|
|
38200
|
+
})
|
|
38201
|
+
: {
|
|
38202
|
+
isAnyRepositoryPulled: false,
|
|
38203
|
+
pulledProjectPaths: new Set(),
|
|
38204
|
+
};
|
|
37968
38205
|
if (autoPullResult.isAnyRepositoryPulled) {
|
|
37969
38206
|
projectSummariesResult = await loadLocalAgentRunnerProjectSummaries(rootPath, {
|
|
37970
38207
|
includeMessagePreviews: Boolean(uiHandle),
|
|
@@ -37974,61 +38211,49 @@
|
|
|
37974
38211
|
lastObservedProjectCount = projectSummaries.length;
|
|
37975
38212
|
ignoredAgentCount = projectSummariesResult.ignoredProjectCount + githubIgnoredRepositoryCount;
|
|
37976
38213
|
}
|
|
37977
|
-
const
|
|
37978
|
-
|
|
38214
|
+
const availableParallelMessageSlots = Math.max(0, maxParallelMessageCount - activeMessageTasksByKey.size);
|
|
38215
|
+
const queuedWorkItems = availableParallelMessageSlots > 0
|
|
38216
|
+
? selectQueuedWorkItems({
|
|
38217
|
+
projectSummaries,
|
|
38218
|
+
activeMessageTasksByKey,
|
|
38219
|
+
availableParallelMessageSlots,
|
|
38220
|
+
isParallelMessageLimitConfigured,
|
|
38221
|
+
})
|
|
38222
|
+
: [];
|
|
38223
|
+
const answeringProjectPaths = createAnsweringProjectPaths(activeMessageTasksByKey, queuedWorkItems);
|
|
38224
|
+
if (queuedWorkItems.length === 0 && activeMessageTasksByKey.size === 0) {
|
|
37979
38225
|
updateMultipleAgentRunUiForWatching(uiHandle, options, rootPath, projectSummaries, ignoredAgentCount);
|
|
37980
|
-
await wait$3(
|
|
38226
|
+
await wait$3(queuePollIntervalMs);
|
|
38227
|
+
continue;
|
|
38228
|
+
}
|
|
38229
|
+
if (queuedWorkItems.length === 0) {
|
|
38230
|
+
updateMultipleAgentRunUiForAnswering(uiHandle, options, rootPath, projectSummaries, answeringProjectPaths, ignoredAgentCount, activeMessageTasksByKey.size);
|
|
38231
|
+
await waitForNextSchedulerTurn(activeMessageTasksByKey, queuePollIntervalMs);
|
|
37981
38232
|
continue;
|
|
37982
38233
|
}
|
|
37983
38234
|
if (!uiHandle) {
|
|
37984
|
-
for (const
|
|
37985
|
-
console.info(colors__default["default"].blue(`Processing ${formatProjectPath(rootPath,
|
|
38235
|
+
for (const queuedWorkItem of queuedWorkItems) {
|
|
38236
|
+
console.info(colors__default["default"].blue(`Processing ${formatProjectPath(rootPath, queuedWorkItem.projectSummary.project.projectPath)}/${queuedWorkItem.queuedMessage.relativePath} with ${queuedWorkItem.projectSummary.localAgentName}.`));
|
|
37986
38237
|
}
|
|
37987
38238
|
}
|
|
37988
|
-
|
|
37989
|
-
|
|
37990
|
-
|
|
37991
|
-
|
|
37992
|
-
|
|
37993
|
-
|
|
37994
|
-
|
|
37995
|
-
|
|
37996
|
-
|
|
37997
|
-
|
|
37998
|
-
|
|
37999
|
-
|
|
38239
|
+
updateMultipleAgentRunUiForAnswering(uiHandle, options, rootPath, projectSummaries, answeringProjectPaths, ignoredAgentCount, activeMessageTasksByKey.size + queuedWorkItems.length);
|
|
38240
|
+
for (const queuedWorkItem of queuedWorkItems) {
|
|
38241
|
+
startActiveAgentMessageTask({
|
|
38242
|
+
rootPath,
|
|
38243
|
+
options,
|
|
38244
|
+
queuedWorkItem,
|
|
38245
|
+
projectSummaries,
|
|
38246
|
+
answeringProjectPaths,
|
|
38247
|
+
ignoredAgentCount,
|
|
38248
|
+
autoPullResult,
|
|
38249
|
+
autoPullTimestampsByProjectPath,
|
|
38250
|
+
activeMessageTasksByKey,
|
|
38251
|
+
messageFailureTracker,
|
|
38000
38252
|
uiHandle,
|
|
38001
|
-
|
|
38002
|
-
? buildMultiAgentTickUiPresentation({
|
|
38003
|
-
rootPath,
|
|
38004
|
-
projectSummaries,
|
|
38005
|
-
answeringProjectPaths,
|
|
38006
|
-
ignoredAgentCount,
|
|
38007
|
-
})
|
|
38008
|
-
: undefined,
|
|
38009
|
-
});
|
|
38010
|
-
return {
|
|
38011
|
-
projectPath: queuedProject.project.projectPath,
|
|
38012
|
-
tickResult,
|
|
38013
|
-
};
|
|
38014
|
-
}));
|
|
38015
|
-
for (const tickResult of tickResults) {
|
|
38016
|
-
if (tickResult.status === 'fulfilled') {
|
|
38017
|
-
if (tickResult.value.tickResult.autoPullTimestamp !== undefined) {
|
|
38018
|
-
autoPullTimestampsByProjectPath.set(tickResult.value.projectPath, tickResult.value.tickResult.autoPullTimestamp);
|
|
38019
|
-
}
|
|
38020
|
-
if (tickResult.value.tickResult.isMessageProcessed) {
|
|
38021
|
-
messageFailureTracker.clearMessageFailure(tickResult.value.projectPath, tickResult.value.tickResult.queuedMessage);
|
|
38022
|
-
}
|
|
38023
|
-
continue;
|
|
38024
|
-
}
|
|
38025
|
-
await handleAgentWatchError({
|
|
38026
|
-
commandDisplayName: 'ptbk agent-folder run-multiple',
|
|
38027
|
-
logDirectoryPath: controls.watchErrorLogDirectoryPath || rootPath,
|
|
38028
|
-
error: tickResult.reason,
|
|
38253
|
+
watchErrorLogDirectoryPath: controls.watchErrorLogDirectoryPath || rootPath,
|
|
38029
38254
|
});
|
|
38030
|
-
await messageFailureTracker.recordFailure(tickResult.reason);
|
|
38031
38255
|
}
|
|
38256
|
+
await waitForNextSchedulerTurn(activeMessageTasksByKey, queuePollIntervalMs);
|
|
38032
38257
|
}
|
|
38033
38258
|
catch (error) {
|
|
38034
38259
|
await handleAgentWatchError({
|
|
@@ -38037,9 +38262,167 @@
|
|
|
38037
38262
|
error,
|
|
38038
38263
|
});
|
|
38039
38264
|
await messageFailureTracker.recordFailure(error);
|
|
38040
|
-
await wait$3(
|
|
38265
|
+
await wait$3(queuePollIntervalMs);
|
|
38266
|
+
}
|
|
38267
|
+
}
|
|
38268
|
+
await waitForActiveMessageTasksToSettle(activeMessageTasksByKey);
|
|
38269
|
+
}
|
|
38270
|
+
/**
|
|
38271
|
+
* Starts one selected queued-message harness task and records it until it settles.
|
|
38272
|
+
*/
|
|
38273
|
+
function startActiveAgentMessageTask(options) {
|
|
38274
|
+
const { queuedWorkItem } = options;
|
|
38275
|
+
const projectPath = queuedWorkItem.projectSummary.project.projectPath;
|
|
38276
|
+
const messageKey = createAgentMessageTaskKey(projectPath, queuedWorkItem.queuedMessage);
|
|
38277
|
+
const promise = runActiveAgentMessageTask({
|
|
38278
|
+
rootPath: options.rootPath,
|
|
38279
|
+
options: options.options,
|
|
38280
|
+
queuedWorkItem,
|
|
38281
|
+
projectSummaries: options.projectSummaries,
|
|
38282
|
+
answeringProjectPaths: options.answeringProjectPaths,
|
|
38283
|
+
ignoredAgentCount: options.ignoredAgentCount,
|
|
38284
|
+
autoPullResult: options.autoPullResult,
|
|
38285
|
+
autoPullTimestampsByProjectPath: options.autoPullTimestampsByProjectPath,
|
|
38286
|
+
messageFailureTracker: options.messageFailureTracker,
|
|
38287
|
+
uiHandle: options.uiHandle,
|
|
38288
|
+
watchErrorLogDirectoryPath: options.watchErrorLogDirectoryPath,
|
|
38289
|
+
}).finally(() => {
|
|
38290
|
+
options.activeMessageTasksByKey.delete(messageKey);
|
|
38291
|
+
});
|
|
38292
|
+
options.activeMessageTasksByKey.set(messageKey, {
|
|
38293
|
+
projectPath,
|
|
38294
|
+
queuedMessage: queuedWorkItem.queuedMessage,
|
|
38295
|
+
promise,
|
|
38296
|
+
});
|
|
38297
|
+
}
|
|
38298
|
+
/**
|
|
38299
|
+
* Runs one queued-message tick and folds its result back into shared watcher state.
|
|
38300
|
+
*/
|
|
38301
|
+
async function runActiveAgentMessageTask(options) {
|
|
38302
|
+
const projectPath = options.queuedWorkItem.projectSummary.project.projectPath;
|
|
38303
|
+
try {
|
|
38304
|
+
const tickRunOptions = createAgentRunOptionsForQueuedProjectTick({
|
|
38305
|
+
runOptions: options.options,
|
|
38306
|
+
isProjectPulledInCurrentIteration: options.autoPullResult.pulledProjectPaths.has(projectPath),
|
|
38307
|
+
});
|
|
38308
|
+
const tickResult = await tickAgentMessages(tickRunOptions, {
|
|
38309
|
+
isQuietWhenIdle: true,
|
|
38310
|
+
projectPath,
|
|
38311
|
+
queuedMessage: options.queuedWorkItem.queuedMessage,
|
|
38312
|
+
uiHandle: options.uiHandle,
|
|
38313
|
+
uiPresentation: options.uiHandle
|
|
38314
|
+
? buildMultiAgentTickUiPresentation({
|
|
38315
|
+
rootPath: options.rootPath,
|
|
38316
|
+
projectSummaries: options.projectSummaries,
|
|
38317
|
+
answeringProjectPaths: options.answeringProjectPaths,
|
|
38318
|
+
ignoredAgentCount: options.ignoredAgentCount,
|
|
38319
|
+
})
|
|
38320
|
+
: undefined,
|
|
38321
|
+
});
|
|
38322
|
+
if (tickResult.autoPullTimestamp !== undefined) {
|
|
38323
|
+
options.autoPullTimestampsByProjectPath.set(projectPath, tickResult.autoPullTimestamp);
|
|
38324
|
+
}
|
|
38325
|
+
if (tickResult.isMessageProcessed) {
|
|
38326
|
+
options.messageFailureTracker.clearMessageFailure(projectPath, tickResult.queuedMessage);
|
|
38327
|
+
}
|
|
38328
|
+
}
|
|
38329
|
+
catch (error) {
|
|
38330
|
+
await handleAgentWatchError({
|
|
38331
|
+
commandDisplayName: 'ptbk agent-folder run-multiple',
|
|
38332
|
+
logDirectoryPath: options.watchErrorLogDirectoryPath,
|
|
38333
|
+
error,
|
|
38334
|
+
});
|
|
38335
|
+
await options.messageFailureTracker.recordFailure(error);
|
|
38336
|
+
}
|
|
38337
|
+
}
|
|
38338
|
+
/**
|
|
38339
|
+
* Selects the next queued messages that can be started without exceeding active harness capacity.
|
|
38340
|
+
*/
|
|
38341
|
+
function selectQueuedWorkItems(options) {
|
|
38342
|
+
const activeProjectPaths = new Set(Array.from(options.activeMessageTasksByKey.values()).map((activeMessageTask) => activeMessageTask.projectPath));
|
|
38343
|
+
const queuedProjectSummaries = options.projectSummaries.filter((projectSummary) => {
|
|
38344
|
+
if (projectSummary.queuedMessageCount === 0) {
|
|
38345
|
+
return false;
|
|
38346
|
+
}
|
|
38347
|
+
return options.isParallelMessageLimitConfigured || !activeProjectPaths.has(projectSummary.project.projectPath);
|
|
38348
|
+
});
|
|
38349
|
+
if (!options.isParallelMessageLimitConfigured) {
|
|
38350
|
+
return queuedProjectSummaries
|
|
38351
|
+
.map((projectSummary) => selectFirstInactiveQueuedWorkItem(projectSummary, options.activeMessageTasksByKey))
|
|
38352
|
+
.filter((workItem) => workItem !== null);
|
|
38353
|
+
}
|
|
38354
|
+
const workItems = [];
|
|
38355
|
+
for (let messageIndex = 0; workItems.length < options.availableParallelMessageSlots; messageIndex++) {
|
|
38356
|
+
let isAnyMessageAtIndex = false;
|
|
38357
|
+
for (const projectSummary of queuedProjectSummaries) {
|
|
38358
|
+
const queuedMessage = projectSummary.queuedMessages[messageIndex];
|
|
38359
|
+
if (!queuedMessage) {
|
|
38360
|
+
continue;
|
|
38361
|
+
}
|
|
38362
|
+
isAnyMessageAtIndex = true;
|
|
38363
|
+
if (options.activeMessageTasksByKey.has(createAgentMessageTaskKey(projectSummary.project.projectPath, queuedMessage))) {
|
|
38364
|
+
continue;
|
|
38365
|
+
}
|
|
38366
|
+
workItems.push({ projectSummary, queuedMessage });
|
|
38367
|
+
if (workItems.length >= options.availableParallelMessageSlots) {
|
|
38368
|
+
return workItems;
|
|
38369
|
+
}
|
|
38370
|
+
}
|
|
38371
|
+
if (!isAnyMessageAtIndex) {
|
|
38372
|
+
return workItems;
|
|
38041
38373
|
}
|
|
38042
38374
|
}
|
|
38375
|
+
return workItems;
|
|
38376
|
+
}
|
|
38377
|
+
/**
|
|
38378
|
+
* Selects the first inactive queued message from a project while preserving legacy one-message-per-project behavior.
|
|
38379
|
+
*/
|
|
38380
|
+
function selectFirstInactiveQueuedWorkItem(projectSummary, activeMessageTasksByKey) {
|
|
38381
|
+
const queuedMessage = projectSummary.queuedMessages.find((message) => !activeMessageTasksByKey.has(createAgentMessageTaskKey(projectSummary.project.projectPath, message)));
|
|
38382
|
+
return queuedMessage ? { projectSummary, queuedMessage } : null;
|
|
38383
|
+
}
|
|
38384
|
+
/**
|
|
38385
|
+
* Builds the set of project paths currently represented by active or newly scheduled harness tasks.
|
|
38386
|
+
*/
|
|
38387
|
+
function createAnsweringProjectPaths(activeMessageTasksByKey, queuedWorkItems) {
|
|
38388
|
+
return new Set([
|
|
38389
|
+
...Array.from(activeMessageTasksByKey.values()).map((activeMessageTask) => activeMessageTask.projectPath),
|
|
38390
|
+
...queuedWorkItems.map((queuedWorkItem) => queuedWorkItem.projectSummary.project.projectPath),
|
|
38391
|
+
]);
|
|
38392
|
+
}
|
|
38393
|
+
/**
|
|
38394
|
+
* Creates a stable scheduler key for one queued message file.
|
|
38395
|
+
*/
|
|
38396
|
+
function createAgentMessageTaskKey(projectPath, queuedMessage) {
|
|
38397
|
+
return `${projectPath}\0${queuedMessage.relativePath}`;
|
|
38398
|
+
}
|
|
38399
|
+
/**
|
|
38400
|
+
* Normalizes the maximum number of parallel queued-message tasks.
|
|
38401
|
+
*/
|
|
38402
|
+
function normalizeMaxParallelMessageCount(rawValue) {
|
|
38403
|
+
const parsedValue = Number(rawValue);
|
|
38404
|
+
if (!Number.isFinite(parsedValue) || parsedValue <= 0) {
|
|
38405
|
+
return Number.POSITIVE_INFINITY;
|
|
38406
|
+
}
|
|
38407
|
+
return Math.floor(parsedValue);
|
|
38408
|
+
}
|
|
38409
|
+
/**
|
|
38410
|
+
* Waits for either one active task to finish or the next queue polling interval.
|
|
38411
|
+
*/
|
|
38412
|
+
async function waitForNextSchedulerTurn(activeMessageTasksByKey, queuePollIntervalMs) {
|
|
38413
|
+
if (activeMessageTasksByKey.size === 0) {
|
|
38414
|
+
return;
|
|
38415
|
+
}
|
|
38416
|
+
await Promise.race([
|
|
38417
|
+
...Array.from(activeMessageTasksByKey.values()).map((activeMessageTask) => activeMessageTask.promise),
|
|
38418
|
+
wait$3(queuePollIntervalMs),
|
|
38419
|
+
]);
|
|
38420
|
+
}
|
|
38421
|
+
/**
|
|
38422
|
+
* Preserves previous shutdown behavior by letting active harness tasks finish before returning.
|
|
38423
|
+
*/
|
|
38424
|
+
async function waitForActiveMessageTasksToSettle(activeMessageTasksByKey) {
|
|
38425
|
+
await Promise.allSettled(Array.from(activeMessageTasksByKey.values()).map((activeMessageTask) => activeMessageTask.promise));
|
|
38043
38426
|
}
|
|
38044
38427
|
/**
|
|
38045
38428
|
* Creates the shared multi-agent rich UI when the terminal supports it.
|
|
@@ -38185,6 +38568,7 @@
|
|
|
38185
38568
|
project,
|
|
38186
38569
|
localAgentName: localAgentIdentity.localAgentName,
|
|
38187
38570
|
localAgentUrl: localAgentIdentity.localAgentUrl || formatProjectPath(rootPath, project.projectPath),
|
|
38571
|
+
queuedMessages: queueSnapshot.queuedMessages,
|
|
38188
38572
|
queuedMessageCount: queueSnapshot.queuedMessages.length,
|
|
38189
38573
|
finishedMessageCount: queueSnapshot.finishedMessageCount,
|
|
38190
38574
|
...(queuedMessagePreview ? { queuedMessagePreview } : {}),
|
|
@@ -38216,14 +38600,16 @@
|
|
|
38216
38600
|
/**
|
|
38217
38601
|
* Updates the shared UI while one or more child repositories are answering queued messages.
|
|
38218
38602
|
*/
|
|
38219
|
-
function updateMultipleAgentRunUiForAnswering(uiHandle, options, rootPath, projectSummaries, answeringProjectPaths, ignoredAgentCount) {
|
|
38220
|
-
|
|
38603
|
+
function updateMultipleAgentRunUiForAnswering(uiHandle, options, rootPath, projectSummaries, answeringProjectPaths, ignoredAgentCount, activeMessageCount) {
|
|
38604
|
+
if (!uiHandle) {
|
|
38605
|
+
return;
|
|
38606
|
+
}
|
|
38221
38607
|
setMultipleAgentRunUiConfig(uiHandle, options, projectSummaries.length, ignoredAgentCount);
|
|
38222
38608
|
uiHandle.state.updateProgress(createMultiAgentQueueProgressSnapshot(projectSummaries));
|
|
38223
38609
|
uiHandle.state.setCurrentPrompt('');
|
|
38224
38610
|
uiHandle.state.setCurrentScriptPaths(buildMultiAgentScriptPaths(projectSummaries, answeringProjectPaths));
|
|
38225
38611
|
uiHandle.state.setPhase('running');
|
|
38226
|
-
uiHandle.state.setStatusMessage(`Answering ${
|
|
38612
|
+
uiHandle.state.setStatusMessage(`Answering ${activeMessageCount} queued message${activeMessageCount === 1 ? '' : 's'}`);
|
|
38227
38613
|
uiHandle.state.setDetailLines(buildMultiAgentAnsweringDetailLines(rootPath, projectSummaries, answeringProjectPaths));
|
|
38228
38614
|
uiHandle.state.setAgentStatusLines(buildMultiAgentStatusLines(rootPath, projectSummaries, answeringProjectPaths));
|
|
38229
38615
|
uiHandle.state.setAgentStatusTableRows(buildMultiAgentStatusTableRows(projectSummaries, answeringProjectPaths));
|
|
@@ -38525,6 +38911,12 @@
|
|
|
38525
38911
|
* @private shared Agents Server constant
|
|
38526
38912
|
*/
|
|
38527
38913
|
const DEFAULT_LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS = 3;
|
|
38914
|
+
/**
|
|
38915
|
+
* Default maximum number of local runner harness instances allowed to answer queued messages at once.
|
|
38916
|
+
*
|
|
38917
|
+
* @private shared Agents Server constant
|
|
38918
|
+
*/
|
|
38919
|
+
const DEFAULT_LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES = 3;
|
|
38528
38920
|
/**
|
|
38529
38921
|
* Stable keys used by the dedicated server-limits table.
|
|
38530
38922
|
*
|
|
@@ -38539,6 +38931,7 @@
|
|
|
38539
38931
|
SPAWN_AGENT_RATE_LIMIT_MAX: 'SPAWN_AGENT_RATE_LIMIT_MAX',
|
|
38540
38932
|
SPAWN_AGENT_RATE_LIMIT_WINDOW_MS: 'SPAWN_AGENT_RATE_LIMIT_WINDOW_MS',
|
|
38541
38933
|
LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS: 'LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS',
|
|
38934
|
+
LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES: 'LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES',
|
|
38542
38935
|
};
|
|
38543
38936
|
/**
|
|
38544
38937
|
* Shared metadata for all server limits exposed in the admin UI and runtime loaders.
|
|
@@ -38634,6 +39027,17 @@
|
|
|
38634
39027
|
step: 1,
|
|
38635
39028
|
legacyMetadataKeys: [],
|
|
38636
39029
|
},
|
|
39030
|
+
{
|
|
39031
|
+
key: SERVER_LIMIT_KEYS.LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES,
|
|
39032
|
+
category: 'Local agent runner',
|
|
39033
|
+
title: 'Max parallel harness instances',
|
|
39034
|
+
description: 'Caps how many queued chat messages the local coding-agent harness may answer at the same time.',
|
|
39035
|
+
unit: 'count',
|
|
39036
|
+
defaultValue: DEFAULT_LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES,
|
|
39037
|
+
minimumValue: 1,
|
|
39038
|
+
step: 1,
|
|
39039
|
+
legacyMetadataKeys: [],
|
|
39040
|
+
},
|
|
38637
39041
|
];
|
|
38638
39042
|
/**
|
|
38639
39043
|
* Fast lookup map used by server-limit validators and UI helpers.
|
|
@@ -38995,6 +39399,7 @@
|
|
|
38995
39399
|
autoPull: false,
|
|
38996
39400
|
autoClone: false,
|
|
38997
39401
|
maxMessageProcessingFailures: localAgentRunnerLimits.maxFailedAttempts,
|
|
39402
|
+
maxParallelMessages: localAgentRunnerLimits.maxParallelMessages,
|
|
38998
39403
|
};
|
|
38999
39404
|
}
|
|
39000
39405
|
/**
|
|
@@ -39006,7 +39411,7 @@
|
|
|
39006
39411
|
while (options.state.isContinuing && Date.now() - startedAt < INTERNAL_SERVER_LIMITS_STARTUP_TIMEOUT_MS) {
|
|
39007
39412
|
try {
|
|
39008
39413
|
const limits = await fetchLocalAgentRunnerLimits(options);
|
|
39009
|
-
logRunnerEvent(options.logStreams.runner, `Local agent runner
|
|
39414
|
+
logRunnerEvent(options.logStreams.runner, `Local agent runner limits: ${limits.maxFailedAttempts} failed attempt(s), ${limits.maxParallelMessages} parallel message(s).`);
|
|
39010
39415
|
return limits;
|
|
39011
39416
|
}
|
|
39012
39417
|
catch (error) {
|
|
@@ -39017,6 +39422,7 @@
|
|
|
39017
39422
|
if (!options.state.isContinuing) {
|
|
39018
39423
|
return {
|
|
39019
39424
|
maxFailedAttempts: DEFAULT_LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS,
|
|
39425
|
+
maxParallelMessages: DEFAULT_LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES,
|
|
39020
39426
|
};
|
|
39021
39427
|
}
|
|
39022
39428
|
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
@@ -39043,6 +39449,7 @@
|
|
|
39043
39449
|
const payload = (await response.json());
|
|
39044
39450
|
return {
|
|
39045
39451
|
maxFailedAttempts: normalizeLocalAgentRunnerMaxFailedAttempts(payload.maxFailedAttempts),
|
|
39452
|
+
maxParallelMessages: normalizeLocalAgentRunnerMaxParallelMessages(payload.maxParallelMessages),
|
|
39046
39453
|
};
|
|
39047
39454
|
}
|
|
39048
39455
|
/**
|
|
@@ -39055,6 +39462,16 @@
|
|
|
39055
39462
|
}
|
|
39056
39463
|
return Math.floor(parsedValue);
|
|
39057
39464
|
}
|
|
39465
|
+
/**
|
|
39466
|
+
* Normalizes the local runner parallel message cap returned by the internal server route.
|
|
39467
|
+
*/
|
|
39468
|
+
function normalizeLocalAgentRunnerMaxParallelMessages(rawValue) {
|
|
39469
|
+
const parsedValue = Number(rawValue);
|
|
39470
|
+
if (!Number.isFinite(parsedValue) || parsedValue <= 0) {
|
|
39471
|
+
return DEFAULT_LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES;
|
|
39472
|
+
}
|
|
39473
|
+
return Math.floor(parsedValue);
|
|
39474
|
+
}
|
|
39058
39475
|
/**
|
|
39059
39476
|
* Starts periodic internal worker calls that queue and reconcile local message-folder jobs.
|
|
39060
39477
|
*/
|
|
@@ -40309,7 +40726,7 @@
|
|
|
40309
40726
|
*/
|
|
40310
40727
|
const DEFAULT_CODER_PACKAGE_JSON_SCRIPTS = {
|
|
40311
40728
|
'coder:generate-boilerplates': 'ptbk coder generate-boilerplates --template ./prompts/templates/common.md',
|
|
40312
|
-
'coder:run': 'ptbk coder run --harness openai-codex --model gpt-5.
|
|
40729
|
+
'coder:run': 'ptbk coder run --harness openai-codex --model gpt-5.5 --thinking-level xhigh --agent agents/developer.book --context AGENTS.md',
|
|
40313
40730
|
// 'coder:find-refactor-candidates': 'ptbk coder find-refactor-candidates',
|
|
40314
40731
|
'coder:verify': 'ptbk coder verify',
|
|
40315
40732
|
};
|
|
@@ -40789,6 +41206,7 @@
|
|
|
40789
41206
|
command.option('--preserve-logs', 'Keep generated temp prompt/log artifacts after successful rounds for debugging and analytics', false);
|
|
40790
41207
|
addPromptRunnerExecutionOptions(command);
|
|
40791
41208
|
command.option('--priority <minimum-priority>', 'Filter prompts by minimum priority level', parseIntOption$1, 0);
|
|
41209
|
+
command.option('--limit <run-count>', 'Stop after processing this many prompt runs', parsePositiveIntegerOption);
|
|
40792
41210
|
command.option('--wait-after-prompt <duration>', _spaceTrim.spaceTrim(`
|
|
40793
41211
|
Wait this long after each prompt has been implemented, verified and committed before starting the next prompt.
|
|
40794
41212
|
Accepts durations like 1h, 30m, 5s. Defaults to 0 (no wait).
|
|
@@ -40807,7 +41225,7 @@
|
|
|
40807
41225
|
command.option('--auto-migrate', 'Run testing-server database migrations automatically after each successfully processed prompt');
|
|
40808
41226
|
command.option('--allow-destructive-auto-migrate', 'Allow auto-migrate even when heuristic SQL safety check flags destructive pending migrations');
|
|
40809
41227
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
40810
|
-
const { dryRun, agent, context, test, preserveLogs, priority, waitAfterPrompt: waitAfterPromptValue, waitBetweenPrompts: waitBetweenPromptsValue, waitAfterError: waitAfterErrorValue, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
41228
|
+
const { dryRun, agent, context, test, preserveLogs, priority, limit, waitAfterPrompt: waitAfterPromptValue, waitBetweenPrompts: waitBetweenPromptsValue, waitAfterError: waitAfterErrorValue, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
40811
41229
|
const testCommand = normalizeCommandOptionValue$1(test);
|
|
40812
41230
|
const runnerOptions = normalizePromptRunnerCliOptions(cliOptions, {
|
|
40813
41231
|
isAgentRequired: !dryRun,
|
|
@@ -40840,6 +41258,7 @@
|
|
|
40840
41258
|
noUi: runnerOptions.noUi,
|
|
40841
41259
|
thinkingLevel: runnerOptions.thinkingLevel,
|
|
40842
41260
|
priority,
|
|
41261
|
+
limit,
|
|
40843
41262
|
normalizeLineEndings: runnerOptions.normalizeLineEndings,
|
|
40844
41263
|
allowCredits: runnerOptions.allowCredits,
|
|
40845
41264
|
autoMigrate,
|
|
@@ -40874,6 +41293,22 @@
|
|
|
40874
41293
|
}
|
|
40875
41294
|
return parsed;
|
|
40876
41295
|
}
|
|
41296
|
+
/**
|
|
41297
|
+
* Parses a positive integer option value.
|
|
41298
|
+
*
|
|
41299
|
+
* @private internal utility of `coder run` command
|
|
41300
|
+
*/
|
|
41301
|
+
function parsePositiveIntegerOption(value) {
|
|
41302
|
+
const parsed = Number(value);
|
|
41303
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
41304
|
+
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
41305
|
+
Invalid value for \`--limit\`: \`${value}\`.
|
|
41306
|
+
|
|
41307
|
+
Use a positive integer.
|
|
41308
|
+
`));
|
|
41309
|
+
}
|
|
41310
|
+
return parsed;
|
|
41311
|
+
}
|
|
40877
41312
|
/**
|
|
40878
41313
|
* Joins one Commander option that may be parsed either as a single string or a variadic token array.
|
|
40879
41314
|
*
|
|
@@ -70289,7 +70724,7 @@
|
|
|
70289
70724
|
/**
|
|
70290
70725
|
* CLI usage text for this script.
|
|
70291
70726
|
*/
|
|
70292
|
-
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]';
|
|
70727
|
+
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]';
|
|
70293
70728
|
/**
|
|
70294
70729
|
* Top-level flags supported by this command.
|
|
70295
70730
|
*/
|
|
@@ -70303,6 +70738,7 @@
|
|
|
70303
70738
|
'--no-ui',
|
|
70304
70739
|
'--thinking-level',
|
|
70305
70740
|
'--priority',
|
|
70741
|
+
'--limit',
|
|
70306
70742
|
'--allow-credits',
|
|
70307
70743
|
'--auto-migrate',
|
|
70308
70744
|
'--allow-destructive-auto-migrate',
|
|
@@ -70339,6 +70775,8 @@
|
|
|
70339
70775
|
const thinkingLevelValue = readOptionValue(args, '--thinking-level');
|
|
70340
70776
|
const hasPriorityFlag = args.includes('--priority');
|
|
70341
70777
|
const priority = parsePriority(readOptionValue(args, '--priority'), hasPriorityFlag);
|
|
70778
|
+
const hasLimitFlag = args.includes('--limit');
|
|
70779
|
+
const limit = parseLimit(readOptionValue(args, '--limit'), hasLimitFlag);
|
|
70342
70780
|
const noCommit = args.includes('--no-commit');
|
|
70343
70781
|
const ignoreGitChanges = args.includes('--ignore-git-changes');
|
|
70344
70782
|
const normalizeLineEndings = !args.includes('--no-normalize-line-endings');
|
|
@@ -70393,6 +70831,7 @@
|
|
|
70393
70831
|
testCommand,
|
|
70394
70832
|
thinkingLevel,
|
|
70395
70833
|
priority,
|
|
70834
|
+
limit,
|
|
70396
70835
|
};
|
|
70397
70836
|
}
|
|
70398
70837
|
/**
|
|
@@ -70456,6 +70895,22 @@
|
|
|
70456
70895
|
}
|
|
70457
70896
|
return priority;
|
|
70458
70897
|
}
|
|
70898
|
+
/**
|
|
70899
|
+
* Parses and validates the optional successful prompt-run limit.
|
|
70900
|
+
*/
|
|
70901
|
+
function parseLimit(limitValue, hasLimitFlag) {
|
|
70902
|
+
if (limitValue === undefined) {
|
|
70903
|
+
if (hasLimitFlag) {
|
|
70904
|
+
exitWithUsageError('Missing value for --limit. Use a positive integer.');
|
|
70905
|
+
}
|
|
70906
|
+
return undefined;
|
|
70907
|
+
}
|
|
70908
|
+
const limit = Number(limitValue);
|
|
70909
|
+
if (!Number.isInteger(limit) || limit <= 0) {
|
|
70910
|
+
exitWithUsageError(`Invalid value for --limit: "${limitValue}". Use a positive integer.`);
|
|
70911
|
+
}
|
|
70912
|
+
return limit;
|
|
70913
|
+
}
|
|
70459
70914
|
/**
|
|
70460
70915
|
* Prints an argument error with usage and exits the process.
|
|
70461
70916
|
*/
|
|
@@ -72565,11 +73020,12 @@
|
|
|
72565
73020
|
// Prepend agent system message before the task so the harness sees agent instructions first
|
|
72566
73021
|
const promptWithAgent = resolvedAgentSystemMessage
|
|
72567
73022
|
? _spaceTrim.spaceTrim((block) => `
|
|
72568
|
-
|
|
72569
|
-
|
|
73023
|
+
|
|
72570
73024
|
## Your Task
|
|
72571
73025
|
|
|
72572
73026
|
${block(taskPrompt)}
|
|
73027
|
+
|
|
73028
|
+
${block(resolvedAgentSystemMessage.trim())}
|
|
72573
73029
|
`)
|
|
72574
73030
|
: taskPrompt;
|
|
72575
73031
|
const codexPrompt = appendCoderContext(promptWithAgent, resolvedCoderContext);
|
|
@@ -72892,6 +73348,7 @@
|
|
|
72892
73348
|
let hasWaitedForStart = false;
|
|
72893
73349
|
let previousRoundStartTime;
|
|
72894
73350
|
let previousRoundEndTime;
|
|
73351
|
+
let completedRunCount = 0;
|
|
72895
73352
|
while (just(true)) {
|
|
72896
73353
|
if (options.autoPull && !options.dryRun) {
|
|
72897
73354
|
await waitForRequestedPause({
|
|
@@ -72977,6 +73434,15 @@
|
|
|
72977
73434
|
});
|
|
72978
73435
|
previousRoundStartTime = currentRoundStartTime;
|
|
72979
73436
|
previousRoundEndTime = Date.now();
|
|
73437
|
+
completedRunCount += 1;
|
|
73438
|
+
if (isRunLimitReached({ completedRunCount, limit: options.limit })) {
|
|
73439
|
+
finishWhenRunLimitIsReached({
|
|
73440
|
+
completedRunCount,
|
|
73441
|
+
isRichUiEnabled,
|
|
73442
|
+
uiHandle,
|
|
73443
|
+
});
|
|
73444
|
+
return;
|
|
73445
|
+
}
|
|
72980
73446
|
}
|
|
72981
73447
|
}
|
|
72982
73448
|
finally {
|
|
@@ -73006,6 +73472,13 @@
|
|
|
73006
73472
|
Auto-pull keeps the repository up to date between prompt rounds, which requires each successful round to end with a clean committed working tree.
|
|
73007
73473
|
`));
|
|
73008
73474
|
}
|
|
73475
|
+
if (options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit <= 0)) {
|
|
73476
|
+
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
73477
|
+
Flag \`--limit\` expects a positive integer.
|
|
73478
|
+
|
|
73479
|
+
Received: \`${options.limit}\`
|
|
73480
|
+
`));
|
|
73481
|
+
}
|
|
73009
73482
|
}
|
|
73010
73483
|
/**
|
|
73011
73484
|
* Pulls the latest repository state before loading prompts when the feature is enabled.
|
|
@@ -73152,6 +73625,21 @@
|
|
|
73152
73625
|
}
|
|
73153
73626
|
return true;
|
|
73154
73627
|
}
|
|
73628
|
+
/**
|
|
73629
|
+
* Checks whether the configured successful prompt-run limit has been reached.
|
|
73630
|
+
*/
|
|
73631
|
+
function isRunLimitReached(options) {
|
|
73632
|
+
const { completedRunCount, limit } = options;
|
|
73633
|
+
return limit !== undefined && completedRunCount >= limit;
|
|
73634
|
+
}
|
|
73635
|
+
/**
|
|
73636
|
+
* Updates UI and console output when a user-configured run limit stops the loop.
|
|
73637
|
+
*/
|
|
73638
|
+
function finishWhenRunLimitIsReached(options) {
|
|
73639
|
+
const { completedRunCount, isRichUiEnabled, uiHandle } = options;
|
|
73640
|
+
const runCountLabel = completedRunCount === 1 ? '1 prompt run' : `${completedRunCount} prompt runs`;
|
|
73641
|
+
announceRunCompletion(`Run limit reached after ${runCountLabel}.`, colors__default["default"].green, isRichUiEnabled, uiHandle);
|
|
73642
|
+
}
|
|
73155
73643
|
/**
|
|
73156
73644
|
* Updates the UI status message while waiting for new prompts in keepAlive server mode.
|
|
73157
73645
|
*/
|