@promptbook/cli 0.112.0 → 0.113.0-0
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/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/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/serverLimits.ts +19 -0
- 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/createAgentWithDefaultVisibility.ts +3 -1
- package/apps/agents-server/src/utils/externalChatRunner/processExternalUserChatJob.ts +9 -17
- 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/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 +138 -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/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/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 +854 -692
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -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/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
|
@@ -23,10 +23,11 @@ export function createLocalUserChatJobMetadata(options: {
|
|
|
23
23
|
agentDirectoryName: string;
|
|
24
24
|
threadId: string;
|
|
25
25
|
threadCreatedAt: string;
|
|
26
|
+
jobId: string;
|
|
26
27
|
queuedAt: string;
|
|
27
28
|
expectedMessagesBeforeAnswer: number;
|
|
28
29
|
}): LocalUserChatJobMetadata {
|
|
29
|
-
const fileName = createLocalChatMessageFileName(options.threadId, options.threadCreatedAt);
|
|
30
|
+
const fileName = createLocalChatMessageFileName(options.threadId, options.threadCreatedAt, options.jobId);
|
|
30
31
|
|
|
31
32
|
return {
|
|
32
33
|
version: 1,
|
|
@@ -102,15 +103,24 @@ export function withoutLocalUserChatJobMetadata(parameters: UserChatJobParameter
|
|
|
102
103
|
/**
|
|
103
104
|
* Creates the filename used by one local message-thread book.
|
|
104
105
|
*/
|
|
105
|
-
export function createLocalChatMessageFileName(threadId: string, threadCreatedAt: string): string {
|
|
106
|
+
export function createLocalChatMessageFileName(threadId: string, threadCreatedAt: string, jobId?: string): string {
|
|
106
107
|
const createdOnDate = resolveLocalChatThreadCreatedOnDate(threadCreatedAt);
|
|
107
|
-
const normalizedThreadId = threadId
|
|
108
|
+
const normalizedThreadId = threadId
|
|
109
|
+
.trim()
|
|
110
|
+
.replace(/[^a-zA-Z0-9._-]+/g, '-')
|
|
111
|
+
.replace(/^-+|-+$/g, '');
|
|
112
|
+
const normalizedJobId = jobId
|
|
113
|
+
?.trim()
|
|
114
|
+
.replace(/[^a-zA-Z0-9._-]+/g, '-')
|
|
115
|
+
.replace(/^-+|-+$/g, '');
|
|
108
116
|
|
|
109
117
|
if (normalizedThreadId.length > 0) {
|
|
110
|
-
return `${createdOnDate}-${normalizedThreadId}.book`;
|
|
118
|
+
return `${createdOnDate}-${normalizedThreadId}${normalizedJobId ? `-${normalizedJobId}` : ''}.book`;
|
|
111
119
|
}
|
|
112
120
|
|
|
113
|
-
return `${createdOnDate}-${Buffer.from(threadId, 'utf8').toString('hex') || 'thread'}
|
|
121
|
+
return `${createdOnDate}-${Buffer.from(threadId, 'utf8').toString('hex') || 'thread'}${
|
|
122
|
+
normalizedJobId ? `-${normalizedJobId}` : ''
|
|
123
|
+
}.book`;
|
|
114
124
|
}
|
|
115
125
|
|
|
116
126
|
/**
|
|
@@ -13,7 +13,7 @@ import { createUserChatRunnerProgressCard } from '../userChat/createUserChatRunn
|
|
|
13
13
|
import { updateUserChatAssistantMessage } from '../userChat/updateUserChatAssistantMessage';
|
|
14
14
|
import type { UserChatJobRecord } from '../userChat/UserChatJobRecord';
|
|
15
15
|
import type { UserChatJobRow } from '../userChat/UserChatJobRow';
|
|
16
|
-
import {
|
|
16
|
+
import { createUserChatRunnerThreadMessages } from '../userChat/userChatMessageLifecycle';
|
|
17
17
|
import {
|
|
18
18
|
createLocalUserChatJobMetadata,
|
|
19
19
|
getLocalUserChatJobMetadata,
|
|
@@ -85,9 +85,11 @@ export async function processLocalUserChatJob(job: UserChatJobRecord): Promise<P
|
|
|
85
85
|
/**
|
|
86
86
|
* Processes the next local user chat job waiting for worker attention.
|
|
87
87
|
*/
|
|
88
|
-
export async function processNextLocalUserChatJob(
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
export async function processNextLocalUserChatJob(
|
|
89
|
+
options: {
|
|
90
|
+
preferredJobId?: string;
|
|
91
|
+
} = {},
|
|
92
|
+
): Promise<ProcessLocalUserChatJobResult | null> {
|
|
91
93
|
if (options.preferredJobId) {
|
|
92
94
|
const claimedPreferredJob = await claimNextQueuedUserChatJob({ preferredJobId: options.preferredJobId });
|
|
93
95
|
if (claimedPreferredJob) {
|
|
@@ -142,27 +144,11 @@ async function enqueueLocalUserChatJob(job: UserChatJobRecord): Promise<ProcessL
|
|
|
142
144
|
throw new Error(`User message "${job.userMessageId}" was not found in chat "${job.chatId}".`);
|
|
143
145
|
}
|
|
144
146
|
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const agentInitialMessage = previousThreadMessages.length === 0
|
|
151
|
-
? parseAgentSource(agentSourceSnapshot.agentSource).initialMessage
|
|
152
|
-
: null;
|
|
153
|
-
const initialAgentThreadMessages = agentInitialMessage
|
|
154
|
-
? [{ sender: 'AGENT' as const, content: agentInitialMessage }]
|
|
155
|
-
: [];
|
|
156
|
-
|
|
157
|
-
const threadMessages = [
|
|
158
|
-
...initialAgentThreadMessages,
|
|
159
|
-
...[...previousThreadMessages, userMessage]
|
|
160
|
-
.filter((message) => message.isComplete !== false)
|
|
161
|
-
.filter((message) => message.sender === 'USER' || message.sender === 'AGENT'),
|
|
162
|
-
].map((message) => ({
|
|
163
|
-
sender: String(message.sender),
|
|
164
|
-
content: message.content,
|
|
165
|
-
}));
|
|
147
|
+
const threadMessages = createUserChatRunnerThreadMessages({
|
|
148
|
+
messages: chat.messages,
|
|
149
|
+
userMessageId: job.userMessageId,
|
|
150
|
+
resolveInitialAgentMessage: () => parseAgentSource(agentSourceSnapshot.agentSource).initialMessage,
|
|
151
|
+
});
|
|
166
152
|
|
|
167
153
|
const agentFolder = await ensureLocalAgentFolder(agentSourceSnapshot);
|
|
168
154
|
const queuedAt = new Date().toISOString();
|
|
@@ -170,6 +156,7 @@ async function enqueueLocalUserChatJob(job: UserChatJobRecord): Promise<ProcessL
|
|
|
170
156
|
agentDirectoryName: agentFolder.directoryName,
|
|
171
157
|
threadId: chat.id,
|
|
172
158
|
threadCreatedAt: chat.createdAt,
|
|
159
|
+
jobId: job.id,
|
|
173
160
|
queuedAt,
|
|
174
161
|
expectedMessagesBeforeAnswer: threadMessages.length,
|
|
175
162
|
});
|
|
@@ -326,7 +313,11 @@ async function handleLocalUserChatJobProcessingError(
|
|
|
326
313
|
const metadata = getLocalUserChatJobMetadata(job);
|
|
327
314
|
const failureReason = error instanceof Error ? error.message : 'Local agent runner synchronization failed.';
|
|
328
315
|
|
|
329
|
-
if (
|
|
316
|
+
if (
|
|
317
|
+
job.status === 'QUEUED' ||
|
|
318
|
+
(job.status === 'RUNNING' && !metadata) ||
|
|
319
|
+
(metadata && isLocalUserChatJobTimedOut(metadata))
|
|
320
|
+
) {
|
|
330
321
|
await persistUserChatJobTerminalState({
|
|
331
322
|
job,
|
|
332
323
|
status: 'FAILED',
|
|
@@ -46,6 +46,7 @@ export type SpawnAgentLimits = {
|
|
|
46
46
|
*/
|
|
47
47
|
export type LocalAgentRunnerLimits = {
|
|
48
48
|
readonly maxFailedAttempts: number;
|
|
49
|
+
readonly maxParallelMessages: number;
|
|
49
50
|
};
|
|
50
51
|
|
|
51
52
|
/**
|
|
@@ -270,6 +271,7 @@ export async function getLocalAgentRunnerLimits(): Promise<LocalAgentRunnerLimit
|
|
|
270
271
|
const limits = await getServerLimits();
|
|
271
272
|
return {
|
|
272
273
|
maxFailedAttempts: limits[SERVER_LIMIT_KEYS.LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS],
|
|
274
|
+
maxParallelMessages: limits[SERVER_LIMIT_KEYS.LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES],
|
|
273
275
|
};
|
|
274
276
|
}
|
|
275
277
|
|
package/apps/agents-server/src/utils/serverManagement/createManagedServer/seedServerCoreAgents.ts
CHANGED
|
@@ -35,7 +35,7 @@ export async function seedServerCoreAgents(
|
|
|
35
35
|
const createdAt = new Date().toISOString();
|
|
36
36
|
const { agentInsertRecord, agentHistoryInsertRecord } = createAgentPersistenceRecords(
|
|
37
37
|
coreAgentBook,
|
|
38
|
-
{ folderId: coreFolderId, sortOrder: index
|
|
38
|
+
{ folderId: coreFolderId, sortOrder: index },
|
|
39
39
|
createdAt,
|
|
40
40
|
);
|
|
41
41
|
|
|
@@ -158,5 +158,5 @@ async function insertCoreFolder(
|
|
|
158
158
|
}),
|
|
159
159
|
);
|
|
160
160
|
|
|
161
|
-
return insertResult.rows[0]
|
|
161
|
+
return insertResult.rows[0]!.id;
|
|
162
162
|
}
|
package/apps/agents-server/src/utils/serverManagement/createManagedServer/seedServerDefaultAgents.ts
CHANGED
|
@@ -29,7 +29,7 @@ export async function seedServerDefaultAgents(
|
|
|
29
29
|
const createdAt = new Date().toISOString();
|
|
30
30
|
const { agentInsertRecord, agentHistoryInsertRecord } = createAgentPersistenceRecords(
|
|
31
31
|
defaultAgentBook,
|
|
32
|
-
{ sortOrder: index
|
|
32
|
+
{ sortOrder: index },
|
|
33
33
|
createdAt,
|
|
34
34
|
);
|
|
35
35
|
|
|
@@ -4,11 +4,6 @@ import { TOOL_TITLES } from '../../../../../src/book-components/Chat/utils/getTo
|
|
|
4
4
|
import { isVisibleChatToolCall } from '../../../../../src/book-components/Chat/utils/isVisibleChatToolCall';
|
|
5
5
|
import { resolveToolCallState } from '../../../../../src/book-components/Chat/utils/resolveToolCallState';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* Default title used while a running chat job reports harness action progress.
|
|
9
|
-
*/
|
|
10
|
-
const USER_CHAT_HARNESS_PROGRESS_TITLE = 'Working on your request';
|
|
11
|
-
|
|
12
7
|
/**
|
|
13
8
|
* Creates a user-facing progress card from the latest visible harness/tool action.
|
|
14
9
|
*
|
|
@@ -24,7 +19,6 @@ export function createUserChatHarnessProgressCard(
|
|
|
24
19
|
}
|
|
25
20
|
|
|
26
21
|
return {
|
|
27
|
-
title: USER_CHAT_HARNESS_PROGRESS_TITLE,
|
|
28
22
|
now: createHarnessProgressNowText(latestVisibleToolCall),
|
|
29
23
|
items: [],
|
|
30
24
|
updatedAt: new Date().toISOString() as NonNullable<ChatMessage['progressCard']>['updatedAt'],
|
|
@@ -11,11 +11,6 @@ export type UserChatRunnerKind = 'local' | 'external';
|
|
|
11
11
|
*/
|
|
12
12
|
export type UserChatRunnerProgressPhase = 'queued_for_runner';
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* Default title used while an out-of-process runner is working on a chat answer.
|
|
16
|
-
*/
|
|
17
|
-
const USER_CHAT_RUNNER_PROGRESS_TITLE = 'Working on your request';
|
|
18
|
-
|
|
19
14
|
/**
|
|
20
15
|
* User-facing labels for durable chat runners.
|
|
21
16
|
*/
|
|
@@ -35,7 +30,6 @@ export function createUserChatRunnerProgressCard(options: {
|
|
|
35
30
|
readonly phase: UserChatRunnerProgressPhase;
|
|
36
31
|
}): NonNullable<ChatMessage['progressCard']> {
|
|
37
32
|
return {
|
|
38
|
-
title: USER_CHAT_RUNNER_PROGRESS_TITLE,
|
|
39
33
|
now: createUserChatRunnerProgressNowText(options),
|
|
40
34
|
items: [],
|
|
41
35
|
updatedAt: new Date().toISOString() as NonNullable<ChatMessage['progressCard']>['updatedAt'],
|
|
@@ -4,6 +4,13 @@ import type { ChatMessage } from '../../../../../src/_packages/types.index';
|
|
|
4
4
|
*/
|
|
5
5
|
export type UserChatMessageLifecycleState = NonNullable<ChatMessage['lifecycleState']>;
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Message shape written into local/external chat-runner `.book` files.
|
|
9
|
+
*/
|
|
10
|
+
export type UserChatRunnerThreadMessage = Pick<ChatMessage, 'content'> & {
|
|
11
|
+
sender: 'USER' | 'AGENT';
|
|
12
|
+
};
|
|
13
|
+
|
|
7
14
|
/**
|
|
8
15
|
* Creates one persisted user-authored message for a durable chat turn.
|
|
9
16
|
*/
|
|
@@ -89,6 +96,36 @@ export function resolvePromptThreadBeforeUserMessage(
|
|
|
89
96
|
return messages.slice(0, userMessageIndex);
|
|
90
97
|
}
|
|
91
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Creates the complete chat thread mirrored to a runner before it writes the next answer.
|
|
101
|
+
*/
|
|
102
|
+
export function createUserChatRunnerThreadMessages(options: {
|
|
103
|
+
messages: ReadonlyArray<ChatMessage>;
|
|
104
|
+
userMessageId: string;
|
|
105
|
+
resolveInitialAgentMessage: () => string | null | undefined;
|
|
106
|
+
}): Array<UserChatRunnerThreadMessage> {
|
|
107
|
+
const userMessage = options.messages.find((message) => message.id === options.userMessageId);
|
|
108
|
+
if (!userMessage) {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const previousThreadMessages = resolvePromptThreadBeforeUserMessage(options.messages, options.userMessageId);
|
|
113
|
+
|
|
114
|
+
return [
|
|
115
|
+
...createInitialUserChatRunnerThreadMessages({
|
|
116
|
+
isFirstUserTurn: previousThreadMessages.length === 0,
|
|
117
|
+
resolveInitialAgentMessage: options.resolveInitialAgentMessage,
|
|
118
|
+
}),
|
|
119
|
+
...previousThreadMessages,
|
|
120
|
+
userMessage,
|
|
121
|
+
]
|
|
122
|
+
.filter(isUserChatRunnerThreadMessage)
|
|
123
|
+
.map((message) => ({
|
|
124
|
+
sender: message.sender,
|
|
125
|
+
content: message.content,
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
|
|
92
129
|
/**
|
|
93
130
|
* Maps durable job status values to message lifecycle labels rendered by the UI.
|
|
94
131
|
*/
|
|
@@ -107,3 +144,35 @@ export function resolveMessageLifecycleStateFromJobStatus(status: string): UserC
|
|
|
107
144
|
return 'completed';
|
|
108
145
|
}
|
|
109
146
|
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Recreates the synthetic first agent message that the UI shows for empty durable chats.
|
|
150
|
+
*/
|
|
151
|
+
function createInitialUserChatRunnerThreadMessages(options: {
|
|
152
|
+
isFirstUserTurn: boolean;
|
|
153
|
+
resolveInitialAgentMessage: () => string | null | undefined;
|
|
154
|
+
}): Array<UserChatRunnerThreadMessage> {
|
|
155
|
+
if (!options.isFirstUserTurn) {
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const initialAgentMessage = options.resolveInitialAgentMessage();
|
|
160
|
+
if (!initialAgentMessage || initialAgentMessage.trim().length === 0) {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return [
|
|
165
|
+
{
|
|
166
|
+
sender: 'AGENT',
|
|
167
|
+
content: initialAgentMessage,
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Returns true when one persisted message should be visible to out-of-process runners.
|
|
174
|
+
*/
|
|
175
|
+
function isUserChatRunnerThreadMessage(message: ChatMessage): message is ChatMessage & UserChatRunnerThreadMessage {
|
|
176
|
+
const isRunnerSender = message.sender === 'USER' || message.sender === 'AGENT';
|
|
177
|
+
return message.isComplete !== false && isRunnerSender;
|
|
178
|
+
}
|
|
@@ -75,11 +75,6 @@ export type UserChatProgressContext = {
|
|
|
75
75
|
readonly isAgentKitCached?: boolean;
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
-
/**
|
|
79
|
-
* Default title used by durable chat progress cards.
|
|
80
|
-
*/
|
|
81
|
-
const USER_CHAT_PROGRESS_TITLE = 'Working on your request';
|
|
82
|
-
|
|
83
78
|
/**
|
|
84
79
|
* Ordered progress item identifiers shared across all durable chat phases.
|
|
85
80
|
*/
|
|
@@ -165,7 +160,6 @@ export function createUserChatProgressCard(
|
|
|
165
160
|
const { now, next } = composeUserChatProgressPhaseText(phase, context);
|
|
166
161
|
|
|
167
162
|
return {
|
|
168
|
-
title: USER_CHAT_PROGRESS_TITLE,
|
|
169
163
|
now,
|
|
170
164
|
next,
|
|
171
165
|
items: USER_CHAT_PROGRESS_ITEMS.map((item) => ({
|
|
@@ -203,6 +203,10 @@ export type VpsSelfUpdateOverview = {
|
|
|
203
203
|
* Author timestamp of the latest remote commit in ISO format.
|
|
204
204
|
*/
|
|
205
205
|
readonly latestRemoteCommitDate: string | null;
|
|
206
|
+
/**
|
|
207
|
+
* Latest remote commit subject.
|
|
208
|
+
*/
|
|
209
|
+
readonly latestRemoteCommitMessage: string | null;
|
|
206
210
|
/**
|
|
207
211
|
* Number of commits the deployed checkout is behind the latest remote commit, or `null` when unknown.
|
|
208
212
|
*/
|
|
@@ -456,22 +460,24 @@ export async function readVpsSelfUpdateOverview(): Promise<VpsSelfUpdateOverview
|
|
|
456
460
|
});
|
|
457
461
|
}
|
|
458
462
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
463
|
+
await refreshVpsSelfUpdateRemoteBranch(repositoryDirectory, currentEnvironment.branch, originRepositoryUrl);
|
|
464
|
+
|
|
465
|
+
const [currentCommit, latestRemoteCommitSha] = await Promise.all([
|
|
466
|
+
readCommitMetadataFromRepository(repositoryDirectory, 'HEAD'),
|
|
467
|
+
readLatestRemoteBranchCommitSha(repositoryDirectory, currentEnvironment.branch, originRepositoryUrl),
|
|
464
468
|
]);
|
|
465
|
-
const
|
|
466
|
-
? await
|
|
469
|
+
const latestRemoteCommit = latestRemoteCommitSha
|
|
470
|
+
? await readCommitMetadataFromRepository(repositoryDirectory, latestRemoteCommitSha)
|
|
467
471
|
: null;
|
|
472
|
+
const currentCommitSha = currentCommit?.commitSha ?? null;
|
|
473
|
+
const latestRemoteCommitResolvedSha = latestRemoteCommit?.commitSha ?? latestRemoteCommitSha;
|
|
468
474
|
const commitsBehindCount =
|
|
469
|
-
currentCommitSha &&
|
|
470
|
-
? await countCommitsBetween(repositoryDirectory, currentCommitSha,
|
|
475
|
+
currentCommitSha && latestRemoteCommitResolvedSha
|
|
476
|
+
? await countCommitsBetween(repositoryDirectory, currentCommitSha, latestRemoteCommitResolvedSha)
|
|
471
477
|
: null;
|
|
472
478
|
const pendingCommits =
|
|
473
|
-
currentCommitSha &&
|
|
474
|
-
? await listCommitsBetween(repositoryDirectory, currentCommitSha,
|
|
479
|
+
currentCommitSha && latestRemoteCommitResolvedSha
|
|
480
|
+
? await listCommitsBetween(repositoryDirectory, currentCommitSha, latestRemoteCommitResolvedSha)
|
|
475
481
|
: [];
|
|
476
482
|
const resolvedJob = resolveVpsSelfUpdateJobForOverview(job, {
|
|
477
483
|
currentEnvironment,
|
|
@@ -486,15 +492,16 @@ export async function readVpsSelfUpdateOverview(): Promise<VpsSelfUpdateOverview
|
|
|
486
492
|
repositoryDirectory,
|
|
487
493
|
currentCommitSha,
|
|
488
494
|
currentCommitShortSha: abbreviateCommitSha(currentCommitSha),
|
|
489
|
-
currentCommitMessage,
|
|
490
|
-
currentCommitDate,
|
|
491
|
-
latestRemoteCommitSha,
|
|
492
|
-
latestRemoteCommitShortSha: abbreviateCommitSha(
|
|
493
|
-
latestRemoteCommitDate,
|
|
495
|
+
currentCommitMessage: currentCommit?.subject ?? null,
|
|
496
|
+
currentCommitDate: currentCommit?.authoredAt ?? null,
|
|
497
|
+
latestRemoteCommitSha: latestRemoteCommitResolvedSha,
|
|
498
|
+
latestRemoteCommitShortSha: abbreviateCommitSha(latestRemoteCommitResolvedSha),
|
|
499
|
+
latestRemoteCommitDate: latestRemoteCommit?.authoredAt ?? null,
|
|
500
|
+
latestRemoteCommitMessage: latestRemoteCommit?.subject ?? null,
|
|
494
501
|
commitsBehindCount,
|
|
495
502
|
pendingCommits,
|
|
496
503
|
isUpdateAvailable: Boolean(
|
|
497
|
-
currentCommitSha &&
|
|
504
|
+
currentCommitSha && latestRemoteCommitResolvedSha && currentCommitSha !== latestRemoteCommitResolvedSha,
|
|
498
505
|
),
|
|
499
506
|
originRepositoryUrl,
|
|
500
507
|
isOriginRepositoryDefault: originRepositoryUrl === VPS_SELF_UPDATE_DEFAULT_ORIGIN_REPOSITORY_URL,
|
|
@@ -525,11 +532,34 @@ export type VpsSelfUpdatePendingCommit = {
|
|
|
525
532
|
readonly authoredAt: string | null;
|
|
526
533
|
};
|
|
527
534
|
|
|
535
|
+
/**
|
|
536
|
+
* Browser-safe metadata read from one git commit object.
|
|
537
|
+
*/
|
|
538
|
+
type VpsSelfUpdateCommitMetadata = {
|
|
539
|
+
/**
|
|
540
|
+
* Full commit hash.
|
|
541
|
+
*/
|
|
542
|
+
readonly commitSha: string;
|
|
543
|
+
/**
|
|
544
|
+
* Single-line commit subject.
|
|
545
|
+
*/
|
|
546
|
+
readonly subject: string;
|
|
547
|
+
/**
|
|
548
|
+
* Author timestamp in ISO format or `null` when unknown.
|
|
549
|
+
*/
|
|
550
|
+
readonly authoredAt: string | null;
|
|
551
|
+
};
|
|
552
|
+
|
|
528
553
|
/**
|
|
529
554
|
* Hard ceiling for the pending-commits listing returned in the overview to avoid huge payloads on a long-stale server.
|
|
530
555
|
*/
|
|
531
556
|
const VPS_SELF_UPDATE_MAX_PENDING_COMMITS = 100;
|
|
532
557
|
|
|
558
|
+
/**
|
|
559
|
+
* Number of latest branch commits fetched for the update overview.
|
|
560
|
+
*/
|
|
561
|
+
const VPS_SELF_UPDATE_OVERVIEW_FETCH_DEPTH = VPS_SELF_UPDATE_MAX_PENDING_COMMITS + 1;
|
|
562
|
+
|
|
533
563
|
/**
|
|
534
564
|
* Browser-safe summary of one commit that the super admin can pick from the custom-target picker.
|
|
535
565
|
*/
|
|
@@ -825,6 +855,7 @@ function createUnavailableOverview(context: {
|
|
|
825
855
|
latestRemoteCommitSha: null,
|
|
826
856
|
latestRemoteCommitShortSha: null,
|
|
827
857
|
latestRemoteCommitDate: null,
|
|
858
|
+
latestRemoteCommitMessage: null,
|
|
828
859
|
commitsBehindCount: null,
|
|
829
860
|
pendingCommits: [],
|
|
830
861
|
isUpdateAvailable: false,
|
|
@@ -1171,6 +1202,59 @@ async function runGitInRepository(repositoryDirectory: string, args: ReadonlyArr
|
|
|
1171
1202
|
}
|
|
1172
1203
|
}
|
|
1173
1204
|
|
|
1205
|
+
/**
|
|
1206
|
+
* Fetches the tracked remote branch into the local object database before building the browser overview.
|
|
1207
|
+
*
|
|
1208
|
+
* @param repositoryDirectory - Repository checkout path.
|
|
1209
|
+
* @param branch - Target branch.
|
|
1210
|
+
* @param originRepositoryUrl - Configured upstream repository URL.
|
|
1211
|
+
*/
|
|
1212
|
+
async function refreshVpsSelfUpdateRemoteBranch(
|
|
1213
|
+
repositoryDirectory: string,
|
|
1214
|
+
branch: string,
|
|
1215
|
+
originRepositoryUrl: string,
|
|
1216
|
+
): Promise<void> {
|
|
1217
|
+
if (!branch) {
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
await runGitInRepository(repositoryDirectory, [
|
|
1222
|
+
'fetch',
|
|
1223
|
+
'--no-tags',
|
|
1224
|
+
'--prune',
|
|
1225
|
+
`--depth=${VPS_SELF_UPDATE_OVERVIEW_FETCH_DEPTH}`,
|
|
1226
|
+
originRepositoryUrl,
|
|
1227
|
+
`+refs/heads/${branch}:${createVpsSelfUpdateRemoteBranchReference(branch)}`,
|
|
1228
|
+
]);
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
/**
|
|
1232
|
+
* Reads the latest tracked-branch commit from the local remote-tracking ref, falling back to `ls-remote`.
|
|
1233
|
+
*
|
|
1234
|
+
* @param repositoryDirectory - Repository checkout path.
|
|
1235
|
+
* @param branch - Target branch.
|
|
1236
|
+
* @param originRepositoryUrl - Configured upstream repository URL.
|
|
1237
|
+
* @returns Remote branch commit sha or `null`.
|
|
1238
|
+
*/
|
|
1239
|
+
async function readLatestRemoteBranchCommitSha(
|
|
1240
|
+
repositoryDirectory: string,
|
|
1241
|
+
branch: string,
|
|
1242
|
+
originRepositoryUrl: string,
|
|
1243
|
+
): Promise<string | null> {
|
|
1244
|
+
if (!branch) {
|
|
1245
|
+
return null;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
const remoteBranchReference = createVpsSelfUpdateRemoteBranchReference(branch);
|
|
1249
|
+
const localCommitSha = await runGitInRepository(repositoryDirectory, [
|
|
1250
|
+
'rev-parse',
|
|
1251
|
+
'--verify',
|
|
1252
|
+
`${remoteBranchReference}^{commit}`,
|
|
1253
|
+
]);
|
|
1254
|
+
|
|
1255
|
+
return localCommitSha || readRemoteCommitSha(repositoryDirectory, branch, originRepositoryUrl);
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1174
1258
|
/**
|
|
1175
1259
|
* Reads the latest remote branch commit without mutating the local checkout.
|
|
1176
1260
|
*
|
|
@@ -1197,17 +1281,47 @@ async function readRemoteCommitSha(
|
|
|
1197
1281
|
}
|
|
1198
1282
|
|
|
1199
1283
|
/**
|
|
1200
|
-
*
|
|
1284
|
+
* Creates the local remote-tracking reference used for the update overview fetch.
|
|
1285
|
+
*
|
|
1286
|
+
* @param branch - Target branch.
|
|
1287
|
+
* @returns Local remote-tracking reference.
|
|
1288
|
+
*/
|
|
1289
|
+
function createVpsSelfUpdateRemoteBranchReference(branch: string): string {
|
|
1290
|
+
return `refs/remotes/origin/${branch}`;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
/**
|
|
1294
|
+
* Reads hash, subject and author timestamp for one known commit from the local repository.
|
|
1201
1295
|
*
|
|
1202
1296
|
* @param repositoryDirectory - Repository checkout path.
|
|
1203
|
-
* @param
|
|
1204
|
-
* @returns
|
|
1297
|
+
* @param commitReference - Commit hash or git revision reference to look up.
|
|
1298
|
+
* @returns Commit metadata or `null` when the commit cannot be resolved locally.
|
|
1205
1299
|
*/
|
|
1206
|
-
async function
|
|
1300
|
+
async function readCommitMetadataFromRepository(
|
|
1207
1301
|
repositoryDirectory: string,
|
|
1208
|
-
|
|
1209
|
-
): Promise<
|
|
1210
|
-
|
|
1302
|
+
commitReference: string,
|
|
1303
|
+
): Promise<VpsSelfUpdateCommitMetadata | null> {
|
|
1304
|
+
const output = await runGitInRepository(repositoryDirectory, [
|
|
1305
|
+
'log',
|
|
1306
|
+
'-1',
|
|
1307
|
+
`--format=%H${GIT_LOG_FIELD_SEPARATOR}%aI${GIT_LOG_FIELD_SEPARATOR}%s`,
|
|
1308
|
+
commitReference,
|
|
1309
|
+
]);
|
|
1310
|
+
if (!output) {
|
|
1311
|
+
return null;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
const fields = output.split(GIT_LOG_FIELD_SEPARATOR);
|
|
1315
|
+
const commitSha = fields[0] ?? '';
|
|
1316
|
+
if (!commitSha) {
|
|
1317
|
+
return null;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
return {
|
|
1321
|
+
commitSha,
|
|
1322
|
+
authoredAt: fields[1] || null,
|
|
1323
|
+
subject: fields.slice(2).join(GIT_LOG_FIELD_SEPARATOR),
|
|
1324
|
+
};
|
|
1211
1325
|
}
|
|
1212
1326
|
|
|
1213
1327
|
/**
|
|
@@ -28,6 +28,12 @@ export declare const DEFAULT_SPAWN_AGENT_RATE_LIMIT_WINDOW_MS: number;
|
|
|
28
28
|
* @private shared Agents Server constant
|
|
29
29
|
*/
|
|
30
30
|
export declare const DEFAULT_LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS = 3;
|
|
31
|
+
/**
|
|
32
|
+
* Default maximum number of local runner harness instances allowed to answer queued messages at once.
|
|
33
|
+
*
|
|
34
|
+
* @private shared Agents Server constant
|
|
35
|
+
*/
|
|
36
|
+
export declare const DEFAULT_LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES = 3;
|
|
31
37
|
/**
|
|
32
38
|
* Stable keys used by the dedicated server-limits table.
|
|
33
39
|
*
|
|
@@ -42,6 +48,7 @@ export declare const SERVER_LIMIT_KEYS: {
|
|
|
42
48
|
readonly SPAWN_AGENT_RATE_LIMIT_MAX: "SPAWN_AGENT_RATE_LIMIT_MAX";
|
|
43
49
|
readonly SPAWN_AGENT_RATE_LIMIT_WINDOW_MS: "SPAWN_AGENT_RATE_LIMIT_WINDOW_MS";
|
|
44
50
|
readonly LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS: "LOCAL_AGENT_RUNNER_MAX_FAILED_ATTEMPTS";
|
|
51
|
+
readonly LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES: "LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES";
|
|
45
52
|
};
|
|
46
53
|
/**
|
|
47
54
|
* One supported dedicated server-limit key.
|
|
@@ -156,6 +163,16 @@ export declare const SERVER_LIMIT_DEFINITIONS: ({
|
|
|
156
163
|
minimumValue: number;
|
|
157
164
|
step: number;
|
|
158
165
|
legacyMetadataKeys: never[];
|
|
166
|
+
} | {
|
|
167
|
+
key: "LOCAL_AGENT_RUNNER_MAX_PARALLEL_MESSAGES";
|
|
168
|
+
category: "Local agent runner";
|
|
169
|
+
title: string;
|
|
170
|
+
description: string;
|
|
171
|
+
unit: "count";
|
|
172
|
+
defaultValue: number;
|
|
173
|
+
minimumValue: number;
|
|
174
|
+
step: number;
|
|
175
|
+
legacyMetadataKeys: never[];
|
|
159
176
|
})[];
|
|
160
177
|
/**
|
|
161
178
|
* Fast lookup map used by server-limit validators and UI helpers.
|