@promptbook/cli 0.113.0-5 → 0.113.0-8
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/admin/update/AdvancedOriginRepositoryPanel.tsx +76 -0
- package/apps/agents-server/src/app/admin/update/CurrentDeploymentCard.tsx +160 -0
- package/apps/agents-server/src/app/admin/update/PendingCommitsCard.tsx +86 -0
- package/apps/agents-server/src/app/admin/update/TargetEnvironmentCard.tsx +331 -0
- package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +20 -873
- package/apps/agents-server/src/app/admin/update/UpdateJobCard.tsx +329 -0
- package/apps/agents-server/src/app/admin/update/UpdateOverview.ts +74 -0
- package/apps/agents-server/src/app/admin/update/buildDeploymentTimeBehindLabel.ts +29 -0
- package/apps/agents-server/src/app/admin/update/formatHumanReadableTimestamp.ts +18 -0
- package/apps/agents-server/src/app/admin/update/getUpdateJobFailureMessage.ts +13 -0
- package/apps/agents-server/src/app/admin/update/getUpdateJobSuccessMessage.ts +13 -0
- package/apps/agents-server/src/app/admin/update/useUpdateClientState.ts +441 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +13 -1
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageClient.tsx +14 -559
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageHeader.tsx +84 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageSection.tsx +52 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/GeneratedCodePreview.tsx +138 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/GeneratedHarnessSection.tsx +98 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/SourceBookSection.tsx +66 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/TranspiledCodeErrorBanner.tsx +30 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/TranspiledCodeExportWarningBanner.tsx +62 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/Transpiler.ts +9 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/useAgentCodeExportState.ts +478 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/cloneMockedChatPreset.ts +17 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/confirmDeleteMockedChat.ts +16 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedMessage.ts +81 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedParticipant.ts +146 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedSettings.ts +19 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDuplicatedDraft.ts +66 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/findMockedChatById.ts +51 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/persistMockedChats.ts +51 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/useMockedChatsEditorState.ts +16 -426
- package/apps/agents-server/src/components/Homepage/buildFreeGraphBoxLayout.ts +446 -0
- package/apps/agents-server/src/components/Homepage/buildGraphLayoutNodes.ts +415 -157
- package/apps/agents-server/src/components/Homepage/useAgentsGraphCanvasState.ts +2 -1
- package/apps/agents-server/src/database/sqlite/$provideLocalSqliteSupabase.ts +3 -1541
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/LocalSqliteQueryBuilder.ts +623 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/LocalSqliteSupabaseClient.ts +64 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/ensureTable.ts +93 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteFilters.ts +202 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteMutationPayload.ts +131 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteRowOperations.ts +102 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteSql.ts +59 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteTableSchema.ts +329 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteTypes.ts +84 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteValueCodec.ts +63 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/normalizeSqliteError.ts +22 -0
- package/apps/agents-server/src/search/createDefaultServerSearchProviders/loadLocalOrganizationSearchDataset.ts +12 -1
- package/apps/agents-server/src/tools/send_email.ts +1 -2
- package/apps/agents-server/src/utils/agentOrganization/loadAgentOrganizationState.ts +13 -1
- package/apps/agents-server/src/utils/backup/createServerBackupZipStream.ts +7 -1382
- package/apps/agents-server/src/utils/backup/serverBackup/appendAgentBackupEntriesToZip.ts +27 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendConversationBackupEntriesToZip.ts +140 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendFileBackupEntriesToZip.ts +147 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendMessageBackupEntriesToZip.ts +65 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendMetadataBackupEntriesToZip.ts +39 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendSectionEntriesToZip.ts +92 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendUserBackupEntriesToZip.ts +80 -0
- package/apps/agents-server/src/utils/backup/serverBackup/createRedactedWalletBackupRecord.ts +34 -0
- package/apps/agents-server/src/utils/backup/serverBackup/createServerBackupManifest.ts +82 -0
- package/apps/agents-server/src/utils/backup/serverBackup/downloadBackupBinaryContent.ts +39 -0
- package/apps/agents-server/src/utils/backup/serverBackup/resolveFeedbackThreadMessages.ts +53 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupAttachments.ts +151 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupContext.ts +167 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupFilenames.ts +161 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupPreviews.ts +97 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupRowUtilities.ts +158 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupTypes.ts +59 -0
- package/apps/agents-server/src/utils/createLocalAgentSourceImporter.ts +159 -0
- package/apps/agents-server/src/utils/createMissingImportedAgentFallback.ts +60 -0
- package/apps/agents-server/src/utils/customDomainRouting.ts +157 -12
- package/apps/agents-server/src/utils/externalChatRunner/processExternalUserChatJob.ts +1 -1
- package/apps/agents-server/src/utils/importAgentWithFallback.ts +1 -58
- package/apps/agents-server/src/utils/localAgentRouteReferences.ts +167 -0
- package/apps/agents-server/src/utils/localChatRunner/processLocalUserChatJob.ts +1 -1
- package/apps/agents-server/src/utils/managementApi/managementApiAgents.ts +17 -3
- package/apps/agents-server/src/utils/messages/sendMessage.ts +5 -3
- package/apps/agents-server/src/utils/resolveAgentStateFromSource.ts +7 -1
- package/apps/agents-server/src/utils/resolveInheritedAgentSource.ts +54 -5
- package/apps/agents-server/src/utils/resolveServerAgentContext.ts +12 -1
- package/apps/agents-server/src/utils/resolveStoredAgentState.ts +2 -1
- package/apps/agents-server/src/utils/speech-to-text/SpeechToTextFailoverRecognition/SpeechToTextFailoverRecognitionProviderRuntime.ts +0 -1
- package/apps/agents-server/src/utils/speech-to-text/SpeechToTextFailoverRecognition.ts +34 -2
- package/apps/agents-server/src/utils/userChat/userChatMessageLifecycle.ts +39 -9
- package/apps/agents-server/tests/e2e/support/ChatHistoryNavigationSupport.ts +5 -0
- package/esm/index.es.js +96 -57
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/find-refactor-candidates/find-refactor-candidates.d.ts +7 -0
- package/esm/scripts/find-refactor-candidates/selectMostImportantRefactorCandidates.d.ts +12 -0
- package/esm/src/book-components/Chat/Chat/insertDictationChunk.d.ts +1 -1
- package/esm/src/book-components/Chat/Chat/insertDictationChunk.test.d.ts +1 -0
- package/esm/src/book-components/Chat/Chat/learnDictationDictionary.test.d.ts +1 -0
- package/esm/src/book-components/Chat/Chat/refineFinalDictationChunk.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/common/createPositiveIntegerOptionParser.d.ts +10 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/avatars/avatarAnimationScheduler.ts +2 -1
- package/src/avatars/visuals/octopus3d3AvatarVisual.ts +6 -2
- package/src/avatars/visuals/octopus3d4AvatarVisual.ts +14 -18
- package/src/book-components/Chat/Chat/insertDictationChunk.ts +3 -3
- package/src/book-components/Chat/Chat/learnDictationDictionary.ts +1 -1
- package/src/book-components/Chat/Chat/useChatInputAreaDictation.ts +133 -26
- package/src/cli/cli-commands/agents-server/buildAgentsServer.ts +3 -1
- package/src/cli/cli-commands/coder/boilerplateTemplates.ts +14 -21
- package/src/cli/cli-commands/coder/find-refactor-candidates.ts +9 -2
- package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +1 -4
- package/src/cli/cli-commands/coder/run.ts +3 -27
- package/src/cli/cli-commands/common/createPositiveIntegerOptionParser.ts +31 -0
- package/src/commitments/TEAM/TEAM.ts +5 -5
- package/src/other/templates/getTemplatesPipelineCollection.ts +727 -781
- package/src/utils/ascii-art/convertImageDataToAsciiArt.ts +1 -4
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/index.umd.js +96 -57
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/find-refactor-candidates/find-refactor-candidates.d.ts +7 -0
- package/umd/scripts/find-refactor-candidates/selectMostImportantRefactorCandidates.d.ts +12 -0
- package/umd/src/book-components/Chat/Chat/insertDictationChunk.d.ts +1 -1
- package/umd/src/book-components/Chat/Chat/insertDictationChunk.test.d.ts +1 -0
- package/umd/src/book-components/Chat/Chat/learnDictationDictionary.test.d.ts +1 -0
- package/umd/src/book-components/Chat/Chat/refineFinalDictationChunk.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/common/createPositiveIntegerOptionParser.d.ts +10 -0
- package/umd/src/version.d.ts +1 -1
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { AgentBasicInformation } from '@promptbook-local/types';
|
|
4
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
5
|
+
import { downloadBlob, parseFilenameFromContentDisposition } from '../../../../utils/download/browserFileDownload';
|
|
6
|
+
import type { Transpiler } from './Transpiler';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Minimal payload returned by the transpiler-list endpoint.
|
|
10
|
+
*
|
|
11
|
+
* @private type of `useAgentCodeExportState`
|
|
12
|
+
*/
|
|
13
|
+
type TranspilerListResponse = {
|
|
14
|
+
readonly transpilers?: Array<Transpiler>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Result returned by the transpilation endpoint.
|
|
19
|
+
*
|
|
20
|
+
* @private type of `useAgentCodeExportState`
|
|
21
|
+
*/
|
|
22
|
+
type TranspilationResult = {
|
|
23
|
+
readonly code: string;
|
|
24
|
+
readonly transpiler: Transpiler;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Minimal API error payload accepted from export endpoints.
|
|
29
|
+
*
|
|
30
|
+
* @private type of `useAgentCodeExportState`
|
|
31
|
+
*/
|
|
32
|
+
type TranspiledCodeApiErrorPayload = {
|
|
33
|
+
readonly error?: string;
|
|
34
|
+
readonly message?: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* State and actions used by the export-as-transpiled-code page client.
|
|
39
|
+
*
|
|
40
|
+
* @private type of `<AgentCodePageClient/>`
|
|
41
|
+
*/
|
|
42
|
+
export type AgentCodeExportState = {
|
|
43
|
+
readonly agentProfile: AgentBasicInformation | null;
|
|
44
|
+
readonly transpilers: Array<Transpiler>;
|
|
45
|
+
readonly selectedTranspilerName: string;
|
|
46
|
+
readonly selectedTranspiler: Transpiler | null;
|
|
47
|
+
readonly transpiledCode: string;
|
|
48
|
+
readonly isPageLoading: boolean;
|
|
49
|
+
readonly isTranspiling: boolean;
|
|
50
|
+
readonly isDownloading: boolean;
|
|
51
|
+
readonly pageErrorMessage: string | null;
|
|
52
|
+
readonly transpileErrorMessage: string | null;
|
|
53
|
+
readonly downloadErrorMessage: string | null;
|
|
54
|
+
readonly downloadButtonLabel: string;
|
|
55
|
+
readonly isDownloadButtonDisabled: boolean;
|
|
56
|
+
readonly selectTranspiler: (transpilerName: string) => void;
|
|
57
|
+
readonly downloadTranspiledCode: () => Promise<void>;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Collects the export-as-transpiled-code page state, data loading, and download action behind one focused hook.
|
|
62
|
+
*
|
|
63
|
+
* @param agentName - Routed agent name.
|
|
64
|
+
* @returns State and actions needed to render `<AgentCodePageClient/>`.
|
|
65
|
+
*
|
|
66
|
+
* @private hook of `<AgentCodePageClient/>`
|
|
67
|
+
*/
|
|
68
|
+
export function useAgentCodeExportState(agentName: string): AgentCodeExportState {
|
|
69
|
+
const agentProfile = useAgentProfile(agentName);
|
|
70
|
+
const { transpilers, selectedTranspilerName, selectTranspiler, isPageLoading, pageErrorMessage } =
|
|
71
|
+
useAgentTranspilers(agentName);
|
|
72
|
+
const { transpiledCode, isTranspiling, transpileErrorMessage } = useTranspiledCode({
|
|
73
|
+
agentName,
|
|
74
|
+
selectedTranspilerName,
|
|
75
|
+
});
|
|
76
|
+
const { isDownloading, downloadErrorMessage, downloadTranspiledCode } = useTranspiledCodeDownload({
|
|
77
|
+
agentName,
|
|
78
|
+
selectedTranspilerName,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const selectedTranspiler = transpilers.find((transpiler) => transpiler.name === selectedTranspilerName) || null;
|
|
82
|
+
const downloadButtonLabel = isDownloading ? 'Preparing ZIP...' : 'Download ZIP';
|
|
83
|
+
const isDownloadButtonDisabled = !selectedTranspilerName || isPageLoading || isTranspiling || isDownloading;
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
agentProfile,
|
|
87
|
+
transpilers,
|
|
88
|
+
selectedTranspilerName,
|
|
89
|
+
selectedTranspiler,
|
|
90
|
+
transpiledCode,
|
|
91
|
+
isPageLoading,
|
|
92
|
+
isTranspiling,
|
|
93
|
+
isDownloading,
|
|
94
|
+
pageErrorMessage,
|
|
95
|
+
transpileErrorMessage,
|
|
96
|
+
downloadErrorMessage,
|
|
97
|
+
downloadButtonLabel,
|
|
98
|
+
isDownloadButtonDisabled,
|
|
99
|
+
selectTranspiler,
|
|
100
|
+
downloadTranspiledCode,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Loads the agent profile shown in the export page header.
|
|
106
|
+
*
|
|
107
|
+
* @param agentName - Routed agent name.
|
|
108
|
+
* @returns Loaded agent profile, or `null` while loading or when unavailable.
|
|
109
|
+
*
|
|
110
|
+
* @private hook of `useAgentCodeExportState`
|
|
111
|
+
*/
|
|
112
|
+
function useAgentProfile(agentName: string): AgentBasicInformation | null {
|
|
113
|
+
const [agentProfile, setAgentProfile] = useState<AgentBasicInformation | null>(null);
|
|
114
|
+
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
const abortController = new AbortController();
|
|
117
|
+
let isDisposed = false;
|
|
118
|
+
|
|
119
|
+
setAgentProfile(null);
|
|
120
|
+
|
|
121
|
+
void (async () => {
|
|
122
|
+
try {
|
|
123
|
+
const profile = await fetchAgentProfile(agentName, abortController.signal);
|
|
124
|
+
if (profile && !isDisposed) {
|
|
125
|
+
setAgentProfile(profile);
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
if (!abortController.signal.aborted) {
|
|
129
|
+
console.error('Error fetching agent profile:', error);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
})();
|
|
133
|
+
|
|
134
|
+
return () => {
|
|
135
|
+
isDisposed = true;
|
|
136
|
+
abortController.abort();
|
|
137
|
+
};
|
|
138
|
+
}, [agentName]);
|
|
139
|
+
|
|
140
|
+
return agentProfile;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Loads the list of transpilers and tracks which one is selected for the current agent.
|
|
145
|
+
*
|
|
146
|
+
* @param agentName - Routed agent name.
|
|
147
|
+
* @returns Transpiler list, selection state, and page-level loading/error state.
|
|
148
|
+
*
|
|
149
|
+
* @private hook of `useAgentCodeExportState`
|
|
150
|
+
*/
|
|
151
|
+
function useAgentTranspilers(agentName: string): {
|
|
152
|
+
readonly transpilers: Array<Transpiler>;
|
|
153
|
+
readonly selectedTranspilerName: string;
|
|
154
|
+
readonly selectTranspiler: (transpilerName: string) => void;
|
|
155
|
+
readonly isPageLoading: boolean;
|
|
156
|
+
readonly pageErrorMessage: string | null;
|
|
157
|
+
} {
|
|
158
|
+
const [transpilers, setTranspilers] = useState<Array<Transpiler>>([]);
|
|
159
|
+
const [selectedTranspilerName, setSelectedTranspilerName] = useState('');
|
|
160
|
+
const [isPageLoading, setIsPageLoading] = useState(true);
|
|
161
|
+
const [pageErrorMessage, setPageErrorMessage] = useState<string | null>(null);
|
|
162
|
+
|
|
163
|
+
useEffect(() => {
|
|
164
|
+
const abortController = new AbortController();
|
|
165
|
+
let isDisposed = false;
|
|
166
|
+
|
|
167
|
+
setIsPageLoading(true);
|
|
168
|
+
setPageErrorMessage(null);
|
|
169
|
+
setTranspilers([]);
|
|
170
|
+
setSelectedTranspilerName('');
|
|
171
|
+
|
|
172
|
+
void (async () => {
|
|
173
|
+
try {
|
|
174
|
+
const nextTranspilers = await fetchTranspilerList(agentName, abortController.signal);
|
|
175
|
+
if (isDisposed) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
setTranspilers(nextTranspilers);
|
|
180
|
+
setSelectedTranspilerName(nextTranspilers[0]?.name || '');
|
|
181
|
+
} catch (error) {
|
|
182
|
+
if (abortController.signal.aborted || isDisposed) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
setPageErrorMessage(getErrorMessage(error, 'Failed to load transpilers'));
|
|
187
|
+
} finally {
|
|
188
|
+
if (!isDisposed) {
|
|
189
|
+
setIsPageLoading(false);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
})();
|
|
193
|
+
|
|
194
|
+
return () => {
|
|
195
|
+
isDisposed = true;
|
|
196
|
+
abortController.abort();
|
|
197
|
+
};
|
|
198
|
+
}, [agentName]);
|
|
199
|
+
|
|
200
|
+
const selectTranspiler = useCallback((transpilerName: string) => {
|
|
201
|
+
setSelectedTranspilerName(transpilerName);
|
|
202
|
+
}, []);
|
|
203
|
+
|
|
204
|
+
return { transpilers, selectedTranspilerName, selectTranspiler, isPageLoading, pageErrorMessage };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Generates the transpiled code for the selected transpiler.
|
|
209
|
+
*
|
|
210
|
+
* @param options - Routed agent name and selected transpiler name.
|
|
211
|
+
* @returns Generated code plus its loading/error state.
|
|
212
|
+
*
|
|
213
|
+
* @private hook of `useAgentCodeExportState`
|
|
214
|
+
*/
|
|
215
|
+
function useTranspiledCode(options: { readonly agentName: string; readonly selectedTranspilerName: string }): {
|
|
216
|
+
readonly transpiledCode: string;
|
|
217
|
+
readonly isTranspiling: boolean;
|
|
218
|
+
readonly transpileErrorMessage: string | null;
|
|
219
|
+
} {
|
|
220
|
+
const { agentName, selectedTranspilerName } = options;
|
|
221
|
+
const [transpiledCode, setTranspiledCode] = useState('');
|
|
222
|
+
const [isTranspiling, setIsTranspiling] = useState(false);
|
|
223
|
+
const [transpileErrorMessage, setTranspileErrorMessage] = useState<string | null>(null);
|
|
224
|
+
|
|
225
|
+
useEffect(() => {
|
|
226
|
+
// Note: Without a selected transpiler there is nothing to generate, so clear any previous result.
|
|
227
|
+
if (!selectedTranspilerName) {
|
|
228
|
+
setIsTranspiling(false);
|
|
229
|
+
setTranspiledCode('');
|
|
230
|
+
setTranspileErrorMessage(null);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const abortController = new AbortController();
|
|
235
|
+
let isDisposed = false;
|
|
236
|
+
|
|
237
|
+
setIsTranspiling(true);
|
|
238
|
+
setTranspileErrorMessage(null);
|
|
239
|
+
setTranspiledCode('');
|
|
240
|
+
|
|
241
|
+
void (async () => {
|
|
242
|
+
try {
|
|
243
|
+
const code = await fetchTranspiledCode(agentName, selectedTranspilerName, abortController.signal);
|
|
244
|
+
if (!isDisposed) {
|
|
245
|
+
setTranspiledCode(code);
|
|
246
|
+
}
|
|
247
|
+
} catch (error) {
|
|
248
|
+
if (abortController.signal.aborted || isDisposed) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
setTranspileErrorMessage(getErrorMessage(error, 'Failed to transpile code'));
|
|
253
|
+
} finally {
|
|
254
|
+
if (!isDisposed) {
|
|
255
|
+
setIsTranspiling(false);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
})();
|
|
259
|
+
|
|
260
|
+
return () => {
|
|
261
|
+
isDisposed = true;
|
|
262
|
+
abortController.abort();
|
|
263
|
+
};
|
|
264
|
+
}, [agentName, selectedTranspilerName]);
|
|
265
|
+
|
|
266
|
+
return { transpiledCode, isTranspiling, transpileErrorMessage };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Handles the ZIP download of the selected transpiled harness.
|
|
271
|
+
*
|
|
272
|
+
* @param options - Routed agent name and selected transpiler name.
|
|
273
|
+
* @returns Download state and the action that triggers the browser download.
|
|
274
|
+
*
|
|
275
|
+
* @private hook of `useAgentCodeExportState`
|
|
276
|
+
*/
|
|
277
|
+
function useTranspiledCodeDownload(options: {
|
|
278
|
+
readonly agentName: string;
|
|
279
|
+
readonly selectedTranspilerName: string;
|
|
280
|
+
}): {
|
|
281
|
+
readonly isDownloading: boolean;
|
|
282
|
+
readonly downloadErrorMessage: string | null;
|
|
283
|
+
readonly downloadTranspiledCode: () => Promise<void>;
|
|
284
|
+
} {
|
|
285
|
+
const { agentName, selectedTranspilerName } = options;
|
|
286
|
+
const [isDownloading, setIsDownloading] = useState(false);
|
|
287
|
+
const [downloadErrorMessage, setDownloadErrorMessage] = useState<string | null>(null);
|
|
288
|
+
|
|
289
|
+
useEffect(() => {
|
|
290
|
+
// Note: A previous download error no longer applies once the agent or selected transpiler changes.
|
|
291
|
+
setDownloadErrorMessage(null);
|
|
292
|
+
}, [agentName, selectedTranspilerName]);
|
|
293
|
+
|
|
294
|
+
const downloadTranspiledCode = useCallback(async () => {
|
|
295
|
+
if (!selectedTranspilerName || isDownloading) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
setIsDownloading(true);
|
|
300
|
+
setDownloadErrorMessage(null);
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
const { blob, filename } = await fetchTranspiledCodeDownload(agentName, selectedTranspilerName);
|
|
304
|
+
downloadBlob(blob, filename);
|
|
305
|
+
} catch (error) {
|
|
306
|
+
setDownloadErrorMessage(getErrorMessage(error, 'Failed to download ZIP export'));
|
|
307
|
+
} finally {
|
|
308
|
+
setIsDownloading(false);
|
|
309
|
+
}
|
|
310
|
+
}, [agentName, isDownloading, selectedTranspilerName]);
|
|
311
|
+
|
|
312
|
+
return { isDownloading, downloadErrorMessage, downloadTranspiledCode };
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Creates the JSON export API path for one agent.
|
|
317
|
+
*
|
|
318
|
+
* @param agentName - Routed agent name.
|
|
319
|
+
* @returns Relative API path used for transpiler listing and code generation.
|
|
320
|
+
*
|
|
321
|
+
* @private function of `useAgentCodeExportState`
|
|
322
|
+
*/
|
|
323
|
+
function createTranspiledCodeApiPath(agentName: string): string {
|
|
324
|
+
return `/agents/${encodeURIComponent(agentName)}/export-as-transpiled-code/api`;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Creates the ZIP download API path for one agent and selected transpiler.
|
|
329
|
+
*
|
|
330
|
+
* @param agentName - Routed agent name.
|
|
331
|
+
* @param transpilerName - Selected transpiler identifier.
|
|
332
|
+
* @returns Relative download URL with the selected transpiler encoded in the query string.
|
|
333
|
+
*
|
|
334
|
+
* @private function of `useAgentCodeExportState`
|
|
335
|
+
*/
|
|
336
|
+
function createTranspiledCodeDownloadApiPath(agentName: string, transpilerName: string): string {
|
|
337
|
+
const searchParams = new URLSearchParams({ transpilerName });
|
|
338
|
+
return `${createTranspiledCodeApiPath(agentName)}/download?${searchParams.toString()}`;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Reads a user-facing API error from a failed export response.
|
|
343
|
+
*
|
|
344
|
+
* @param response - Failed HTTP response.
|
|
345
|
+
* @param fallbackMessage - Fallback message when the body has no structured error.
|
|
346
|
+
* @returns Friendly error message suitable for rendering in the UI.
|
|
347
|
+
*
|
|
348
|
+
* @private function of `useAgentCodeExportState`
|
|
349
|
+
*/
|
|
350
|
+
async function resolveTranspiledCodeApiErrorMessage(response: Response, fallbackMessage: string): Promise<string> {
|
|
351
|
+
try {
|
|
352
|
+
const payload = (await response.json()) as TranspiledCodeApiErrorPayload;
|
|
353
|
+
const message = payload.message || payload.error;
|
|
354
|
+
|
|
355
|
+
if (message && message.trim().length > 0) {
|
|
356
|
+
return message.trim();
|
|
357
|
+
}
|
|
358
|
+
} catch {
|
|
359
|
+
// Keep the fallback message when the error body is not valid JSON.
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return fallbackMessage;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Loads the list of transpilers available for the agent export.
|
|
367
|
+
*
|
|
368
|
+
* @param agentName - Routed agent name.
|
|
369
|
+
* @param signal - Abort signal cancelling the request when the effect is disposed.
|
|
370
|
+
* @returns Available transpilers, or an empty list when none are returned.
|
|
371
|
+
*
|
|
372
|
+
* @private function of `useAgentCodeExportState`
|
|
373
|
+
*/
|
|
374
|
+
async function fetchTranspilerList(agentName: string, signal: AbortSignal): Promise<Array<Transpiler>> {
|
|
375
|
+
const response = await fetch(createTranspiledCodeApiPath(agentName), {
|
|
376
|
+
method: 'GET',
|
|
377
|
+
signal,
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
if (!response.ok) {
|
|
381
|
+
throw new Error(await resolveTranspiledCodeApiErrorMessage(response, 'Failed to load transpilers'));
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const payload = (await response.json()) as TranspilerListResponse;
|
|
385
|
+
return payload.transpilers || [];
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Generates the transpiled code for one agent and transpiler.
|
|
390
|
+
*
|
|
391
|
+
* @param agentName - Routed agent name.
|
|
392
|
+
* @param transpilerName - Selected transpiler identifier.
|
|
393
|
+
* @param signal - Abort signal cancelling the request when the effect is disposed.
|
|
394
|
+
* @returns Generated harness code.
|
|
395
|
+
*
|
|
396
|
+
* @private function of `useAgentCodeExportState`
|
|
397
|
+
*/
|
|
398
|
+
async function fetchTranspiledCode(agentName: string, transpilerName: string, signal: AbortSignal): Promise<string> {
|
|
399
|
+
const response = await fetch(createTranspiledCodeApiPath(agentName), {
|
|
400
|
+
method: 'POST',
|
|
401
|
+
headers: {
|
|
402
|
+
'Content-Type': 'application/json',
|
|
403
|
+
},
|
|
404
|
+
body: JSON.stringify({ transpilerName }),
|
|
405
|
+
signal,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
if (!response.ok) {
|
|
409
|
+
throw new Error(await resolveTranspiledCodeApiErrorMessage(response, 'Failed to transpile code'));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const result = (await response.json()) as TranspilationResult;
|
|
413
|
+
return result.code;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Downloads the ZIP export for one agent and transpiler.
|
|
418
|
+
*
|
|
419
|
+
* @param agentName - Routed agent name.
|
|
420
|
+
* @param transpilerName - Selected transpiler identifier.
|
|
421
|
+
* @returns Download blob and its resolved filename.
|
|
422
|
+
*
|
|
423
|
+
* @private function of `useAgentCodeExportState`
|
|
424
|
+
*/
|
|
425
|
+
async function fetchTranspiledCodeDownload(
|
|
426
|
+
agentName: string,
|
|
427
|
+
transpilerName: string,
|
|
428
|
+
): Promise<{ readonly blob: Blob; readonly filename: string }> {
|
|
429
|
+
const response = await fetch(createTranspiledCodeDownloadApiPath(agentName, transpilerName), {
|
|
430
|
+
method: 'GET',
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
if (!response.ok) {
|
|
434
|
+
throw new Error(await resolveTranspiledCodeApiErrorMessage(response, 'Failed to download ZIP export'));
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const filename =
|
|
438
|
+
parseFilenameFromContentDisposition(response.headers.get('Content-Disposition')) ||
|
|
439
|
+
'promptbook-agent-export.zip';
|
|
440
|
+
const blob = await response.blob();
|
|
441
|
+
|
|
442
|
+
return { blob, filename };
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Loads the agent profile for the export header, returning `null` when unavailable.
|
|
447
|
+
*
|
|
448
|
+
* @param agentName - Routed agent name.
|
|
449
|
+
* @param signal - Abort signal cancelling the request when the effect is disposed.
|
|
450
|
+
* @returns Loaded agent profile, or `null` when the profile endpoint responds with an error status.
|
|
451
|
+
*
|
|
452
|
+
* @private function of `useAgentCodeExportState`
|
|
453
|
+
*/
|
|
454
|
+
async function fetchAgentProfile(agentName: string, signal: AbortSignal): Promise<AgentBasicInformation | null> {
|
|
455
|
+
const response = await fetch(`/agents/${encodeURIComponent(agentName)}/api/profile`, {
|
|
456
|
+
method: 'GET',
|
|
457
|
+
signal,
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
if (!response.ok) {
|
|
461
|
+
return null;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return (await response.json()) as AgentBasicInformation;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Extracts a user-facing message from an unknown caught value.
|
|
469
|
+
*
|
|
470
|
+
* @param error - Unknown caught value.
|
|
471
|
+
* @param fallbackMessage - Message used when the caught value is not an `Error`.
|
|
472
|
+
* @returns Human-readable error message.
|
|
473
|
+
*
|
|
474
|
+
* @private function of `useAgentCodeExportState`
|
|
475
|
+
*/
|
|
476
|
+
function getErrorMessage(error: unknown, fallbackMessage: string): string {
|
|
477
|
+
return error instanceof Error ? error.message : fallbackMessage;
|
|
478
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MockedChatPreset } from '@/src/utils/mockedChatsSchema';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Clones one mocked-chat preset so editor state does not mutate saved references.
|
|
5
|
+
*
|
|
6
|
+
* @private function of <MockedChatsEditorClient/>
|
|
7
|
+
*/
|
|
8
|
+
export function cloneMockedChatPreset(preset: MockedChatPreset): MockedChatPreset {
|
|
9
|
+
return {
|
|
10
|
+
...preset,
|
|
11
|
+
participants: preset.participants.map((participant) => ({ ...participant })),
|
|
12
|
+
messages: preset.messages.map((message) => ({ ...message })),
|
|
13
|
+
settings: {
|
|
14
|
+
...preset.settings,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { showConfirm } from '@/src/components/AsyncDialogs/asyncDialogs';
|
|
2
|
+
import type { MockedChatPreset } from '@/src/utils/mockedChatsSchema';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Requests confirmation before deleting one mocked chat.
|
|
6
|
+
*
|
|
7
|
+
* @private function of <MockedChatsEditorClient/>
|
|
8
|
+
*/
|
|
9
|
+
export async function confirmDeleteMockedChat(targetChat: MockedChatPreset): Promise<boolean> {
|
|
10
|
+
return showConfirm({
|
|
11
|
+
title: 'Delete mocked chat',
|
|
12
|
+
message: `Delete "${targetChat.name}"? This cannot be undone.`,
|
|
13
|
+
confirmLabel: 'Delete mocked chat',
|
|
14
|
+
cancelLabel: 'Cancel',
|
|
15
|
+
}).catch(() => false);
|
|
16
|
+
}
|
package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedMessage.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createMockedChatMessageId,
|
|
3
|
+
type MockedChatParticipant,
|
|
4
|
+
type MockedChatPreset,
|
|
5
|
+
type MockedChatScriptedMessage,
|
|
6
|
+
} from '@/src/utils/mockedChatsSchema';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Fallback offset distance when adding new scripted messages.
|
|
10
|
+
*
|
|
11
|
+
* @private constant of <MockedChatsEditorClient/>
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_NEW_MESSAGE_OFFSET_STEP_MS = 1_200;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Adds one scripted message at the end of the sequence.
|
|
17
|
+
*
|
|
18
|
+
* @private function of <MockedChatsEditorClient/>
|
|
19
|
+
*/
|
|
20
|
+
export function createDraftWithAddedMessage(previousDraft: MockedChatPreset): MockedChatPreset {
|
|
21
|
+
const previousOffset = previousDraft.messages[previousDraft.messages.length - 1]?.offsetMs || 0;
|
|
22
|
+
|
|
23
|
+
const nextMessage: MockedChatScriptedMessage = {
|
|
24
|
+
id: createMockedChatMessageId(),
|
|
25
|
+
senderId: resolveDefaultMessageSenderId(previousDraft.participants),
|
|
26
|
+
content: 'New scripted message',
|
|
27
|
+
offsetMs: previousOffset + DEFAULT_NEW_MESSAGE_OFFSET_STEP_MS,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
...previousDraft,
|
|
32
|
+
messages: [...previousDraft.messages, nextMessage],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Updates one scripted message field.
|
|
38
|
+
*
|
|
39
|
+
* @private function of <MockedChatsEditorClient/>
|
|
40
|
+
*/
|
|
41
|
+
export function createDraftWithUpdatedMessage<TField extends keyof MockedChatScriptedMessage>(
|
|
42
|
+
previousDraft: MockedChatPreset,
|
|
43
|
+
messageId: string,
|
|
44
|
+
field: TField,
|
|
45
|
+
value: MockedChatScriptedMessage[TField],
|
|
46
|
+
): MockedChatPreset {
|
|
47
|
+
return {
|
|
48
|
+
...previousDraft,
|
|
49
|
+
messages: previousDraft.messages.map((message) => {
|
|
50
|
+
if (message.id !== messageId) {
|
|
51
|
+
return message;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
...message,
|
|
56
|
+
[field]: value,
|
|
57
|
+
};
|
|
58
|
+
}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Removes one scripted message.
|
|
64
|
+
*
|
|
65
|
+
* @private function of <MockedChatsEditorClient/>
|
|
66
|
+
*/
|
|
67
|
+
export function createDraftWithRemovedMessage(previousDraft: MockedChatPreset, messageId: string): MockedChatPreset {
|
|
68
|
+
return {
|
|
69
|
+
...previousDraft,
|
|
70
|
+
messages: previousDraft.messages.filter((message) => message.id !== messageId),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Resolves the participant used for newly added scripted messages.
|
|
76
|
+
*
|
|
77
|
+
* @private function of <MockedChatsEditorClient/>
|
|
78
|
+
*/
|
|
79
|
+
function resolveDefaultMessageSenderId(participants: ReadonlyArray<MockedChatParticipant>): string {
|
|
80
|
+
return participants.find((participant) => participant.isMe)?.id || participants[0]?.id || 'USER';
|
|
81
|
+
}
|