@promptbook/node 0.114.0-12 → 0.114.0-14

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.
Files changed (35) hide show
  1. package/esm/index.es.js +154 -50
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/scripts/run-agent-messages/messages/buildAgentGoalChatPromptSection.d.ts +22 -4
  4. package/esm/scripts/run-agent-messages/messages/buildAgentMessagePrompt.d.ts +3 -3
  5. package/esm/src/book-3.0/AgentMessageRunReport.d.ts +28 -0
  6. package/esm/src/book-3.0/AgentPlannedMessagesSidecar.d.ts +94 -0
  7. package/esm/src/book-3.0/AgentPlannedMessagesSidecar.test.d.ts +1 -0
  8. package/esm/src/book-3.0/createAgentMessageSidecarBaseName.d.ts +13 -0
  9. package/esm/src/book-components/Chat/utils/agentProjectToolCall.d.ts +46 -0
  10. package/esm/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +24 -0
  11. package/esm/src/cli/cli-commands/coder/waitOptions.d.ts +12 -0
  12. package/esm/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.d.ts +59 -0
  13. package/esm/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.d.ts +19 -0
  14. package/esm/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.test.d.ts +1 -0
  15. package/esm/src/version.d.ts +1 -1
  16. package/package.json +2 -2
  17. package/umd/index.umd.js +154 -50
  18. package/umd/index.umd.js.map +1 -1
  19. package/umd/scripts/run-agent-messages/messages/buildAgentGoalChatPromptSection.d.ts +22 -4
  20. package/umd/scripts/run-agent-messages/messages/buildAgentMessagePrompt.d.ts +3 -3
  21. package/umd/src/book-3.0/AgentMessageRunReport.d.ts +28 -0
  22. package/umd/src/book-3.0/AgentPlannedMessagesSidecar.d.ts +94 -0
  23. package/umd/src/book-3.0/AgentPlannedMessagesSidecar.test.d.ts +1 -0
  24. package/umd/src/book-3.0/createAgentMessageSidecarBaseName.d.ts +13 -0
  25. package/umd/src/book-components/Chat/utils/agentProjectToolCall.d.ts +46 -0
  26. package/umd/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +24 -0
  27. package/umd/src/cli/cli-commands/coder/waitOptions.d.ts +12 -0
  28. package/umd/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.d.ts +59 -0
  29. package/umd/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.d.ts +19 -0
  30. package/umd/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.test.d.ts +1 -0
  31. package/umd/src/version.d.ts +1 -1
  32. package/esm/apps/agents-server/src/utils/agentGoalChat/agentGoalChatConstants.d.ts +0 -12
  33. package/esm/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeConstants.d.ts +0 -40
  34. package/umd/apps/agents-server/src/utils/agentGoalChat/agentGoalChatConstants.d.ts +0 -12
  35. package/umd/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeConstants.d.ts +0 -40
package/esm/index.es.js CHANGED
@@ -29,7 +29,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
29
29
  * @generated
30
30
  * @see https://github.com/webgptorg/promptbook
31
31
  */
32
- const PROMPTBOOK_ENGINE_VERSION = '0.114.0-12';
32
+ const PROMPTBOOK_ENGINE_VERSION = '0.114.0-14';
33
33
  /**
34
34
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
35
35
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -5220,7 +5220,7 @@ function buildAgentProjectsPromptSection(options = {}) {
5220
5220
  - You have 100% control over every project folder: create, read, modify, and delete files there, run scripts and commands inside it, and keep any persistent data you need between conversations.
5221
5221
  - When the user asks you to build something (for example a website) or to do longer-term work, create a new project folder \`${AGENT_PROJECTS_DIRECTORY_PATH}/<project-name>/\` (use a short kebab-case name) and do the work inside it. Modify an existing project when the user refers to work you already did.
5222
5222
  - A project can be a git repository — you can run \`git init\` inside a project folder and commit your work there.
5223
- - Do not touch anything outside the \`${AGENT_PROJECTS_DIRECTORY_PATH}/\` directory except the queued message file you are answering.
5223
+ - Do not touch anything outside the \`${AGENT_PROJECTS_DIRECTORY_PATH}/\` directory beyond the file changes allowed at the top of this prompt.
5224
5224
 
5225
5225
  ${block(buildProjectReferenceInstructions(projectsUrlPath))}
5226
5226
  ${block(buildProjectRuntimeInstructions(options.projectRuntimeApi))}
@@ -5276,63 +5276,148 @@ function buildProjectRuntimeInstructions(projectRuntimeApi) {
5276
5276
  }
5277
5277
 
5278
5278
  /**
5279
- * Host used for local project runtimes.
5279
+ * Milliseconds in one second.
5280
+ *
5281
+ * @private internal timeout-chat constant
5280
5282
  */
5283
+ const SECOND_IN_MILLISECONDS = 1000;
5281
5284
  /**
5282
- * Header used by internal local-runner routes.
5285
+ * Seconds in one minute.
5286
+ *
5287
+ * @private internal timeout-chat constant
5283
5288
  */
5284
- const USER_CHAT_WORKER_TOKEN_HEADER = 'x-user-chat-worker-token';
5285
-
5289
+ const MINUTE_IN_SECONDS = 60;
5290
+ /**
5291
+ * Seconds in one hour.
5292
+ *
5293
+ * @private internal timeout-chat constant
5294
+ */
5295
+ const HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS;
5296
+ /**
5297
+ * Seconds in one day.
5298
+ *
5299
+ * @private internal timeout-chat constant
5300
+ */
5301
+ const HOURS_IN_DAY = 24;
5286
5302
  /**
5287
- * Title stored on every agent goal chat.
5303
+ * Seconds in one day.
5304
+ *
5305
+ * @private internal timeout-chat constant
5288
5306
  */
5307
+ const DAY_IN_SECONDS = HOURS_IN_DAY * HOUR_IN_SECONDS;
5289
5308
  /**
5290
- * Internal endpoint used by managed coding agents to plan goal-chat messages.
5309
+ * Converts timeout duration into natural language sentence fragments.
5310
+ *
5311
+ * Shared by every timeout surface: the chat chips, the goal-chat planned messages of the Agents
5312
+ * Server, and the planned-message prompt section of the agent-folder runner.
5313
+ *
5314
+ * @param milliseconds - Duration or repeat interval in milliseconds.
5315
+ * @returns Label such as `5 minutes` or `1 hour 30 minutes`.
5316
+ *
5317
+ * @private internal utility of `<Chat/>` and the Agents Server planned messages
5291
5318
  */
5292
- const AGENT_GOAL_CHAT_PLANNED_MESSAGES_INTERNAL_API_PATH = '/api/internal/agent-goal-chat-planned-messages';
5319
+ function formatTimeoutDurationHuman(milliseconds) {
5320
+ const normalizedMilliseconds = Math.max(0, Math.floor(milliseconds));
5321
+ const totalSeconds = Math.max(1, Math.floor(normalizedMilliseconds / SECOND_IN_MILLISECONDS));
5322
+ if (totalSeconds < MINUTE_IN_SECONDS) {
5323
+ return formatTimeoutUnit(totalSeconds, 'second');
5324
+ }
5325
+ if (totalSeconds < HOUR_IN_SECONDS) {
5326
+ const roundedMinutes = Math.max(1, Math.round(totalSeconds / MINUTE_IN_SECONDS));
5327
+ return formatTimeoutUnit(roundedMinutes, 'minute');
5328
+ }
5329
+ if (totalSeconds < DAY_IN_SECONDS) {
5330
+ const hours = Math.floor(totalSeconds / HOUR_IN_SECONDS);
5331
+ const minutes = Math.floor((totalSeconds % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS);
5332
+ if (minutes === 0) {
5333
+ return formatTimeoutUnit(hours, 'hour');
5334
+ }
5335
+ return `${formatTimeoutUnit(hours, 'hour')} ${formatTimeoutUnit(minutes, 'minute')}`;
5336
+ }
5337
+ const days = Math.floor(totalSeconds / DAY_IN_SECONDS);
5338
+ const hours = Math.floor((totalSeconds % DAY_IN_SECONDS) / HOUR_IN_SECONDS);
5339
+ if (hours === 0) {
5340
+ return formatTimeoutUnit(days, 'day');
5341
+ }
5342
+ return `${formatTimeoutUnit(days, 'day')} ${formatTimeoutUnit(hours, 'hour')}`;
5343
+ }
5344
+ /**
5345
+ * Formats one pluralized timeout unit.
5346
+ *
5347
+ * @private internal timeout-chat helper
5348
+ */
5349
+ function formatTimeoutUnit(value, unit) {
5350
+ return `${value} ${unit}${value === 1 ? '' : 's'}`;
5351
+ }
5352
+ // Note: [💞] Ignore a discrepancy between file name and entity name
5293
5353
 
5294
5354
  /**
5295
5355
  * Builds the planned-message instructions available to an Agents Server-managed coding agent.
5296
5356
  *
5297
- * Planned messages always target the agent's singleton goal chat, regardless of the chat in which
5298
- * the command is invoked.
5357
+ * Planned messages always target the agent's singleton goal chat, regardless of the chat in which the
5358
+ * wake-up is planned, and they repeat like `setInterval` until they are cancelled. The sidecar file is
5359
+ * the only channel that changes them, so an answer that merely claims a follow-up was planned changes
5360
+ * nothing — and an answer that changes nothing keeps the current plan running.
5361
+ *
5362
+ * @param sidecar - Sidecar prepared by the Agents Server for the answered message.
5363
+ * @returns Prompt section, or an empty string outside Agents Server-managed runs.
5299
5364
  */
5300
- function buildAgentGoalChatPromptSection(runtimeApi) {
5301
- if (!runtimeApi) {
5365
+ function buildAgentGoalChatPromptSection(sidecar) {
5366
+ if (!sidecar) {
5302
5367
  return '';
5303
5368
  }
5304
- return spaceTrim$1(`
5305
- ## Planned goal-chat messages
5369
+ return spaceTrim$1((block) => `
5370
+ ## Planned goal-chat messages
5306
5371
 
5307
- You can plan a future message that wakes you in your singleton goal chat. These commands are available during every Agents Server-managed chat invocation, not only while answering inside the goal chat.
5372
+ You can plan a message that repeatedly wakes you in your singleton goal chat. A planned message works like \`setInterval\`, not like \`setTimeout\`: once planned, it keeps waking you at its interval until you cancel it. This works during every Agents Server-managed chat invocation, not only while answering inside the goal chat.
5308
5373
 
5309
- - Use \`list_timeouts\` before planning follow-up work so you do not create duplicates.
5310
- - Use \`set_timeout\` when useful work should resume later. The delay is a positive number of milliseconds and the message should say exactly what your future invocation needs to do.
5311
- - Use \`cancel_timeout\` with the returned \`timeoutId\` when a planned message is no longer useful.
5312
- - A fired message appears in the goal chat and invokes you there. If more future work remains, plan the next useful message during that invocation.
5374
+ ${block(buildCurrentPlannedMessagesLines(sidecar.currentPlannedMessages))}
5313
5375
 
5314
- Run the corresponding authenticated command:
5376
+ Editing \`${sidecar.relativeSidecarPath}\` is the **only** way to change what wakes you. Writing in your answer that you scheduled something does not schedule anything.
5315
5377
 
5316
- \`\`\`bash
5317
- # list_timeouts
5318
- curl -sS -X POST "$${runtimeApi.serverUrlEnvironmentVariableName}${AGENT_GOAL_CHAT_PLANNED_MESSAGES_INTERNAL_API_PATH}" \\
5319
- -H "Content-Type: application/json" \\
5320
- -H "${USER_CHAT_WORKER_TOKEN_HEADER}: $${runtimeApi.tokenEnvironmentVariableName}" \\
5321
- -d '{"action":"list","agentPermanentId":"${runtimeApi.agentPermanentId}"}'
5322
-
5323
- # set_timeout
5324
- curl -sS -X POST "$${runtimeApi.serverUrlEnvironmentVariableName}${AGENT_GOAL_CHAT_PLANNED_MESSAGES_INTERNAL_API_PATH}" \\
5325
- -H "Content-Type: application/json" \\
5326
- -H "${USER_CHAT_WORKER_TOKEN_HEADER}: $${runtimeApi.tokenEnvironmentVariableName}" \\
5327
- -d '{"action":"set","agentPermanentId":"${runtimeApi.agentPermanentId}","milliseconds":3600000,"message":"Continue the current goal and decide the next concrete action."}'
5378
+ - **Keeping your planned messages as they are is the default.** When the list above already matches your goal, leave \`commands\` empty — every listed message keeps repeating on its own, and re-planning it would only duplicate it.
5379
+ - When your goal needs a repeating wake-up that is not listed above, append \`{"action":"set","milliseconds":<repeat interval>,"message":"<what each future invocation must do>"}\` to the \`commands\` array of that file.
5380
+ - When a listed message no longer matches your goal (for example your goal now says every 10 minutes while the message repeats every 5 minutes), append \`{"action":"cancel","timeoutId":"<timeout id>"}\` and one \`set\` command with the interval your goal really requires.
5381
+ - When your goal no longer needs a listed message at all, cancel it without planning a replacement.
5382
+ - Never edit \`version\`, \`agentPermanentId\`, or \`currentPlannedMessages\`.
5383
+ - The Agents Server applies every command once your answer is finished, and each repetition appears in the goal chat and invokes you there.
5384
+ - Only mention a planned follow-up in your answer when it is really planned: either you appended the matching \`set\` command, or you kept one of the messages listed above.
5385
+ `);
5386
+ }
5387
+ /**
5388
+ * Renders the already planned messages so the agent can compare them with its goal.
5389
+ *
5390
+ * @param currentPlannedMessages - Planned messages prepared by the Agents Server.
5391
+ * @returns Markdown list, or a sentence stating that nothing is planned yet.
5392
+ *
5393
+ * @private function of `buildAgentGoalChatPromptSection`
5394
+ */
5395
+ function buildCurrentPlannedMessagesLines(currentPlannedMessages) {
5396
+ if (currentPlannedMessages.length === 0) {
5397
+ return 'You currently have no planned messages waiting.';
5398
+ }
5399
+ const plannedMessageLines = currentPlannedMessages.map(createCurrentPlannedMessageLine);
5400
+ return spaceTrim$1((block) => `
5401
+ These planned messages are already waiting for you, so keep them unless they stopped matching your goal:
5328
5402
 
5329
- # cancel_timeout
5330
- curl -sS -X POST "$${runtimeApi.serverUrlEnvironmentVariableName}${AGENT_GOAL_CHAT_PLANNED_MESSAGES_INTERNAL_API_PATH}" \\
5331
- -H "Content-Type: application/json" \\
5332
- -H "${USER_CHAT_WORKER_TOKEN_HEADER}: $${runtimeApi.tokenEnvironmentVariableName}" \\
5333
- -d '{"action":"cancel","agentPermanentId":"${runtimeApi.agentPermanentId}","timeoutId":"<timeout-id>"}'
5334
- \`\`\`
5335
- `);
5403
+ ${block(plannedMessageLines.join('\n'))}
5404
+ `);
5405
+ }
5406
+ /**
5407
+ * Renders one already planned message with the schedule the agent has to compare with its goal.
5408
+ *
5409
+ * @param plannedMessage - One planned message prepared by the Agents Server.
5410
+ * @returns Markdown list item.
5411
+ *
5412
+ * @private function of `buildAgentGoalChatPromptSection`
5413
+ */
5414
+ function createCurrentPlannedMessageLine(plannedMessage) {
5415
+ var _a;
5416
+ const message = ((_a = plannedMessage.message) === null || _a === void 0 ? void 0 : _a.trim()) || 'Continue working towards the current goal.';
5417
+ const schedule = plannedMessage.intervalMs
5418
+ ? `repeats every ${formatTimeoutDurationHuman(plannedMessage.intervalMs)}`
5419
+ : `wakes you once at ${plannedMessage.dueAt}`;
5420
+ return `- \`${plannedMessage.timeoutId}\` ${schedule}: ${message}`;
5336
5421
  }
5337
5422
 
5338
5423
  // Note: [💞] This file defines the shared TEAM workspace convention rather than one standalone entity.
@@ -5363,8 +5448,8 @@ function buildAgentTeamPromptSection(workspace) {
5363
5448
  return '';
5364
5449
  }
5365
5450
  const teammateSections = workspace.manifest.teammates.map((teammate) => {
5366
- const sourcePath = toPromptPath(join(workspace.relativeWorkspacePath, AGENT_TEAMMATE_SOURCES_DIRECTORY_NAME, teammate.sourceFileName));
5367
- const transcriptPath = toPromptPath(join(workspace.relativeWorkspacePath, `${teammate.permanentId}--01.book`));
5451
+ const sourcePath = toPromptPath$1(join(workspace.relativeWorkspacePath, AGENT_TEAMMATE_SOURCES_DIRECTORY_NAME, teammate.sourceFileName));
5452
+ const transcriptPath = toPromptPath$1(join(workspace.relativeWorkspacePath, `${teammate.permanentId}--01.book`));
5368
5453
  const instructions = teammate.instructions.trim() || 'No additional TEAM instructions were provided.';
5369
5454
  return spaceTrim$1(`
5370
5455
  - ${teammate.agentName}
@@ -5382,7 +5467,7 @@ function buildAgentTeamPromptSection(workspace) {
5382
5467
 
5383
5468
  - The underlying coding harness is already executing this turn **exactly once**. Never start, queue, or invoke another coding harness, agent runner, or \`ptbk\` command to consult a teammate.
5384
5469
  - The primary agent remains responsible for the final user-facing \`MESSAGE @Agent\` answer.
5385
- - Teammate source files are read-only context. When a teammate consultation occurs, record the actual exchange in a new top-level \`.book\` file in \`${toPromptPath(workspace.relativeWorkspacePath)}\`.
5470
+ - Teammate source files are read-only context. When a teammate consultation occurs, record the actual exchange in a new top-level \`.book\` file in \`${toPromptPath$1(workspace.relativeWorkspacePath)}\`.
5386
5471
  - Name each transcript \`<teammate permanent id>--<sequence>.book\`, for example \`${workspace.manifest.teammates[0].permanentId}--01.book\`.
5387
5472
  - Every transcript must contain alternating \`MESSAGE @${workspace.manifest.primaryAgent.agentName}\` and \`MESSAGE @<teammate name>\` blocks. Do not create a transcript for a teammate that was not consulted.
5388
5473
  `);
@@ -5390,7 +5475,7 @@ function buildAgentTeamPromptSection(workspace) {
5390
5475
  /**
5391
5476
  * Converts a filesystem-relative path into the portable path notation used in prompts.
5392
5477
  */
5393
- function toPromptPath(path) {
5478
+ function toPromptPath$1(path) {
5394
5479
  return path.replace(/\\/gu, '/');
5395
5480
  }
5396
5481
 
@@ -5403,7 +5488,7 @@ function buildAgentMessagePrompt(messageRelativePath, agentSystemMessage, option
5403
5488
 
5404
5489
  - Read \`${messageRelativePath}\` and answer the most recent \`MESSAGE\` block. In a normal chat it is from \`@User\`; in your internal goal chat it can be from \`@Agent\`.
5405
5490
  - Only change the queued message file by appending one new \`MESSAGE @Agent\` block
5406
- ${block(buildAllowedFileChangesPromptLine(options.teamWorkspace))}
5491
+ ${block(buildAllowedFileChangesPromptLine(options))}
5407
5492
 
5408
5493
  ## Rules for the answering
5409
5494
 
@@ -5439,7 +5524,7 @@ function buildAgentMessagePrompt(messageRelativePath, agentSystemMessage, option
5439
5524
 
5440
5525
  - You can use \`message\` for message that will be sent immediately after clicking the button, or \`messageDraft\` for message that will be prefilled in the input field for editing before sending.
5441
5526
 
5442
- ${block(buildAgentGoalChatPromptSection(options.goalChatRuntimeApi))}
5527
+ ${block(buildAgentGoalChatPromptSection(options.plannedMessagesSidecar))}
5443
5528
 
5444
5529
  ${block(buildAgentProjectsPromptSection(options))}
5445
5530
 
@@ -5453,11 +5538,30 @@ function buildAgentMessagePrompt(messageRelativePath, agentSystemMessage, option
5453
5538
  /**
5454
5539
  * Explains the exact files that one coding harness may change for a user turn.
5455
5540
  */
5456
- function buildAllowedFileChangesPromptLine(teamWorkspace) {
5457
- if (!teamWorkspace) {
5458
- return `- Do not modify any other file in the repository, except files inside your own \`${AGENT_PROJECTS_DIRECTORY_PATH}/\` directory`;
5541
+ function buildAllowedFileChangesPromptLine(options) {
5542
+ const allowedFileChanges = [`files inside your own \`${AGENT_PROJECTS_DIRECTORY_PATH}/\` directory`];
5543
+ if (options.teamWorkspace) {
5544
+ allowedFileChanges.push(`new consultation transcripts inside \`${toPromptPath(options.teamWorkspace.relativeWorkspacePath)}\``);
5459
5545
  }
5460
- return `- Do not modify any other file in the repository, except files inside your own \`${AGENT_PROJECTS_DIRECTORY_PATH}/\` directory and new consultation transcripts inside \`${teamWorkspace.relativeWorkspacePath.replace(/\\/gu, '/')}\``;
5546
+ if (options.plannedMessagesSidecar) {
5547
+ allowedFileChanges.push(`the \`commands\` array of \`${toPromptPath(options.plannedMessagesSidecar.relativeSidecarPath)}\``);
5548
+ }
5549
+ return `- Do not modify any other file in the repository, except ${formatAllowedFileChanges(allowedFileChanges)}`;
5550
+ }
5551
+ /**
5552
+ * Joins the allowed file-change phrases into one readable enumeration.
5553
+ */
5554
+ function formatAllowedFileChanges(allowedFileChanges) {
5555
+ if (allowedFileChanges.length === 1) {
5556
+ return allowedFileChanges[0];
5557
+ }
5558
+ return `${allowedFileChanges.slice(0, -1).join(', ')} and ${allowedFileChanges[allowedFileChanges.length - 1]}`;
5559
+ }
5560
+ /**
5561
+ * Converts a filesystem-relative path into the portable path notation used in prompts.
5562
+ */
5563
+ function toPromptPath(path) {
5564
+ return path.replace(/\\/gu, '/');
5461
5565
  }
5462
5566
 
5463
5567
  /**