@promptbook/cli 0.114.0-13 → 0.114.0-18

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 (231) hide show
  1. package/apps/agents-server/next.config.ts +6 -0
  2. package/apps/agents-server/src/app/admin/_components/AdminFilterFields.tsx +84 -0
  3. package/apps/agents-server/src/app/admin/_components/AdminMetricCard.tsx +36 -0
  4. package/apps/agents-server/src/app/admin/_components/AdminTaskManagerTabs.tsx +97 -0
  5. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerClient.tsx +103 -0
  6. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerEditDialog.tsx +232 -0
  7. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerFiltersCard.tsx +195 -0
  8. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerRow.tsx +189 -0
  9. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerSummaryMetrics.tsx +60 -0
  10. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerTableCard.tsx +147 -0
  11. package/apps/agents-server/src/app/admin/planned-messages/page.tsx +17 -0
  12. package/apps/agents-server/src/app/admin/planned-messages/plannedMessageEditForm.ts +186 -0
  13. package/apps/agents-server/src/app/admin/planned-messages/plannedMessageManagerDialogs.ts +46 -0
  14. package/apps/agents-server/src/app/admin/planned-messages/plannedMessageManagerPresentation.tsx +188 -0
  15. package/apps/agents-server/src/app/admin/planned-messages/resolvePlannedMessageSortValue.ts +115 -0
  16. package/apps/agents-server/src/app/admin/planned-messages/usePlannedMessageManagerData.ts +116 -0
  17. package/apps/agents-server/src/app/admin/planned-messages/usePlannedMessageManagerState.ts +289 -0
  18. package/apps/agents-server/src/app/admin/task-manager/TaskManagerClient.tsx +7 -2
  19. package/apps/agents-server/src/app/admin/task-manager/TaskManagerFiltersCard.tsx +7 -73
  20. package/apps/agents-server/src/app/admin/task-manager/TaskManagerSummaryMetrics.tsx +5 -30
  21. package/apps/agents-server/src/app/admin/task-manager/[taskId]/TaskManagerTaskDetailClient.tsx +1 -1
  22. package/apps/agents-server/src/app/agents/[agentName]/api/book/reference-diagnostics/route.ts +30 -7
  23. package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +1 -0
  24. package/apps/agents-server/src/app/agents/[agentName]/api/book/test.http +3 -3
  25. package/apps/agents-server/src/app/agents/[agentName]/book/BookEditorMissingReferences.tsx +106 -12
  26. package/apps/agents-server/src/app/agents/[agentName]/book/BookEditorWrapper.tsx +3 -0
  27. package/apps/agents-server/src/app/agents/[agentName]/book/useBookEditorDiagnostics.ts +12 -0
  28. package/apps/agents-server/src/app/agents/[agentName]/book/useBookEditorWrapper.tsx +2 -0
  29. package/apps/agents-server/src/app/agents/[agentName]/chat/AgentGoalChatPlannedMessages.tsx +46 -3
  30. package/apps/agents-server/src/app/api/admin/default-agents/reinstate/route.ts +5 -1
  31. package/apps/agents-server/src/app/api/admin/planned-messages/[timeoutId]/route.ts +80 -0
  32. package/apps/agents-server/src/app/api/admin/planned-messages/route.ts +19 -0
  33. package/apps/agents-server/src/app/api/internal/agent-goal-chat-planned-messages/route.ts +30 -2
  34. package/apps/agents-server/src/components/DefaultAgents/ReinstateBundledAgentsButton.tsx +7 -0
  35. package/apps/agents-server/src/components/DefaultAgents/coreAgentsAdminRoute.ts +6 -0
  36. package/apps/agents-server/src/components/Header/buildHeaderSystemMenuItems.ts +7 -0
  37. package/apps/agents-server/src/components/Homepage/DefaultAgentsStatusNotice.tsx +1 -7
  38. package/apps/agents-server/src/database/migrations/2026-08-1800-user-chat-timeout-schedule.sql +11 -0
  39. package/apps/agents-server/src/instrumentation-node.ts +18 -0
  40. package/apps/agents-server/src/languages/ServerTranslationKeys.ts +4 -0
  41. package/apps/agents-server/src/languages/translations/czech.yaml +4 -0
  42. package/apps/agents-server/src/languages/translations/english.yaml +4 -0
  43. package/apps/agents-server/src/tools/agentGoalChatTimeoutToolFunctions.ts +62 -15
  44. package/apps/agents-server/src/tools/agentGoalChatTimeoutTools.ts +63 -9
  45. package/apps/agents-server/src/utils/adminEntityLookups/loadAgentNamesByPermanentId.ts +45 -0
  46. package/apps/agents-server/src/utils/adminEntityLookups/loadUsernamesByUserId.ts +36 -0
  47. package/apps/agents-server/src/utils/adminEntityLookups.ts +2 -0
  48. package/apps/agents-server/src/utils/agentGoalChat/agentGoalChatPlannedMessageActions.ts +299 -52
  49. package/apps/agents-server/src/utils/agentGoalChat/createAgentGoalChatNoteContent.ts +45 -17
  50. package/apps/agents-server/src/utils/agentGoalChat.ts +1 -0
  51. package/apps/agents-server/src/utils/agentProjects/agentProjectIdentity.ts +46 -0
  52. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeAutostartScheduler.ts +162 -0
  53. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeDesiredState.ts +252 -0
  54. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeDisplay.ts +6 -3
  55. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeDomains.ts +2 -44
  56. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimePaths.ts +25 -0
  57. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimePm2.ts +4 -3
  58. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeRegistry.ts +77 -24
  59. package/apps/agents-server/src/utils/agentProjects/agentProjectStateMutationQueue.ts +58 -0
  60. package/apps/agents-server/src/utils/agentProjects/listAllLocalAgentProjectIdentities.ts +48 -0
  61. package/apps/agents-server/src/utils/agentProjects/resolveAgentProjectRuntimeEnvironmentFlag.ts +23 -0
  62. package/apps/agents-server/src/utils/agentProjects/resolveAgentProjectRuntimeStatus.ts +73 -0
  63. package/apps/agents-server/src/utils/agentProjects/startDefaultAgentProjectRuntimes.ts +110 -0
  64. package/apps/agents-server/src/utils/agentReferenceResolver/MissingCoreAgentRecovery.ts +19 -0
  65. package/apps/agents-server/src/utils/agentReferenceResolver/bookScopedAgentReferences.ts +7 -0
  66. package/apps/agents-server/src/utils/agentReferenceResolver/createAgentInheritanceDiagnostics.ts +457 -0
  67. package/apps/agents-server/src/utils/agentReferenceResolver/createUnresolvedAgentReferenceDiagnostics.ts +27 -0
  68. package/apps/agents-server/src/utils/agentReferenceResolver/resolveCoreAgentAwareMissingReferences.ts +156 -0
  69. package/apps/agents-server/src/utils/chatMessageChips/createAnsweredMessageChipToolCalls.ts +15 -3
  70. package/apps/agents-server/src/utils/chatMessageChips/createPlannedMessageChipToolCalls.ts +8 -3
  71. package/apps/agents-server/src/utils/chatMessageChips/createTouchedExternalSourceChipToolCalls.ts +39 -0
  72. package/apps/agents-server/src/utils/chatMessageChips/createTouchedProjectChipResult.ts +45 -0
  73. package/apps/agents-server/src/utils/chatMessageChips/createTouchedProjectChipToolCalls.ts +58 -24
  74. package/apps/agents-server/src/utils/cronExpression/CronExpression.ts +63 -0
  75. package/apps/agents-server/src/utils/cronExpression/normalizeCronExpression.ts +34 -0
  76. package/apps/agents-server/src/utils/cronExpression/normalizeCronExpressionWhitespace.ts +11 -0
  77. package/apps/agents-server/src/utils/cronExpression/parseCronExpression.ts +41 -0
  78. package/apps/agents-server/src/utils/cronExpression/parseCronExpressionField.ts +140 -0
  79. package/apps/agents-server/src/utils/cronExpression/resolveNextCronRun.ts +100 -0
  80. package/apps/agents-server/src/utils/cronExpression/throwInvalidCronExpressionField.ts +20 -0
  81. package/apps/agents-server/src/utils/cronExpression.ts +10 -0
  82. package/apps/agents-server/src/utils/explicitFromCommitment.ts +130 -0
  83. package/apps/agents-server/src/utils/getAdminChatTasksResponse/getAdminChatTasks/loadAdminChatTaskFallbackData.ts +3 -77
  84. package/apps/agents-server/src/utils/localChatRunner/applyLocalAgentPlannedMessageCommands.ts +53 -4
  85. package/apps/agents-server/src/utils/localChatRunner/prepareLocalAgentPlannedMessagesSidecar.ts +15 -7
  86. package/apps/agents-server/src/utils/localChatRunner/processLocalUserChatJob.ts +8 -0
  87. package/apps/agents-server/src/utils/manGoOnboarding/manGoOnboardingAgentBooks.ts +5 -11
  88. package/apps/agents-server/src/utils/manGoOnboarding/manGoOnboardingAgentRuntime.ts +2 -2
  89. package/apps/agents-server/src/utils/managementApi/managementApiSchemas.ts +2 -2
  90. package/apps/agents-server/src/utils/plannedMessageManager/cancelManagedPlannedMessage.ts +35 -0
  91. package/apps/agents-server/src/utils/plannedMessageManager/collectPlannedMessageAgentOptions.ts +56 -0
  92. package/apps/agents-server/src/utils/plannedMessageManager/createPlannedMessageManagerCounters.ts +104 -0
  93. package/apps/agents-server/src/utils/plannedMessageManager/filterPlannedMessages.ts +191 -0
  94. package/apps/agents-server/src/utils/plannedMessageManager/getPlannedMessageManagerResponse.ts +55 -0
  95. package/apps/agents-server/src/utils/plannedMessageManager/isPlannedMessageStillPlanned.ts +18 -0
  96. package/apps/agents-server/src/utils/plannedMessageManager/loadPlannedMessageManagerRecord.ts +32 -0
  97. package/apps/agents-server/src/utils/plannedMessageManager/mapPlannedMessageManagerRecord.ts +73 -0
  98. package/apps/agents-server/src/utils/plannedMessageManager/parsePlannedMessageManagerUpdateRequest.ts +76 -0
  99. package/apps/agents-server/src/utils/plannedMessageManager/resolvePlannedMessageEndReason.ts +59 -0
  100. package/apps/agents-server/src/utils/plannedMessageManager/resolvePlannedMessageLifecycle.ts +99 -0
  101. package/apps/agents-server/src/utils/plannedMessageManager/resolvePlannedMessageRecurrenceKind.ts +40 -0
  102. package/apps/agents-server/src/utils/plannedMessageManager/updateManagedPlannedMessage.ts +121 -0
  103. package/apps/agents-server/src/utils/plannedMessagesAdmin.ts +200 -0
  104. package/apps/agents-server/src/utils/resolveInheritedAgentSource.ts +114 -95
  105. package/apps/agents-server/src/utils/userChatClient.ts +4 -0
  106. package/apps/agents-server/src/utils/userChatTimeout/UserChatTimeoutRecord.ts +37 -1
  107. package/apps/agents-server/src/utils/userChatTimeout/agentScopedTimeoutBulkActions.ts +11 -17
  108. package/apps/agents-server/src/utils/userChatTimeout/createTimeoutWakeUpMessage.ts +37 -13
  109. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/PlannedMessageSchedule.ts +52 -0
  110. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/hasPlannedMessageRecurrence.ts +13 -0
  111. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/isPlannedMessageScheduleFinished.ts +30 -0
  112. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/normalizePlannedMessageScheduleValues.ts +62 -0
  113. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/parsePlannedMessageSchedule.ts +202 -0
  114. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/resolvePlannedMessageDueAt.ts +121 -0
  115. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule.ts +12 -0
  116. package/apps/agents-server/src/utils/userChatTimeout/setAgentScopedUserChatTimeoutPausedState.ts +66 -0
  117. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/createUserChatTimeout.ts +76 -5
  118. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/listAllUserChatTimeouts.ts +37 -0
  119. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/mapUserChatTimeoutRow.ts +9 -0
  120. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/repeatFiredUserChatTimeout.ts +19 -9
  121. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/updateAgentScopedUserChatTimeout.ts +39 -6
  122. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore.ts +1 -0
  123. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutWorker.ts +110 -11
  124. package/apps/agents-server/src/utils/userChatTimeout.ts +16 -0
  125. package/apps/agents-server/src/utils/vpsSelfUpdate/vpsSelfUpdateCron.ts +23 -316
  126. package/apps/agents-server/tests/e2e/support/AgentManagementApi.ts +3 -3
  127. package/esm/index.es.js +951 -102
  128. package/esm/index.es.js.map +1 -1
  129. package/esm/scripts/run-agent-messages/git/commitAgentProjectChanges.d.ts +15 -0
  130. package/esm/scripts/run-agent-messages/git/commitAnsweredMessageProjectChanges.d.ts +24 -0
  131. package/esm/scripts/run-agent-messages/git/ensureAgentProjectGitRepository.d.ts +20 -0
  132. package/esm/scripts/run-agent-messages/git/readAgentProjectCommitChange.d.ts +11 -0
  133. package/esm/scripts/run-agent-messages/git/runAgentProjectGitCommand.d.ts +29 -0
  134. package/esm/scripts/run-agent-messages/messages/buildAgentGoalChatPromptSection.d.ts +3 -3
  135. package/esm/scripts/run-agent-messages/messages/listAgentProjectDirectoryNames.d.ts +7 -0
  136. package/esm/scripts/run-agent-messages/messages/resolveAnsweredMessageTouches.d.ts +29 -0
  137. package/esm/scripts/run-codex-prompts/ping/pingCoderHarnessPeriodically.d.ts +22 -0
  138. package/esm/src/book-3.0/AgentMessageRunReport.d.ts +18 -0
  139. package/esm/src/book-3.0/AgentPlannedMessagesSidecar.d.ts +38 -5
  140. package/esm/src/book-3.0/describeAgentPlannedMessageSchedule.d.ts +31 -0
  141. package/esm/src/book-components/BookEditor/createDeprecatedCommitmentDiagnostics.browser.d.ts +1 -9
  142. package/esm/src/book-components/BookEditor/createDuplicateFromCommitmentDiagnostics.d.ts +28 -0
  143. package/esm/src/book-components/BookEditor/createDuplicateFromCommitmentDiagnostics.test.d.ts +1 -0
  144. package/esm/src/book-components/Chat/Chat/renderAgentProjectDiff.d.ts +13 -0
  145. package/esm/src/book-components/Chat/Chat/renderAgentProjectToolCallDetails.d.ts +16 -0
  146. package/esm/src/book-components/Chat/utils/agentProjectToolCall.d.ts +39 -0
  147. package/esm/src/book-components/Chat/utils/agentProjectToolCall.test.d.ts +1 -0
  148. package/esm/src/book-components/Chat/utils/externalSourceToolCall.d.ts +38 -0
  149. package/esm/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +6 -0
  150. package/esm/src/cli/cli-commands/coder/waitOptions.d.ts +12 -0
  151. package/esm/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +15 -0
  152. package/esm/src/utils/agent-message-runtime/AgentMessageProjectChange.d.ts +76 -0
  153. package/esm/src/utils/agent-message-runtime/AgentMessageTouchedExternalSource.d.ts +45 -0
  154. package/esm/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.d.ts +3 -0
  155. package/esm/src/utils/agent-message-runtime/resolveAgentMessageTouchedExternalSources.d.ts +18 -0
  156. package/esm/src/utils/agent-message-runtime/resolveAgentMessageTouchedExternalSources.test.d.ts +1 -0
  157. package/esm/src/utils/random/$generateBookBoilerplate.test.d.ts +1 -0
  158. package/esm/src/version.d.ts +1 -1
  159. package/package.json +1 -1
  160. package/src/book-2.0/agent-source/string_book.ts +1 -1
  161. package/src/book-2.0/book-language-documentation/czechBookLanguageManualDictionary.ts +6 -1
  162. package/src/book-2.0/book-language-documentation/englishBookLanguageManualDictionary.ts +6 -1
  163. package/src/book-3.0/AgentMessageRunReport.ts +59 -0
  164. package/src/book-3.0/AgentPlannedMessagesSidecar.ts +64 -9
  165. package/src/book-3.0/describeAgentPlannedMessageSchedule.ts +94 -0
  166. package/src/book-components/BookEditor/BookEditorMonaco.tsx +2 -0
  167. package/src/book-components/BookEditor/createDeprecatedCommitmentDiagnostics.browser.ts +3 -11
  168. package/src/book-components/BookEditor/createDuplicateFromCommitmentDiagnostics.ts +71 -0
  169. package/src/book-components/Chat/Chat/Chat.module.css +165 -18
  170. package/src/book-components/Chat/Chat/ChatMessageMap.tsx +0 -1
  171. package/src/book-components/Chat/Chat/renderAgentProjectDiff.tsx +85 -0
  172. package/src/book-components/Chat/Chat/renderAgentProjectToolCallDetails.tsx +206 -0
  173. package/src/book-components/Chat/Chat/renderToolCallDetails.tsx +8 -0
  174. package/src/book-components/Chat/MarkdownContent/MarkdownContent.tsx +2 -3
  175. package/src/book-components/Chat/utils/agentProjectToolCall.ts +82 -5
  176. package/src/book-components/Chat/utils/externalSourceToolCall.ts +65 -0
  177. package/src/book-components/Chat/utils/getToolCallChipletInfo.ts +36 -0
  178. package/src/book-components/Chat/utils/renderMarkdown.ts +3 -10
  179. package/src/book-components/Chat/utils/timeoutToolCallPresentation.ts +12 -1
  180. package/src/cli/cli-commands/coder/ping.ts +35 -9
  181. package/src/cli/cli-commands/coder/waitOptions.ts +33 -0
  182. package/src/cli/cli-commands/common/harness/$applyHarnessInstallationStatus.ts +3 -1
  183. package/src/cli/cli-commands/common/harness/$checkHarnessInstallation.ts +3 -1
  184. package/src/cli/cli-commands/common/harnessUpdateCliOptions.ts +1 -4
  185. package/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.ts +47 -3
  186. package/src/commands/FORMAT/formatCommandParser.ts +4 -2
  187. package/src/commitments/FROM/FROM.ts +13 -0
  188. package/src/other/templates/getTemplatesPipelineCollection.ts +819 -751
  189. package/src/utils/agent-message-runtime/AgentMessageProjectChange.ts +183 -0
  190. package/src/utils/agent-message-runtime/AgentMessageTouchedExternalSource.ts +80 -0
  191. package/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.ts +3 -0
  192. package/src/utils/agent-message-runtime/resolveAgentMessageRuntimeActivity.ts +2 -4
  193. package/src/utils/agent-message-runtime/resolveAgentMessageTouchedExternalSources.ts +341 -0
  194. package/src/utils/random/$generateBookBoilerplate.ts +1 -1
  195. package/src/version.ts +2 -2
  196. package/src/versions.txt +5 -0
  197. package/umd/index.umd.js +950 -101
  198. package/umd/index.umd.js.map +1 -1
  199. package/umd/scripts/run-agent-messages/git/commitAgentProjectChanges.d.ts +15 -0
  200. package/umd/scripts/run-agent-messages/git/commitAnsweredMessageProjectChanges.d.ts +24 -0
  201. package/umd/scripts/run-agent-messages/git/ensureAgentProjectGitRepository.d.ts +20 -0
  202. package/umd/scripts/run-agent-messages/git/readAgentProjectCommitChange.d.ts +11 -0
  203. package/umd/scripts/run-agent-messages/git/runAgentProjectGitCommand.d.ts +29 -0
  204. package/umd/scripts/run-agent-messages/messages/buildAgentGoalChatPromptSection.d.ts +3 -3
  205. package/umd/scripts/run-agent-messages/messages/listAgentProjectDirectoryNames.d.ts +7 -0
  206. package/umd/scripts/run-agent-messages/messages/resolveAnsweredMessageTouches.d.ts +29 -0
  207. package/umd/scripts/run-codex-prompts/ping/pingCoderHarnessPeriodically.d.ts +22 -0
  208. package/umd/src/book-3.0/AgentMessageRunReport.d.ts +18 -0
  209. package/umd/src/book-3.0/AgentPlannedMessagesSidecar.d.ts +38 -5
  210. package/umd/src/book-3.0/describeAgentPlannedMessageSchedule.d.ts +31 -0
  211. package/umd/src/book-components/BookEditor/createDeprecatedCommitmentDiagnostics.browser.d.ts +1 -9
  212. package/umd/src/book-components/BookEditor/createDuplicateFromCommitmentDiagnostics.d.ts +28 -0
  213. package/umd/src/book-components/BookEditor/createDuplicateFromCommitmentDiagnostics.test.d.ts +1 -0
  214. package/umd/src/book-components/Chat/Chat/renderAgentProjectDiff.d.ts +13 -0
  215. package/umd/src/book-components/Chat/Chat/renderAgentProjectToolCallDetails.d.ts +16 -0
  216. package/umd/src/book-components/Chat/utils/agentProjectToolCall.d.ts +39 -0
  217. package/umd/src/book-components/Chat/utils/agentProjectToolCall.test.d.ts +1 -0
  218. package/umd/src/book-components/Chat/utils/externalSourceToolCall.d.ts +38 -0
  219. package/umd/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +6 -0
  220. package/umd/src/cli/cli-commands/coder/waitOptions.d.ts +12 -0
  221. package/umd/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +15 -0
  222. package/umd/src/utils/agent-message-runtime/AgentMessageProjectChange.d.ts +76 -0
  223. package/umd/src/utils/agent-message-runtime/AgentMessageTouchedExternalSource.d.ts +45 -0
  224. package/umd/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.d.ts +3 -0
  225. package/umd/src/utils/agent-message-runtime/resolveAgentMessageTouchedExternalSources.d.ts +18 -0
  226. package/umd/src/utils/agent-message-runtime/resolveAgentMessageTouchedExternalSources.test.d.ts +1 -0
  227. package/umd/src/utils/random/$generateBookBoilerplate.test.d.ts +1 -0
  228. package/umd/src/version.d.ts +1 -1
  229. package/apps/agents-server/src/app/admin/task-manager/TaskManagerScopeTabs.tsx +0 -74
  230. package/esm/scripts/run-agent-messages/messages/resolveTouchedAgentProjects.d.ts +0 -15
  231. package/umd/scripts/run-agent-messages/messages/resolveTouchedAgentProjects.d.ts +0 -15
@@ -1,11 +1,19 @@
1
1
  import { spaceTrim } from 'spacetrim';
2
2
  import { ParseError } from '../../../../../src/errors/ParseError';
3
- import type { UserChatTimeoutRecord, UserChatTimeoutStatus } from '../userChatTimeout';
3
+ import type {
4
+ PlannedMessageScheduleInput,
5
+ UpdateAgentScopedUserChatTimeoutPatch,
6
+ UserChatTimeoutRecord,
7
+ UserChatTimeoutStatus,
8
+ } from '../userChatTimeout';
4
9
  import {
5
10
  cancelScheduledUserChatTimeout,
6
11
  getAgentScopedUserChatTimeout,
7
12
  listAgentUserChatTimeouts,
13
+ parsePlannedMessageSchedule,
14
+ resolvePlannedMessageDueAt,
8
15
  scheduleThreadScopedUserChatTimeout,
16
+ updateScheduledUserChatTimeout,
9
17
  } from '../userChatTimeout';
10
18
  import { ensureAgentGoalChat } from './ensureAgentGoalChat';
11
19
 
@@ -24,14 +32,6 @@ const MAX_LISTED_PLANNED_MESSAGES_LIMIT = 100;
24
32
  */
25
33
  const ACTIVE_PLANNED_MESSAGE_STATUSES: ReadonlyArray<UserChatTimeoutStatus> = ['QUEUED', 'RUNNING'];
26
34
 
27
- /**
28
- * Shortest repeat interval one agent may plan for itself.
29
- *
30
- * Planned messages repeat like `setInterval`, so an interval below one minute would turn the goal
31
- * chat into an unattended self-invocation loop instead of a plan.
32
- */
33
- const MINIMUM_PLANNED_MESSAGE_INTERVAL_MS = 60_000;
34
-
35
35
  /**
36
36
  * Minimal goal-chat identity needed when scheduling a planned message.
37
37
  */
@@ -41,35 +41,76 @@ type AgentGoalChatPlannedMessageTarget = {
41
41
  };
42
42
 
43
43
  /**
44
- * Serializable summary of one planned goal-chat message.
44
+ * Serializable schedule of one planned goal-chat message.
45
+ *
46
+ * The field names match the planned-message sidecar snapshot, so one scheduling result, one listed
47
+ * message, and one sidecar entry all describe a schedule in exactly the same way.
45
48
  */
46
- export type AgentGoalChatPlannedMessageItem = {
47
- readonly timeoutId: string;
48
- readonly status: UserChatTimeoutStatus;
49
+ export type AgentGoalChatPlannedMessageScheduleFields = {
49
50
  readonly dueAt: string;
50
- readonly isPaused: boolean;
51
51
  readonly message: string | null;
52
52
 
53
53
  /**
54
- * Repeat interval in milliseconds, or `null` for a planned message that wakes the agent only once.
54
+ * Repeat interval in milliseconds, or `null` when the planned message does not repeat at a fixed
55
+ * interval.
55
56
  */
56
57
  readonly intervalMs: number | null;
58
+
59
+ /**
60
+ * Five-field cron expression, or `null` when the planned message does not follow a cron.
61
+ */
62
+ readonly cronExpression: string | null;
63
+
64
+ /**
65
+ * Moment before which the planned message never wakes the agent, or `null`.
66
+ */
67
+ readonly startsAt: string | null;
68
+
69
+ /**
70
+ * Moment after which the planned message never wakes the agent again, or `null`.
71
+ */
72
+ readonly endsAt: string | null;
73
+
74
+ /**
75
+ * Total number of wake-ups, or `null` when the planned message repeats until it is cancelled.
76
+ */
77
+ readonly maxRunCount: number | null;
78
+
79
+ /**
80
+ * Number of wake-ups that already happened.
81
+ */
82
+ readonly runCount: number;
83
+ };
84
+
85
+ /**
86
+ * Serializable summary of one planned goal-chat message.
87
+ */
88
+ export type AgentGoalChatPlannedMessageItem = AgentGoalChatPlannedMessageScheduleFields & {
89
+ readonly timeoutId: string;
90
+ readonly status: UserChatTimeoutStatus;
91
+ readonly isPaused: boolean;
57
92
  };
58
93
 
59
94
  /**
60
95
  * Result returned after scheduling one planned goal-chat message.
61
96
  */
62
- export type SetAgentGoalChatPlannedMessageResult = {
97
+ export type SetAgentGoalChatPlannedMessageResult = AgentGoalChatPlannedMessageScheduleFields & {
63
98
  readonly action: 'set';
64
99
  readonly status: 'set';
65
100
  readonly timeoutId: string;
66
- readonly dueAt: string;
67
- readonly message: string | null;
101
+ };
68
102
 
69
- /**
70
- * Repeat interval in milliseconds of the scheduled planned message.
71
- */
72
- readonly intervalMs: number | null;
103
+ /**
104
+ * Result returned after changing the schedule of one planned goal-chat message.
105
+ *
106
+ * The schedule fields are absent when there was no such planned message to change. A planned message
107
+ * which is firing right now reports `busy` together with the schedule it still has, because its
108
+ * schedule is being consumed by that very firing and is therefore left untouched.
109
+ */
110
+ export type UpdateAgentGoalChatPlannedMessageResult = Partial<AgentGoalChatPlannedMessageScheduleFields> & {
111
+ readonly action: 'update';
112
+ readonly status: 'updated' | 'busy' | 'not_found';
113
+ readonly timeoutId: string;
73
114
  };
74
115
 
75
116
  /**
@@ -92,26 +133,55 @@ export type CancelAgentGoalChatPlannedMessageResult = {
92
133
  readonly dueAt?: string;
93
134
  };
94
135
 
136
+ /**
137
+ * Schedule an agent may request for one planned message.
138
+ *
139
+ * Every field is untrusted, and leaving all of them out is only allowed when updating the message text
140
+ * of an existing planned message.
141
+ */
142
+ export type AgentGoalChatPlannedMessageScheduleRequest = {
143
+ readonly milliseconds?: unknown;
144
+ readonly cronExpression?: unknown;
145
+ readonly startsAt?: unknown;
146
+ readonly endsAt?: unknown;
147
+ readonly maxRunCount?: unknown;
148
+ };
149
+
95
150
  /**
96
151
  * Shared operations used by both model tools and the coding-agent runtime API.
97
152
  *
98
- * Planned messages behave like `setInterval`: `set` starts a repeating wake-up and only `cancel`
99
- * stops it, so an agent that is happy with its plan does not have to do anything.
153
+ * A planned message can repeat like `setInterval`, wake the agent a bounded number of times, run only
154
+ * inside a date window, or fire just once and it can be re-planned or cancelled at any time from any
155
+ * invocation of the agent.
100
156
  */
101
157
  export type AgentGoalChatPlannedMessageActions = {
102
158
  /**
103
- * Starts one repeating planned message, where `milliseconds` is its repeat interval.
159
+ * Plans one message, where the schedule says how and how long it repeats.
104
160
  */
105
- readonly set: (options: {
106
- readonly agentPermanentId: string;
107
- readonly milliseconds: unknown;
108
- readonly message: unknown;
109
- }) => Promise<SetAgentGoalChatPlannedMessageResult>;
161
+ readonly set: (
162
+ options: AgentGoalChatPlannedMessageScheduleRequest & {
163
+ readonly agentPermanentId: string;
164
+ readonly message: unknown;
165
+ },
166
+ ) => Promise<SetAgentGoalChatPlannedMessageResult>;
167
+
168
+ /**
169
+ * Changes the schedule or the text of one already planned message, keeping its identity.
170
+ */
171
+ readonly update: (
172
+ options: AgentGoalChatPlannedMessageScheduleRequest & {
173
+ readonly agentPermanentId: string;
174
+ readonly timeoutId: unknown;
175
+ readonly message?: unknown;
176
+ },
177
+ ) => Promise<UpdateAgentGoalChatPlannedMessageResult>;
178
+
110
179
  readonly list: (options: {
111
180
  readonly agentPermanentId: string;
112
181
  readonly isIncludingFinished?: unknown;
113
182
  readonly limit?: unknown;
114
183
  }) => Promise<ListAgentGoalChatPlannedMessagesResult>;
184
+
115
185
  readonly cancel: (options: {
116
186
  readonly agentPermanentId: string;
117
187
  readonly timeoutId: unknown;
@@ -126,6 +196,7 @@ export type AgentGoalChatPlannedMessageDependencies = {
126
196
  readonly scheduleThreadScopedUserChatTimeout: typeof scheduleThreadScopedUserChatTimeout;
127
197
  readonly listAgentUserChatTimeouts: typeof listAgentUserChatTimeouts;
128
198
  readonly getAgentScopedUserChatTimeout: typeof getAgentScopedUserChatTimeout;
199
+ readonly updateScheduledUserChatTimeout: typeof updateScheduledUserChatTimeout;
129
200
  readonly cancelScheduledUserChatTimeout: typeof cancelScheduledUserChatTimeout;
130
201
  };
131
202
 
@@ -137,6 +208,7 @@ const AGENT_GOAL_CHAT_PLANNED_MESSAGE_DEPENDENCIES: AgentGoalChatPlannedMessageD
137
208
  scheduleThreadScopedUserChatTimeout,
138
209
  listAgentUserChatTimeouts,
139
210
  getAgentScopedUserChatTimeout,
211
+ updateScheduledUserChatTimeout,
140
212
  cancelScheduledUserChatTimeout,
141
213
  };
142
214
 
@@ -144,7 +216,7 @@ const AGENT_GOAL_CHAT_PLANNED_MESSAGE_DEPENDENCIES: AgentGoalChatPlannedMessageD
144
216
  * Creates the shared planned-message operations for one agent's singleton goal chat.
145
217
  *
146
218
  * @param dependencyOverrides - Optional persistence substitutions used by focused tests.
147
- * @returns Scheduling, listing, and cancellation operations with normalized serializable results.
219
+ * @returns Scheduling, re-planning, listing, and cancellation operations with normalized serializable results.
148
220
  */
149
221
  export function createAgentGoalChatPlannedMessageActions(
150
222
  dependencyOverrides: Partial<AgentGoalChatPlannedMessageDependencies> = {},
@@ -157,16 +229,18 @@ export function createAgentGoalChatPlannedMessageActions(
157
229
  return {
158
230
  async set(options): Promise<SetAgentGoalChatPlannedMessageResult> {
159
231
  const agentPermanentId = parseRequiredText(options.agentPermanentId, 'agentPermanentId');
160
- const intervalMs = parsePlannedMessageIntervalMs(options.milliseconds);
232
+ const schedule = parsePlannedMessageSchedule(createPlannedMessageScheduleInput(options));
161
233
  const message = parseRequiredText(options.message, 'message');
162
234
  const goalChat = await dependencies.ensureAgentGoalChat(agentPermanentId);
163
- // Note: A planned message repeats like `setInterval`, so the requested delay is also its interval
164
235
  const plannedMessage = await dependencies.scheduleThreadScopedUserChatTimeout({
165
236
  userId: goalChat.userId,
166
237
  agentPermanentId,
167
238
  chatId: goalChat.id,
168
- durationMs: intervalMs,
169
- recurrenceIntervalMs: intervalMs,
239
+ recurrenceIntervalMs: schedule.recurrenceIntervalMs,
240
+ cronExpression: schedule.cronExpression,
241
+ startsAt: schedule.startsAt,
242
+ endsAt: schedule.endsAt,
243
+ maxRunCount: schedule.maxRunCount,
170
244
  message,
171
245
  });
172
246
 
@@ -174,9 +248,49 @@ export function createAgentGoalChatPlannedMessageActions(
174
248
  action: 'set',
175
249
  status: 'set',
176
250
  timeoutId: plannedMessage.timeoutId,
177
- dueAt: plannedMessage.dueAt,
178
- message: plannedMessage.message,
179
- intervalMs: plannedMessage.recurrenceIntervalMs,
251
+ ...createPlannedMessageScheduleFields(plannedMessage),
252
+ };
253
+ },
254
+
255
+ async update(options): Promise<UpdateAgentGoalChatPlannedMessageResult> {
256
+ const agentPermanentId = parseRequiredText(options.agentPermanentId, 'agentPermanentId');
257
+ const timeoutId = parseRequiredText(options.timeoutId, 'timeoutId');
258
+ const existingPlannedMessage = await dependencies.getAgentScopedUserChatTimeout({
259
+ agentPermanentId,
260
+ timeoutId,
261
+ });
262
+
263
+ if (!isActivePlannedMessage(existingPlannedMessage)) {
264
+ return { action: 'update', status: 'not_found', timeoutId };
265
+ }
266
+
267
+ if (existingPlannedMessage.status === 'RUNNING') {
268
+ // Note: A firing planned message is being re-armed from its stored schedule right now,
269
+ // so changing that schedule underneath the firing would be silently overwritten
270
+ return {
271
+ action: 'update',
272
+ status: 'busy',
273
+ timeoutId,
274
+ ...createPlannedMessageScheduleFields(existingPlannedMessage),
275
+ };
276
+ }
277
+
278
+ const patch = createPlannedMessagePatch(existingPlannedMessage, options);
279
+ const updatedPlannedMessage = await dependencies.updateScheduledUserChatTimeout({
280
+ agentPermanentId,
281
+ timeoutId,
282
+ patch,
283
+ });
284
+
285
+ if (!updatedPlannedMessage) {
286
+ return { action: 'update', status: 'not_found', timeoutId };
287
+ }
288
+
289
+ return {
290
+ action: 'update',
291
+ status: 'updated',
292
+ timeoutId,
293
+ ...createPlannedMessageScheduleFields(updatedPlannedMessage),
180
294
  };
181
295
  },
182
296
 
@@ -236,26 +350,140 @@ export function createAgentGoalChatPlannedMessageActions(
236
350
  export const AGENT_GOAL_CHAT_PLANNED_MESSAGE_ACTIONS = createAgentGoalChatPlannedMessageActions();
237
351
 
238
352
  /**
239
- * Parses one planned-message repeat interval.
353
+ * Collects the untrusted schedule fields of one planned-message request.
354
+ *
355
+ * @param request - Schedule requested by an agent.
356
+ * @returns Schedule input of the shared schedule parser.
357
+ */
358
+ function createPlannedMessageScheduleInput(
359
+ request: AgentGoalChatPlannedMessageScheduleRequest,
360
+ ): PlannedMessageScheduleInput {
361
+ return {
362
+ milliseconds: request.milliseconds,
363
+ cronExpression: request.cronExpression,
364
+ startsAt: request.startsAt,
365
+ endsAt: request.endsAt,
366
+ maxRunCount: request.maxRunCount,
367
+ };
368
+ }
369
+
370
+ /**
371
+ * Builds the stored patch of one re-planned message.
240
372
  *
241
- * @param rawMilliseconds - Untrusted interval supplied by a model or runtime API.
242
- * @returns Repeat interval in whole milliseconds.
373
+ * Only the requested fields change: the schedule is re-validated as a whole against the fields that
374
+ * stay, and the next wake-up is moved to the first one the new schedule allows.
375
+ *
376
+ * @param existingPlannedMessage - Planned message being changed.
377
+ * @param request - Schedule and message requested by the agent.
378
+ * @returns Patch written to the stored planned message.
243
379
  */
244
- function parsePlannedMessageIntervalMs(rawMilliseconds: unknown): number {
245
- const milliseconds = Number(rawMilliseconds);
380
+ function createPlannedMessagePatch(
381
+ existingPlannedMessage: UserChatTimeoutRecord,
382
+ request: AgentGoalChatPlannedMessageScheduleRequest & { readonly message?: unknown },
383
+ ): UpdateAgentScopedUserChatTimeoutPatch {
384
+ const isMessageRequested = request.message !== undefined;
385
+ const messagePatch = isMessageRequested ? { message: parseRequiredText(request.message, 'message') } : {};
386
+
387
+ if (!isPlannedMessageScheduleRequested(request)) {
388
+ if (!isMessageRequested) {
389
+ throw new ParseError(
390
+ spaceTrim(`
391
+ Nothing to change in this planned message.
392
+
393
+ - Pass at least one of \`cronExpression\`, \`milliseconds\`, \`startsAt\`, \`endsAt\`, \`maxRunCount\`, or \`message\`.
394
+ `),
395
+ );
396
+ }
397
+
398
+ return messagePatch;
399
+ }
400
+
401
+ const schedule = parsePlannedMessageSchedule(
402
+ createMergedPlannedMessageScheduleInput(existingPlannedMessage, request),
403
+ );
404
+ const dueAtDate = resolvePlannedMessageDueAt({
405
+ schedule,
406
+ completedRunCount: existingPlannedMessage.runCount,
407
+ afterDate: new Date(),
408
+ });
246
409
 
247
- if (!Number.isFinite(milliseconds) || milliseconds < MINIMUM_PLANNED_MESSAGE_INTERVAL_MS) {
410
+ if (dueAtDate === null) {
248
411
  throw new ParseError(
249
412
  spaceTrim(`
250
- Invalid planned-message interval.
413
+ This change would leave the planned message without any wake-up ahead.
251
414
 
252
- - A planned message **repeats** at this interval until it is cancelled.
253
- - \`milliseconds\` must be a number of at least \`${MINIMUM_PLANNED_MESSAGE_INTERVAL_MS}\`.
415
+ - Its schedule would already be over, for example because \`endsAt\` is in the past or \`maxRunCount\` is not above the ${existingPlannedMessage.runCount} run(s) it already did.
416
+ - **Cancel** the planned message instead when it should stop.
254
417
  `),
255
418
  );
256
419
  }
257
420
 
258
- return Math.floor(milliseconds);
421
+ return {
422
+ ...messagePatch,
423
+ dueAt: dueAtDate.toISOString(),
424
+ recurrenceIntervalMs: schedule.recurrenceIntervalMs,
425
+ cronExpression: schedule.cronExpression,
426
+ startsAt: schedule.startsAt,
427
+ endsAt: schedule.endsAt,
428
+ maxRunCount: schedule.maxRunCount,
429
+ };
430
+ }
431
+
432
+ /**
433
+ * Merges one requested schedule change into the schedule a planned message already has.
434
+ *
435
+ * Choosing a cron drops the fixed interval and choosing an interval drops the cron, because one
436
+ * planned message follows exactly one recurrence rule.
437
+ *
438
+ * @param existingPlannedMessage - Planned message being changed.
439
+ * @param request - Schedule requested by the agent.
440
+ * @returns Schedule input describing the planned message after the change.
441
+ */
442
+ function createMergedPlannedMessageScheduleInput(
443
+ existingPlannedMessage: UserChatTimeoutRecord,
444
+ request: AgentGoalChatPlannedMessageScheduleRequest,
445
+ ): PlannedMessageScheduleInput {
446
+ const isCronRequested = Boolean(request.cronExpression);
447
+ const isIntervalRequested = request.milliseconds !== undefined && request.milliseconds !== null;
448
+
449
+ return {
450
+ milliseconds: isCronRequested
451
+ ? null
452
+ : resolveRequestedScheduleValue(request.milliseconds, existingPlannedMessage.recurrenceIntervalMs),
453
+ cronExpression: isIntervalRequested
454
+ ? null
455
+ : resolveRequestedScheduleValue(request.cronExpression, existingPlannedMessage.cronExpression),
456
+ startsAt: resolveRequestedScheduleValue(request.startsAt, existingPlannedMessage.startsAt),
457
+ endsAt: resolveRequestedScheduleValue(request.endsAt, existingPlannedMessage.endsAt),
458
+ maxRunCount: resolveRequestedScheduleValue(request.maxRunCount, existingPlannedMessage.maxRunCount),
459
+ };
460
+ }
461
+
462
+ /**
463
+ * Keeps the stored value of one schedule field that was not part of the request.
464
+ *
465
+ * @param requestedValue - Untrusted value from the request, where `undefined` means "not requested".
466
+ * @param storedValue - Value the planned message has today.
467
+ * @returns Value describing the field after the change.
468
+ */
469
+ function resolveRequestedScheduleValue(requestedValue: unknown, storedValue: unknown): unknown {
470
+ return requestedValue === undefined ? storedValue : requestedValue;
471
+ }
472
+
473
+ /**
474
+ * Determines whether one request changes the schedule instead of only the message text.
475
+ *
476
+ * @param request - Schedule requested by the agent.
477
+ * @returns `true` when at least one schedule field was requested.
478
+ */
479
+ function isPlannedMessageScheduleRequested(request: AgentGoalChatPlannedMessageScheduleRequest): boolean {
480
+ return (
481
+ request.milliseconds !== undefined ||
482
+ request.cronExpression !== undefined ||
483
+ request.startsAt !== undefined ||
484
+ request.endsAt !== undefined ||
485
+ request.maxRunCount !== undefined
486
+ );
259
487
  }
260
488
 
261
489
  /**
@@ -304,6 +532,27 @@ function parseListLimit(rawLimit: unknown): number {
304
532
  return Math.floor(limit);
305
533
  }
306
534
 
535
+ /**
536
+ * Maps one durable timeout row into the schedule shared by every planned-message result.
537
+ *
538
+ * @param plannedMessage - Stored timeout row.
539
+ * @returns Serializable schedule of the planned message.
540
+ */
541
+ function createPlannedMessageScheduleFields(
542
+ plannedMessage: UserChatTimeoutRecord,
543
+ ): AgentGoalChatPlannedMessageScheduleFields {
544
+ return {
545
+ dueAt: plannedMessage.dueAt,
546
+ message: plannedMessage.message,
547
+ intervalMs: plannedMessage.recurrenceIntervalMs,
548
+ cronExpression: plannedMessage.cronExpression,
549
+ startsAt: plannedMessage.startsAt,
550
+ endsAt: plannedMessage.endsAt,
551
+ maxRunCount: plannedMessage.maxRunCount,
552
+ runCount: plannedMessage.runCount,
553
+ };
554
+ }
555
+
307
556
  /**
308
557
  * Maps one durable timeout row into the model-facing planned-message shape.
309
558
  *
@@ -314,15 +563,13 @@ function createPlannedMessageListItem(plannedMessage: UserChatTimeoutRecord): Ag
314
563
  return {
315
564
  timeoutId: plannedMessage.timeoutId,
316
565
  status: plannedMessage.status,
317
- dueAt: plannedMessage.dueAt,
318
566
  isPaused: Boolean(plannedMessage.pausedAt),
319
- message: plannedMessage.message,
320
- intervalMs: plannedMessage.recurrenceIntervalMs,
567
+ ...createPlannedMessageScheduleFields(plannedMessage),
321
568
  };
322
569
  }
323
570
 
324
571
  /**
325
- * Determines whether one timeout can still be cancelled.
572
+ * Determines whether one timeout can still be changed or cancelled.
326
573
  *
327
574
  * @param plannedMessage - Stored timeout or a missing lookup result.
328
575
  * @returns `true` for active messages without an existing cancellation request.
@@ -1,5 +1,8 @@
1
1
  import { spaceTrim } from 'spacetrim';
2
- import { formatTimeoutDurationHuman } from '../../../../../src/book-components/Chat/utils/timeoutToolCallPresentation';
2
+ import {
3
+ describeAgentPlannedMessageSchedule,
4
+ type AgentPlannedMessageScheduleDescription,
5
+ } from '../../../../../src/book-3.0/describeAgentPlannedMessageSchedule';
3
6
 
4
7
  /**
5
8
  * Lifecycle events of an agent that are recorded in its goal chat.
@@ -57,27 +60,54 @@ export function createAgentGoalChatLifecycleNoteContent(options: {
57
60
  }
58
61
 
59
62
  /**
60
- * Builds the goal-chat note left when a planned message is scheduled.
61
- *
62
- * @param options - Planned-message identity, repeat interval, due time, and optional payload message.
63
- * @returns Note content stored as one agent message.
63
+ * Planned-message details shown in one goal-chat note.
64
64
  */
65
- export function createAgentGoalChatPlannedMessageNoteContent(options: {
65
+ export type AgentGoalChatPlannedMessageNoteOptions = AgentPlannedMessageScheduleDescription & {
66
66
  readonly timeoutId: string;
67
67
  readonly dueAt: string;
68
- readonly intervalMs?: number | null;
69
68
  readonly message?: string | null;
70
- }): string {
69
+ };
70
+
71
+ /**
72
+ * Builds the goal-chat note left when a planned message is scheduled.
73
+ *
74
+ * @param options - Planned-message identity, its whole schedule, and optional payload message.
75
+ * @returns Note content stored as one agent message.
76
+ */
77
+ export function createAgentGoalChatPlannedMessageNoteContent(options: AgentGoalChatPlannedMessageNoteOptions): string {
78
+ return createAgentGoalChatPlannedMessageScheduleNoteContent('⏳ I planned a message that', options);
79
+ }
80
+
81
+ /**
82
+ * Builds the goal-chat note left when the schedule of a planned message is changed.
83
+ *
84
+ * @param options - Planned-message identity, its new schedule, and optional payload message.
85
+ * @returns Note content stored as one agent message.
86
+ */
87
+ export function createAgentGoalChatUpdatedPlannedMessageNoteContent(
88
+ options: AgentGoalChatPlannedMessageNoteOptions,
89
+ ): string {
90
+ return createAgentGoalChatPlannedMessageScheduleNoteContent('🔁 I changed a planned message, which now', options);
91
+ }
92
+
93
+ /**
94
+ * Builds one goal-chat note describing the current schedule of a planned message.
95
+ *
96
+ * @param headlinePrefix - Sentence opening telling apart a new plan from a changed one.
97
+ * @param options - Planned-message identity, its schedule, and optional payload message.
98
+ * @returns Note content stored as one agent message.
99
+ *
100
+ * @private function of `createAgentGoalChatNoteContent`
101
+ */
102
+ function createAgentGoalChatPlannedMessageScheduleNoteContent(
103
+ headlinePrefix: string,
104
+ options: AgentGoalChatPlannedMessageNoteOptions,
105
+ ): string {
71
106
  const plannedMessage = options.message?.trim() || '';
72
- const headline = options.intervalMs
73
- ? `⏳ I planned a message that will wake me up every ${formatTimeoutDurationHuman(
74
- options.intervalMs,
75
- )}, for the first time at ${options.dueAt}.`
76
- : `⏳ I planned a message that will wake me up at ${options.dueAt}.`;
77
107
 
78
108
  return spaceTrim(
79
109
  (block) => `
80
- ${headline}
110
+ ${headlinePrefix} ${describeAgentPlannedMessageSchedule(options)}.
81
111
 
82
112
  ${plannedMessage ? block(plannedMessage) : ''}
83
113
 
@@ -92,9 +122,7 @@ export function createAgentGoalChatPlannedMessageNoteContent(options: {
92
122
  * @param options - Planned-message identity.
93
123
  * @returns Note content stored as one agent message.
94
124
  */
95
- export function createAgentGoalChatCancelledPlannedMessageNoteContent(options: {
96
- readonly timeoutId: string;
97
- }): string {
125
+ export function createAgentGoalChatCancelledPlannedMessageNoteContent(options: { readonly timeoutId: string }): string {
98
126
  return spaceTrim(`
99
127
  🚫 I cancelled the planned message \`${options.timeoutId}\`, so it will not wake me up anymore.
100
128
  `);
@@ -10,6 +10,7 @@ export {
10
10
  createAgentGoalChatCancelledPlannedMessageNoteContent,
11
11
  createAgentGoalChatLifecycleNoteContent,
12
12
  createAgentGoalChatPlannedMessageNoteContent,
13
+ createAgentGoalChatUpdatedPlannedMessageNoteContent,
13
14
  } from './agentGoalChat/createAgentGoalChatNoteContent';
14
15
  export { ensureAgentGoalChat } from './agentGoalChat/ensureAgentGoalChat';
15
16
  export {
@@ -0,0 +1,46 @@
1
+ import { isSameAgentPermanentId } from '../agentIdentifier';
2
+
3
+ /**
4
+ * Identity of one agent project, shared by every project runtime state store.
5
+ */
6
+ export type AgentProjectIdentity = {
7
+ /**
8
+ * Permanent id of the agent owning the project.
9
+ */
10
+ readonly agentPermanentId: string;
11
+
12
+ /**
13
+ * Directory name of the project inside the agent `projects/` folder.
14
+ */
15
+ readonly projectName: string;
16
+ };
17
+
18
+ /**
19
+ * Creates the case-insensitive lookup key of one agent project.
20
+ *
21
+ * Agent permanent ids and project directory names are compared without letter casing everywhere,
22
+ * so state stores keyed by this function can never hold two entries for the same project.
23
+ *
24
+ * @param identity - Agent and project identification.
25
+ * @returns Lookup key usable in a `Map` or `Set`.
26
+ */
27
+ export function createAgentProjectIdentityKey(identity: AgentProjectIdentity): string {
28
+ return `${identity.agentPermanentId.toLowerCase()}/${identity.projectName.toLowerCase()}`;
29
+ }
30
+
31
+ /**
32
+ * Returns whether two identities describe the same agent project.
33
+ *
34
+ * @param firstIdentity - First agent and project identification.
35
+ * @param secondIdentity - Second agent and project identification.
36
+ * @returns `true` when both identities point at the same project of the same agent.
37
+ */
38
+ export function isSameAgentProjectIdentity(
39
+ firstIdentity: AgentProjectIdentity,
40
+ secondIdentity: AgentProjectIdentity,
41
+ ): boolean {
42
+ return (
43
+ isSameAgentPermanentId(firstIdentity.agentPermanentId, secondIdentity.agentPermanentId) &&
44
+ firstIdentity.projectName.toLowerCase() === secondIdentity.projectName.toLowerCase()
45
+ );
46
+ }