@promptbook/cli 0.114.0-12 → 0.114.0-13
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/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +7 -4
- package/apps/agents-server/src/app/agents/[agentName]/chat/AgentGoalChatPlannedMessages.tsx +23 -8
- package/apps/agents-server/src/app/agents/[agentName]/chat/CanonicalAgentChatSurface.tsx +14 -3
- package/apps/agents-server/src/app/agents/[agentName]/chat/page.tsx +2 -20
- package/apps/agents-server/src/app/agents/[agentName]/page.tsx +2 -1
- package/apps/agents-server/src/app/agents/[agentName]/projectReferenceActions.ts +61 -0
- package/apps/agents-server/src/components/AgentProjects/resolveLatestCompletedAgentMessageKey.ts +32 -0
- package/apps/agents-server/src/components/AgentProjects/useAgentProjectMarkdownReferences.ts +124 -2
- package/apps/agents-server/src/languages/ServerTranslationKeys.ts +3 -0
- package/apps/agents-server/src/languages/translations/czech.yaml +3 -0
- package/apps/agents-server/src/languages/translations/english.yaml +3 -0
- package/apps/agents-server/src/tools/agentGoalChatTimeoutToolFunctions.ts +24 -2
- package/apps/agents-server/src/tools/agentGoalChatTimeoutTools.ts +5 -4
- package/apps/agents-server/src/utils/agentGoalChat/agentGoalChatPlannedMessageActions.ts +38 -9
- package/apps/agents-server/src/utils/agentGoalChat/createAgentGoalChatNoteContent.ts +15 -6
- package/apps/agents-server/src/utils/agentProjects/listAgentProjectNames.ts +35 -0
- package/apps/agents-server/src/utils/agentProjects/listAgentProjects.ts +6 -23
- package/apps/agents-server/src/utils/agentProjects/resolveAgentChatProjectReferences.ts +25 -0
- package/apps/agents-server/src/utils/chatMessageChips/createAnsweredMessageChipToolCalls.ts +37 -0
- package/apps/agents-server/src/utils/chatMessageChips/createPlannedMessageChipToolCalls.ts +39 -0
- package/apps/agents-server/src/utils/chatMessageChips/createTouchedProjectChipToolCalls.ts +75 -0
- package/apps/agents-server/src/utils/localChatRunner/applyLocalAgentPlannedMessageCommands.ts +212 -0
- package/apps/agents-server/src/utils/localChatRunner/prepareLocalAgentPlannedMessagesSidecar.ts +66 -0
- package/apps/agents-server/src/utils/localChatRunner/processLocalUserChatJob.ts +110 -22
- package/apps/agents-server/src/utils/userChat/persistUserChatJobTerminalState.ts +5 -0
- package/apps/agents-server/src/utils/userChat/userChatJobRunReport.ts +30 -0
- package/apps/agents-server/src/utils/userChatTimeout/createTimeoutWakeUpMessage.ts +9 -1
- package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/repeatFiredUserChatTimeout.ts +74 -0
- package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore.ts +1 -0
- package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutWorker.ts +63 -54
- package/esm/index.es.js +639 -80
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-agent-messages/messages/buildAgentGoalChatPromptSection.d.ts +22 -4
- package/esm/scripts/run-agent-messages/messages/buildAgentMessagePrompt.d.ts +3 -3
- package/esm/scripts/run-agent-messages/messages/loadAgentPlannedMessagesSidecar.d.ts +10 -0
- package/esm/scripts/run-agent-messages/messages/resolveTouchedAgentProjects.d.ts +15 -0
- package/esm/src/book-3.0/AgentMessageRunReport.d.ts +28 -0
- package/esm/src/book-3.0/AgentPlannedMessagesSidecar.d.ts +94 -0
- package/esm/src/book-3.0/AgentPlannedMessagesSidecar.test.d.ts +1 -0
- package/esm/src/book-3.0/createAgentMessageSidecarBaseName.d.ts +13 -0
- package/esm/src/book-components/Chat/utils/agentProjectToolCall.d.ts +46 -0
- package/esm/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +24 -0
- package/esm/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.d.ts +59 -0
- package/esm/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.d.ts +19 -0
- package/esm/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.test.d.ts +1 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/book-3.0/AgentMessageRunReport.ts +76 -0
- package/src/book-3.0/AgentPlannedMessagesSidecar.ts +229 -0
- package/src/book-3.0/AgentTeamConversationWorkspace.ts +3 -5
- package/src/book-3.0/createAgentMessageSidecarBaseName.ts +20 -0
- package/src/book-components/Chat/Chat/Chat.module.css +6 -1
- package/src/book-components/Chat/Chat/renderToolCallDetails.tsx +1 -12
- package/src/book-components/Chat/utils/agentProjectToolCall.ts +74 -0
- package/src/book-components/Chat/utils/getToolCallChipletInfo.ts +28 -0
- package/src/book-components/Chat/utils/timeoutToolCallPresentation.ts +23 -3
- package/src/other/templates/getTemplatesPipelineCollection.ts +784 -738
- package/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.ts +105 -0
- package/src/utils/agent-message-runtime/resolveAgentMessageRuntimeActivity.ts +6 -54
- package/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.ts +147 -0
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/index.umd.js +639 -80
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-agent-messages/messages/buildAgentGoalChatPromptSection.d.ts +22 -4
- package/umd/scripts/run-agent-messages/messages/buildAgentMessagePrompt.d.ts +3 -3
- package/umd/scripts/run-agent-messages/messages/loadAgentPlannedMessagesSidecar.d.ts +10 -0
- package/umd/scripts/run-agent-messages/messages/resolveTouchedAgentProjects.d.ts +15 -0
- package/umd/src/book-3.0/AgentMessageRunReport.d.ts +28 -0
- package/umd/src/book-3.0/AgentPlannedMessagesSidecar.d.ts +94 -0
- package/umd/src/book-3.0/AgentPlannedMessagesSidecar.test.d.ts +1 -0
- package/umd/src/book-3.0/createAgentMessageSidecarBaseName.d.ts +13 -0
- package/umd/src/book-components/Chat/utils/agentProjectToolCall.d.ts +46 -0
- package/umd/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +24 -0
- package/umd/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.d.ts +59 -0
- package/umd/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.d.ts +19 -0
- package/umd/src/utils/agent-message-runtime/resolveAgentMessageTouchedProjectNames.test.d.ts +1 -0
- package/umd/src/version.d.ts +1 -1
- package/esm/apps/agents-server/src/utils/agentGoalChat/agentGoalChatConstants.d.ts +0 -12
- package/umd/apps/agents-server/src/utils/agentGoalChat/agentGoalChatConstants.d.ts +0 -12
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import { AGENT_MESSAGES_DIRECTORY_PATH } from './agentFolderPaths';
|
|
3
|
+
import { createAgentMessageSidecarBaseName } from './createAgentMessageSidecarBaseName';
|
|
4
|
+
|
|
5
|
+
// Note: [💞] This file defines the shared planned-message sidecar convention rather than one standalone entity.
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Relative directory holding the planned-message sidecar of each queued message.
|
|
9
|
+
*
|
|
10
|
+
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
11
|
+
*/
|
|
12
|
+
export const AGENT_PLANNED_MESSAGES_DIRECTORY_PATH = join(AGENT_MESSAGES_DIRECTORY_PATH, 'planned');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Command actions an agent can request from its planned-message sidecar.
|
|
16
|
+
*
|
|
17
|
+
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
18
|
+
*/
|
|
19
|
+
export const AGENT_PLANNED_MESSAGE_COMMAND_ACTIONS = ['set', 'cancel'] as const;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* One planned-message command action.
|
|
23
|
+
*
|
|
24
|
+
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
25
|
+
*/
|
|
26
|
+
export type AgentPlannedMessageCommandAction = (typeof AGENT_PLANNED_MESSAGE_COMMAND_ACTIONS)[number];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* One planned message that is already waiting to wake the agent.
|
|
30
|
+
*
|
|
31
|
+
* A planned message repeats like `setInterval`, so `intervalMs` is what the agent compares with its
|
|
32
|
+
* goal, while `dueAt` only says when the nearest repetition happens.
|
|
33
|
+
*
|
|
34
|
+
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
35
|
+
*/
|
|
36
|
+
export type AgentPlannedMessageSnapshot = {
|
|
37
|
+
readonly timeoutId: string;
|
|
38
|
+
readonly dueAt: string;
|
|
39
|
+
readonly message: string | null;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Repeat interval in milliseconds, or `null` for a planned message that wakes the agent only once.
|
|
43
|
+
*/
|
|
44
|
+
readonly intervalMs: number | null;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* One command written by the coding harness into its planned-message sidecar.
|
|
49
|
+
*
|
|
50
|
+
* The payload stays untyped on purpose: it is untrusted harness output and is validated by the very
|
|
51
|
+
* same shared planned-message actions that back the model tools and the internal runtime API.
|
|
52
|
+
*
|
|
53
|
+
* For a `set` command, `milliseconds` is the repeat interval of the planned message, not a one-shot delay.
|
|
54
|
+
*
|
|
55
|
+
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
56
|
+
*/
|
|
57
|
+
export type AgentPlannedMessageCommand = {
|
|
58
|
+
readonly action: AgentPlannedMessageCommandAction;
|
|
59
|
+
readonly milliseconds?: unknown;
|
|
60
|
+
readonly message?: unknown;
|
|
61
|
+
readonly timeoutId?: unknown;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Planned-message sidecar prepared for one queued message.
|
|
66
|
+
*
|
|
67
|
+
* `currentPlannedMessages` is written by the Agents Server and is read-only for the agent, while
|
|
68
|
+
* `commands` is the only channel through which a coding harness can plan or cancel a wake-up.
|
|
69
|
+
*
|
|
70
|
+
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
71
|
+
*/
|
|
72
|
+
export type AgentPlannedMessagesSidecar = {
|
|
73
|
+
readonly version: 1;
|
|
74
|
+
readonly agentPermanentId: string;
|
|
75
|
+
readonly currentPlannedMessages: ReadonlyArray<AgentPlannedMessageSnapshot>;
|
|
76
|
+
readonly commands: ReadonlyArray<AgentPlannedMessageCommand>;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Creates the relative planned-message sidecar path of one queued message.
|
|
81
|
+
*
|
|
82
|
+
* @param messageFileName - File name of the queued `.book` message.
|
|
83
|
+
* @returns Relative path of the sidecar inside the agent folder.
|
|
84
|
+
*
|
|
85
|
+
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
86
|
+
*/
|
|
87
|
+
export function createAgentPlannedMessagesSidecarPath(messageFileName: string): string {
|
|
88
|
+
return join(AGENT_PLANNED_MESSAGES_DIRECTORY_PATH, `${createAgentMessageSidecarBaseName(messageFileName)}.json`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Serializes one planned-message sidecar into its stored representation.
|
|
93
|
+
*
|
|
94
|
+
* @param sidecar - Sidecar prepared for one queued message.
|
|
95
|
+
* @returns Pretty-printed JSON the coding harness can edit by hand.
|
|
96
|
+
*
|
|
97
|
+
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
98
|
+
*/
|
|
99
|
+
export function createAgentPlannedMessagesSidecarContent(sidecar: AgentPlannedMessagesSidecar): string {
|
|
100
|
+
return `${JSON.stringify(sidecar, null, 2)}\n`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Parses one untrusted planned-message sidecar written back by a coding harness.
|
|
105
|
+
*
|
|
106
|
+
* A malformed sidecar never fails the already answered chat, so this returns `null` instead of throwing.
|
|
107
|
+
*
|
|
108
|
+
* @param sidecarContent - Raw file content read from the agent folder.
|
|
109
|
+
* @returns Normalized sidecar, or `null` when it cannot be used.
|
|
110
|
+
*
|
|
111
|
+
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
112
|
+
*/
|
|
113
|
+
export function parseAgentPlannedMessagesSidecar(sidecarContent: string): AgentPlannedMessagesSidecar | null {
|
|
114
|
+
let parsedSidecar: unknown;
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
parsedSidecar = JSON.parse(sidecarContent);
|
|
118
|
+
} catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (!parsedSidecar || typeof parsedSidecar !== 'object' || Array.isArray(parsedSidecar)) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const sidecar = parsedSidecar as Partial<AgentPlannedMessagesSidecar>;
|
|
127
|
+
|
|
128
|
+
if (sidecar.version !== 1 || typeof sidecar.agentPermanentId !== 'string') {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
version: 1,
|
|
134
|
+
agentPermanentId: sidecar.agentPermanentId,
|
|
135
|
+
currentPlannedMessages: normalizeAgentPlannedMessageSnapshots(sidecar.currentPlannedMessages),
|
|
136
|
+
commands: normalizeAgentPlannedMessageCommands(sidecar.commands),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Keeps only the commands whose action is understood by the planned-message actions.
|
|
142
|
+
*
|
|
143
|
+
* @param rawCommands - Untrusted `commands` value read from one sidecar.
|
|
144
|
+
* @returns Commands that can be dispatched, in their original order.
|
|
145
|
+
*
|
|
146
|
+
* @private internal utility of `parseAgentPlannedMessagesSidecar`
|
|
147
|
+
*/
|
|
148
|
+
function normalizeAgentPlannedMessageCommands(rawCommands: unknown): Array<AgentPlannedMessageCommand> {
|
|
149
|
+
if (!Array.isArray(rawCommands)) {
|
|
150
|
+
return [];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return rawCommands.filter(isAgentPlannedMessageCommand);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Checks whether one untrusted sidecar entry names a supported planned-message action.
|
|
158
|
+
*
|
|
159
|
+
* @param value - Untrusted command entry.
|
|
160
|
+
* @returns `true` when the entry can be dispatched.
|
|
161
|
+
*
|
|
162
|
+
* @private internal utility of `parseAgentPlannedMessagesSidecar`
|
|
163
|
+
*/
|
|
164
|
+
function isAgentPlannedMessageCommand(value: unknown): value is AgentPlannedMessageCommand {
|
|
165
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const action = (value as AgentPlannedMessageCommand).action;
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
typeof action === 'string' &&
|
|
173
|
+
AGENT_PLANNED_MESSAGE_COMMAND_ACTIONS.includes(action as AgentPlannedMessageCommandAction)
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Keeps only the already planned messages that can be shown to the agent.
|
|
179
|
+
*
|
|
180
|
+
* @param rawSnapshots - Untrusted `currentPlannedMessages` value read from one sidecar.
|
|
181
|
+
* @returns Planned-message snapshots with the fields required for display and cancellation.
|
|
182
|
+
*
|
|
183
|
+
* @private internal utility of `parseAgentPlannedMessagesSidecar`
|
|
184
|
+
*/
|
|
185
|
+
function normalizeAgentPlannedMessageSnapshots(rawSnapshots: unknown): Array<AgentPlannedMessageSnapshot> {
|
|
186
|
+
if (!Array.isArray(rawSnapshots)) {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return rawSnapshots.filter(isAgentPlannedMessageSnapshot).map(createNormalizedAgentPlannedMessageSnapshot);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Normalizes the optional fields of one already planned message.
|
|
195
|
+
*
|
|
196
|
+
* @param snapshot - Planned-message entry with the required identity fields.
|
|
197
|
+
* @returns Snapshot with a usable repeat interval and message.
|
|
198
|
+
*
|
|
199
|
+
* @private internal utility of `parseAgentPlannedMessagesSidecar`
|
|
200
|
+
*/
|
|
201
|
+
function createNormalizedAgentPlannedMessageSnapshot(
|
|
202
|
+
snapshot: AgentPlannedMessageSnapshot,
|
|
203
|
+
): AgentPlannedMessageSnapshot {
|
|
204
|
+
const intervalMs = Number(snapshot.intervalMs);
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
timeoutId: snapshot.timeoutId,
|
|
208
|
+
dueAt: snapshot.dueAt,
|
|
209
|
+
message: typeof snapshot.message === 'string' ? snapshot.message : null,
|
|
210
|
+
intervalMs: Number.isFinite(intervalMs) && intervalMs > 0 ? Math.floor(intervalMs) : null,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Checks whether one untrusted sidecar entry describes an already planned message.
|
|
216
|
+
*
|
|
217
|
+
* @param value - Untrusted planned-message entry.
|
|
218
|
+
* @returns `true` when the entry can be shown and cancelled.
|
|
219
|
+
*
|
|
220
|
+
* @private internal utility of `parseAgentPlannedMessagesSidecar`
|
|
221
|
+
*/
|
|
222
|
+
function isAgentPlannedMessageSnapshot(value: unknown): value is AgentPlannedMessageSnapshot {
|
|
223
|
+
return Boolean(
|
|
224
|
+
value &&
|
|
225
|
+
typeof value === 'object' &&
|
|
226
|
+
typeof (value as AgentPlannedMessageSnapshot).timeoutId === 'string' &&
|
|
227
|
+
typeof (value as AgentPlannedMessageSnapshot).dueAt === 'string',
|
|
228
|
+
);
|
|
229
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { join } from 'path';
|
|
2
2
|
import { AGENT_FINISHED_MESSAGES_DIRECTORY_PATH, AGENT_MESSAGES_DIRECTORY_PATH } from './agentFolderPaths';
|
|
3
|
+
import { createAgentMessageSidecarBaseName } from './createAgentMessageSidecarBaseName';
|
|
3
4
|
|
|
4
5
|
// Note: [💞] This file defines the shared TEAM workspace convention rather than one standalone entity.
|
|
5
6
|
|
|
@@ -71,10 +72,7 @@ export type AgentTeamConversationWorkspaceManifest = {
|
|
|
71
72
|
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
72
73
|
*/
|
|
73
74
|
export function createAgentTeamConversationWorkspaceDirectoryName(messageFileName: string): string {
|
|
74
|
-
|
|
75
|
-
const normalizedBaseName = rawBaseName.replace(/[^A-Za-z0-9._-]+/gu, '-').replace(/^[._-]+|[._-]+$/gu, '');
|
|
76
|
-
|
|
77
|
-
return normalizedBaseName || 'message';
|
|
75
|
+
return createAgentMessageSidecarBaseName(messageFileName);
|
|
78
76
|
}
|
|
79
77
|
|
|
80
78
|
/**
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { basename } from 'path';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates the stable file-system safe base name that belongs to one queued `.book` message.
|
|
5
|
+
*
|
|
6
|
+
* Every sidecar the Agents Server prepares next to a queued message (TEAM workspaces, planned-message
|
|
7
|
+
* files, ...) derives its own name from this one normalization, so a sidecar can always be found again
|
|
8
|
+
* from the message file name alone.
|
|
9
|
+
*
|
|
10
|
+
* @param messageFileName - File name of the queued message, with or without directories.
|
|
11
|
+
* @returns Normalized base name usable as a directory or file name.
|
|
12
|
+
*
|
|
13
|
+
* @private internal convention shared by the Agents Server and agent-folder runner
|
|
14
|
+
*/
|
|
15
|
+
export function createAgentMessageSidecarBaseName(messageFileName: string): string {
|
|
16
|
+
const rawBaseName = basename(messageFileName).replace(/\.book$/iu, '');
|
|
17
|
+
const normalizedBaseName = rawBaseName.replace(/[^A-Za-z0-9._-]+/gu, '-').replace(/^[._-]+|[._-]+$/gu, '');
|
|
18
|
+
|
|
19
|
+
return normalizedBaseName || 'message';
|
|
20
|
+
}
|
|
@@ -735,7 +735,12 @@
|
|
|
735
735
|
border-radius: 999px;
|
|
736
736
|
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.12);
|
|
737
737
|
color: inherit;
|
|
738
|
-
|
|
738
|
+
/*
|
|
739
|
+
* OpenMoji includes ASCII digits for keycap emoji sequences. Keeping it first in this stack
|
|
740
|
+
* makes time labels such as `10:28 AM` use its non-text digit glyphs, so chips must inherit
|
|
741
|
+
* the chat typography and use OpenMoji only as its existing emoji fallback.
|
|
742
|
+
*/
|
|
743
|
+
font-family: inherit;
|
|
739
744
|
cursor: pointer;
|
|
740
745
|
transition: all 0.2s ease;
|
|
741
746
|
backdrop-filter: blur(8px);
|
|
@@ -7,6 +7,7 @@ import type { ChatMessage } from '../types/ChatMessage';
|
|
|
7
7
|
import type { ChatParticipant } from '../types/ChatParticipant';
|
|
8
8
|
import { getToolCallChipletInfo, TOOL_TITLES } from '../utils/getToolCallChipletInfo';
|
|
9
9
|
import { resolveToolCallState } from '../utils/resolveToolCallState';
|
|
10
|
+
import { isTimeoutToolCallName } from '../utils/timeoutToolCallPresentation';
|
|
10
11
|
import { getToolCallTimestamp } from '../utils/toolCallParsing/getToolCallTimestamp';
|
|
11
12
|
import { parseToolCallArguments } from '../utils/toolCallParsing/parseToolCallArguments';
|
|
12
13
|
import { parseToolCallResult } from '../utils/toolCallParsing/parseToolCallResult';
|
|
@@ -375,18 +376,6 @@ function isTimeToolCallName(toolName: string): boolean {
|
|
|
375
376
|
return toolName === 'get_current_time' || toolName === 'useTime';
|
|
376
377
|
}
|
|
377
378
|
|
|
378
|
-
/**
|
|
379
|
-
* Checks whether a tool name should use the timeout renderer.
|
|
380
|
-
*
|
|
381
|
-
* @param toolName - Raw tool name.
|
|
382
|
-
* @returns `true` when the tool is a timeout-like tool.
|
|
383
|
-
*
|
|
384
|
-
* @private function of ChatToolCallModal
|
|
385
|
-
*/
|
|
386
|
-
function isTimeoutToolCallName(toolName: string): boolean {
|
|
387
|
-
return toolName === 'set_timeout' || toolName === 'cancel_timeout';
|
|
388
|
-
}
|
|
389
|
-
|
|
390
379
|
/**
|
|
391
380
|
* Checks whether a tool name should use the email renderer.
|
|
392
381
|
*
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synthetic tool name used for agent-project chips in chat UI.
|
|
3
|
+
*
|
|
4
|
+
* The Agents Server emits one such tool call per project an answer viewed or edited, so the chat
|
|
5
|
+
* shows which projects the agent worked with below the message that touched them.
|
|
6
|
+
*
|
|
7
|
+
* @private internal chat-ui marker for touched agent projects
|
|
8
|
+
*/
|
|
9
|
+
export const AGENT_PROJECT_TOOL_CALL_NAME = 'agent_project_touched';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Safe, user-facing metadata shown in agent-project chips.
|
|
13
|
+
*
|
|
14
|
+
* @private internal chat-ui type for touched agent projects
|
|
15
|
+
*/
|
|
16
|
+
export type AgentProjectToolCallResult = {
|
|
17
|
+
/**
|
|
18
|
+
* Directory name of the project.
|
|
19
|
+
*/
|
|
20
|
+
readonly projectName: string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Human-readable project name shown in the chip.
|
|
24
|
+
*/
|
|
25
|
+
readonly displayName?: string;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Link to the project page, when the chat knows where the project lives.
|
|
29
|
+
*/
|
|
30
|
+
readonly projectHref?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Parses the project-chip payload from one tool result.
|
|
35
|
+
*
|
|
36
|
+
* @param result - Raw tool result payload.
|
|
37
|
+
* @returns Parsed project metadata, or `null` when the result describes no project.
|
|
38
|
+
*
|
|
39
|
+
* @private internal helper reused by chip and modal rendering
|
|
40
|
+
*/
|
|
41
|
+
export function parseAgentProjectToolCallResult(result: unknown): AgentProjectToolCallResult | null {
|
|
42
|
+
if (!result || typeof result !== 'object' || Array.isArray(result)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const candidate = result as Partial<AgentProjectToolCallResult>;
|
|
47
|
+
if (typeof candidate.projectName !== 'string' || candidate.projectName.trim().length === 0) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
projectName: candidate.projectName.trim(),
|
|
53
|
+
...(typeof candidate.displayName === 'string' && candidate.displayName.trim().length > 0
|
|
54
|
+
? { displayName: candidate.displayName.trim() }
|
|
55
|
+
: {}),
|
|
56
|
+
...(typeof candidate.projectHref === 'string' && candidate.projectHref.trim().length > 0
|
|
57
|
+
? { projectHref: candidate.projectHref.trim() }
|
|
58
|
+
: {}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Resolves the chip label of one touched agent project.
|
|
64
|
+
*
|
|
65
|
+
* @param projectResult - Parsed project metadata.
|
|
66
|
+
* @returns Human-readable project name.
|
|
67
|
+
*
|
|
68
|
+
* @private internal helper reused by chip and modal rendering
|
|
69
|
+
*/
|
|
70
|
+
export function resolveAgentProjectToolCallLabel(projectResult: AgentProjectToolCallResult): string {
|
|
71
|
+
return projectResult.displayName || projectResult.projectName;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { ToolCall } from '../../../types/ToolCall';
|
|
2
2
|
import { ASSISTANT_PREPARATION_TOOL_CALL_NAME } from '../../../types/ToolCall';
|
|
3
3
|
import type { AgentChipData } from '../AgentChip/AgentChip';
|
|
4
|
+
import {
|
|
5
|
+
AGENT_PROJECT_TOOL_CALL_NAME,
|
|
6
|
+
parseAgentProjectToolCallResult,
|
|
7
|
+
resolveAgentProjectToolCallLabel,
|
|
8
|
+
} from './agentProjectToolCall';
|
|
4
9
|
import { formatToolCallLocalTime } from './formatToolCallLocalTime';
|
|
5
10
|
import { formatToolCallTranslationTemplate } from './formatToolCallTranslationTemplate';
|
|
6
11
|
import {
|
|
@@ -112,6 +117,7 @@ type ToolCallChipletResolver = (context: ToolCallChipletContext) => ToolCallChip
|
|
|
112
117
|
*/
|
|
113
118
|
const SPECIALIZED_TOOL_CALL_CHIPLET_RESOLVERS: ReadonlyArray<ToolCallChipletResolver> = [
|
|
114
119
|
resolveWalletCredentialChipletInfo,
|
|
120
|
+
resolveAgentProjectToolCallChipletInfo,
|
|
115
121
|
resolveTeamToolCallChipletInfo,
|
|
116
122
|
resolveTimeToolCallChipletInfo,
|
|
117
123
|
resolveEmailToolCallChipletInfo,
|
|
@@ -140,6 +146,7 @@ export function buildToolCallChipText(chipletInfo: ToolCallChipletInfo): string
|
|
|
140
146
|
export const TOOL_TITLES: Record<string, { title: string; emoji: string }> = {
|
|
141
147
|
[ASSISTANT_PREPARATION_TOOL_CALL_NAME]: { title: 'Preparing agent', emoji: '✨' },
|
|
142
148
|
[WALLET_CREDENTIAL_TOOL_CALL_NAME]: { title: 'Credential used', emoji: '🔐' },
|
|
149
|
+
[AGENT_PROJECT_TOOL_CALL_NAME]: { title: 'Project', emoji: '📁' },
|
|
143
150
|
'self-learning': { title: 'self-learning', emoji: '🧠' },
|
|
144
151
|
retrieve_user_memory: { title: 'Reading memory', emoji: '🧠' },
|
|
145
152
|
store_user_memory: { title: 'Storing memory', emoji: '🧠' },
|
|
@@ -320,6 +327,27 @@ function resolveWalletCredentialChipletInfo(context: ToolCallChipletContext): To
|
|
|
320
327
|
return createEmojiToolCallChipletInfo(context, walletCredentialResult.credentialName);
|
|
321
328
|
}
|
|
322
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Resolves the project-name chip label for touched agent projects.
|
|
332
|
+
*
|
|
333
|
+
* @param context - Shared chiplet resolution context.
|
|
334
|
+
* @returns Chiplet info when the tool call marks a touched project, otherwise `null`.
|
|
335
|
+
*
|
|
336
|
+
* @private utility of `<Chat/>`
|
|
337
|
+
*/
|
|
338
|
+
function resolveAgentProjectToolCallChipletInfo(context: ToolCallChipletContext): ToolCallChipletInfo | null {
|
|
339
|
+
if (context.toolCall.name !== AGENT_PROJECT_TOOL_CALL_NAME) {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const projectResult = parseAgentProjectToolCallResult(context.resultRaw);
|
|
344
|
+
if (!projectResult) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return createEmojiToolCallChipletInfo(context, resolveAgentProjectToolCallLabel(projectResult));
|
|
349
|
+
}
|
|
350
|
+
|
|
323
351
|
/**
|
|
324
352
|
* Resolves a chip label and agent metadata for TEAM tool calls.
|
|
325
353
|
*
|
|
@@ -2,12 +2,26 @@ import type { TODO_any } from '../../../utils/organization/TODO_any';
|
|
|
2
2
|
import { formatToolCallDateTime } from './formatToolCallDateTime';
|
|
3
3
|
import { formatToolCallTranslationTemplate } from './formatToolCallTranslationTemplate';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Tool name of one scheduled wake-up, used by every producer of timeout chips.
|
|
7
|
+
*
|
|
8
|
+
* @private internal timeout-chat constant
|
|
9
|
+
*/
|
|
10
|
+
export const SET_TIMEOUT_TOOL_CALL_NAME = 'set_timeout';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Tool name of one cancelled wake-up, used by every producer of timeout chips.
|
|
14
|
+
*
|
|
15
|
+
* @private internal timeout-chat constant
|
|
16
|
+
*/
|
|
17
|
+
export const CANCEL_TIMEOUT_TOOL_CALL_NAME = 'cancel_timeout';
|
|
18
|
+
|
|
5
19
|
/**
|
|
6
20
|
* Tool names handled by timeout-specific chat presentation.
|
|
7
21
|
*
|
|
8
22
|
* @private internal timeout-chat constant
|
|
9
23
|
*/
|
|
10
|
-
const TIMEOUT_TOOL_NAMES = [
|
|
24
|
+
const TIMEOUT_TOOL_NAMES = [SET_TIMEOUT_TOOL_CALL_NAME, CANCEL_TIMEOUT_TOOL_CALL_NAME] as const;
|
|
11
25
|
|
|
12
26
|
/**
|
|
13
27
|
* Milliseconds in one second.
|
|
@@ -412,9 +426,15 @@ function formatTimeoutDurationCompact(milliseconds: number): string {
|
|
|
412
426
|
/**
|
|
413
427
|
* Converts timeout duration into natural language sentence fragments.
|
|
414
428
|
*
|
|
415
|
-
*
|
|
429
|
+
* Shared by every timeout surface: the chat chips, the goal-chat planned messages of the Agents
|
|
430
|
+
* Server, and the planned-message prompt section of the agent-folder runner.
|
|
431
|
+
*
|
|
432
|
+
* @param milliseconds - Duration or repeat interval in milliseconds.
|
|
433
|
+
* @returns Label such as `5 minutes` or `1 hour 30 minutes`.
|
|
434
|
+
*
|
|
435
|
+
* @private internal utility of `<Chat/>` and the Agents Server planned messages
|
|
416
436
|
*/
|
|
417
|
-
function formatTimeoutDurationHuman(milliseconds: number): string {
|
|
437
|
+
export function formatTimeoutDurationHuman(milliseconds: number): string {
|
|
418
438
|
const normalizedMilliseconds = Math.max(0, Math.floor(milliseconds));
|
|
419
439
|
const totalSeconds = Math.max(1, Math.floor(normalizedMilliseconds / SECOND_IN_MILLISECONDS));
|
|
420
440
|
|