@promptbook/cli 0.104.0-1 → 0.104.0-10
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/config.ts +1 -3
- package/apps/agents-server/next.config.ts +2 -2
- package/apps/agents-server/package.json +7 -3
- package/apps/agents-server/public/fonts/OpenMoji-color-cbdt.woff2 +0 -0
- package/apps/agents-server/public/swagger.json +115 -0
- package/apps/agents-server/scripts/generate-reserved-paths/generate-reserved-paths.ts +54 -0
- package/apps/agents-server/scripts/generate-reserved-paths/tsconfig.json +19 -0
- package/apps/agents-server/src/app/AddAgentButton.tsx +47 -21
- package/apps/agents-server/src/app/actions.ts +22 -5
- package/apps/agents-server/src/app/admin/browser-test/BrowserTestClient.tsx +211 -0
- package/apps/agents-server/src/app/admin/browser-test/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/chat-feedback/ChatFeedbackClient.tsx +221 -274
- package/apps/agents-server/src/app/admin/chat-history/ChatHistoryClient.tsx +94 -137
- package/apps/agents-server/src/app/admin/messages/MessagesClient.tsx +294 -0
- package/apps/agents-server/src/app/admin/messages/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/messages/send-email/SendEmailClient.tsx +104 -0
- package/apps/agents-server/src/app/admin/messages/send-email/actions.ts +35 -0
- package/apps/agents-server/src/app/admin/messages/send-email/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/metadata/MetadataClient.tsx +23 -19
- package/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +15 -1
- package/apps/agents-server/src/app/agents/[agentName]/AgentOptionsMenu.tsx +51 -9
- package/apps/agents-server/src/app/agents/[agentName]/AgentProfileChat.tsx +47 -4
- package/apps/agents-server/src/app/agents/[agentName]/AgentProfileWrapper.tsx +53 -11
- package/apps/agents-server/src/app/agents/[agentName]/_utils.ts +23 -3
- package/apps/agents-server/src/app/agents/[agentName]/agentLinks.tsx +8 -8
- package/apps/agents-server/src/app/agents/[agentName]/api/agents/route.ts +17 -26
- package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +4 -2
- package/apps/agents-server/src/app/agents/[agentName]/api/chat/route.ts +20 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/mcp/route.ts +6 -11
- package/apps/agents-server/src/app/agents/[agentName]/api/profile/route.ts +5 -1
- package/apps/agents-server/src/app/agents/[agentName]/api/voice/route.ts +5 -2
- package/apps/agents-server/src/app/agents/[agentName]/book/BookEditorWrapper.tsx +20 -16
- package/apps/agents-server/src/app/agents/[agentName]/book/page.tsx +15 -2
- package/apps/agents-server/src/app/agents/[agentName]/book+chat/page.tsx +15 -2
- package/apps/agents-server/src/app/agents/[agentName]/chat/page.tsx +12 -0
- package/apps/agents-server/src/app/agents/[agentName]/code/api/route.ts +68 -0
- package/apps/agents-server/src/app/agents/[agentName]/code/page.tsx +223 -0
- package/apps/agents-server/src/app/agents/[agentName]/generateAgentMetadata.ts +5 -0
- package/apps/agents-server/src/app/agents/[agentName]/history/actions.ts +2 -2
- package/apps/agents-server/src/app/agents/[agentName]/history/page.tsx +10 -3
- package/apps/agents-server/src/app/agents/[agentName]/images/default-avatar.png/getAgentDefaultAvatarPrompt.ts +31 -0
- package/apps/agents-server/src/app/agents/[agentName]/images/default-avatar.png/route.ts +194 -0
- package/apps/agents-server/src/app/agents/[agentName]/images/icon-256.png/route.tsx +14 -2
- package/apps/agents-server/src/app/agents/[agentName]/images/page.tsx +200 -0
- package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-fullhd.png/route.tsx +4 -3
- package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-phone.png/route.tsx +4 -3
- package/apps/agents-server/src/app/agents/[agentName]/integration/page.tsx +10 -3
- package/apps/agents-server/src/app/agents/[agentName]/links/page.tsx +11 -4
- package/apps/agents-server/src/app/agents/[agentName]/opengraph-image.tsx +11 -2
- package/apps/agents-server/src/app/agents/[agentName]/page.tsx +18 -10
- package/apps/agents-server/src/app/agents/[agentName]/system-message/page.tsx +100 -0
- package/apps/agents-server/src/app/api/admin-email/route.ts +12 -0
- package/apps/agents-server/src/app/api/agents/[agentName]/clone/route.ts +13 -14
- package/apps/agents-server/src/app/api/agents/[agentName]/restore/route.ts +20 -0
- package/apps/agents-server/src/app/api/agents/[agentName]/route.ts +43 -1
- package/apps/agents-server/src/app/api/agents/route.ts +28 -3
- package/apps/agents-server/src/app/api/api-tokens/route.ts +6 -7
- package/apps/agents-server/src/app/api/browser-test/act/route.ts +141 -0
- package/apps/agents-server/src/app/api/browser-test/screenshot/route.ts +30 -0
- package/apps/agents-server/src/app/api/browser-test/scroll-facebook/route.ts +62 -0
- package/apps/agents-server/src/app/api/docs/book.md/route.ts +61 -0
- package/apps/agents-server/src/app/api/emails/incoming/sendgrid/route.ts +48 -0
- package/apps/agents-server/src/app/api/federated-agents/route.ts +12 -0
- package/apps/agents-server/src/app/api/images/[filename]/route.ts +107 -0
- package/apps/agents-server/src/app/api/messages/route.ts +102 -0
- package/apps/agents-server/src/app/api/metadata/route.ts +5 -6
- package/apps/agents-server/src/app/api/upload/route.ts +128 -45
- package/apps/agents-server/src/app/docs/[docId]/page.tsx +2 -3
- package/apps/agents-server/src/app/docs/page.tsx +12 -12
- package/apps/agents-server/src/app/globals.css +140 -33
- package/apps/agents-server/src/app/humans.txt/route.ts +1 -1
- package/apps/agents-server/src/app/layout.tsx +27 -22
- package/apps/agents-server/src/app/page.tsx +54 -6
- package/apps/agents-server/src/app/recycle-bin/actions.ts +20 -14
- package/apps/agents-server/src/app/recycle-bin/page.tsx +27 -41
- package/apps/agents-server/src/app/robots.txt/route.ts +1 -1
- package/apps/agents-server/src/app/security.txt/route.ts +1 -1
- package/apps/agents-server/src/app/sitemap.xml/route.ts +9 -7
- package/apps/agents-server/src/app/swagger/page.tsx +14 -0
- package/apps/agents-server/src/components/AgentProfile/AgentProfile.tsx +41 -116
- package/apps/agents-server/src/components/AgentProfile/AgentProfileImage.tsx +92 -0
- package/apps/agents-server/src/components/AgentProfile/QrCodeModal.tsx +0 -1
- package/apps/agents-server/src/components/AgentProfile/useAgentBackground.ts +97 -0
- package/apps/agents-server/src/components/Auth/AuthControls.tsx +5 -4
- package/apps/agents-server/src/components/DeletedAgentBanner.tsx +26 -0
- package/apps/agents-server/src/components/DocsToolbar/DocsToolbar.tsx +38 -0
- package/apps/agents-server/src/components/DocumentationContent/DocumentationContent.tsx +11 -9
- package/apps/agents-server/src/components/Footer/Footer.tsx +5 -5
- package/apps/agents-server/src/components/ForgottenPasswordDialog/ForgottenPasswordDialog.tsx +61 -0
- package/apps/agents-server/src/components/Header/Header.tsx +114 -40
- package/apps/agents-server/src/components/Homepage/AgentCard.tsx +145 -23
- package/apps/agents-server/src/components/Homepage/AgentsList.tsx +93 -15
- package/apps/agents-server/src/components/Homepage/DeletedAgentsList.tsx +66 -0
- package/apps/agents-server/src/components/Homepage/ExternalAgentsSection.tsx +12 -3
- package/apps/agents-server/src/components/Homepage/ExternalAgentsSectionClient.tsx +19 -10
- package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +3 -2
- package/apps/agents-server/src/components/LoginForm/LoginForm.tsx +50 -1
- package/apps/agents-server/src/components/NewAgentDialog/NewAgentDialog.tsx +88 -0
- package/apps/agents-server/src/components/NotFoundPage/NotFoundPage.tsx +7 -2
- package/apps/agents-server/src/components/OpenMojiIcon/OpenMojiIcon.tsx +16 -7
- package/apps/agents-server/src/components/PrintHeader/PrintHeader.tsx +4 -4
- package/apps/agents-server/src/components/RegisterUserDialog/RegisterUserDialog.tsx +61 -0
- package/apps/agents-server/src/components/VercelDeploymentCard/VercelDeploymentCard.tsx +2 -0
- package/apps/agents-server/src/components/_utils/generateMetaTxt.ts +12 -10
- package/apps/agents-server/src/components/_utils/headlessParam.tsx +7 -3
- package/apps/agents-server/src/database/$provideSupabaseForBrowser.ts +3 -3
- package/apps/agents-server/src/database/$provideSupabaseForServer.ts +1 -1
- package/apps/agents-server/src/database/$provideSupabaseForWorker.ts +3 -3
- package/apps/agents-server/src/database/metadataDefaults.ts +19 -1
- package/apps/agents-server/src/database/migrate.ts +34 -1
- package/apps/agents-server/src/database/migrations/2025-11-0001-initial-schema.sql +1 -3
- package/apps/agents-server/src/database/migrations/2025-11-0002-metadata-table.sql +1 -3
- package/apps/agents-server/src/database/migrations/2025-12-0240-agent-public-id.sql +3 -0
- package/apps/agents-server/src/database/migrations/2025-12-0360-agent-deleted-at.sql +1 -0
- package/apps/agents-server/src/database/migrations/2025-12-0370-image-table.sql +19 -0
- package/apps/agents-server/src/database/migrations/2025-12-0380-agent-visibility.sql +1 -0
- package/apps/agents-server/src/database/migrations/2025-12-0390-upload-tracking.sql +20 -0
- package/apps/agents-server/src/database/migrations/2025-12-0401-file-upload-status.sql +13 -0
- package/apps/agents-server/src/database/migrations/2025-12-0402-message-table.sql +42 -0
- package/apps/agents-server/src/database/migrations/2025-12-0403-generation-lock-table.sql +15 -0
- package/apps/agents-server/src/database/migrations/2025-12-0640-openai-assistant-cache.sql +12 -0
- package/apps/agents-server/src/database/migrations/2025-12-0820-agent-history-permanent-id.sql +29 -0
- package/apps/agents-server/src/database/schema.ts +231 -4
- package/apps/agents-server/src/generated/reservedPaths.ts +32 -0
- package/apps/agents-server/src/message-providers/email/_common/Email.ts +73 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/TODO.txt +1 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddress.test.ts.todo +108 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddress.ts +62 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddresses.test.ts.todo +117 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddresses.ts +19 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddress.test.ts.todo +119 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddress.ts +19 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddresses.test.ts.todo +74 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddresses.ts +14 -0
- package/apps/agents-server/src/message-providers/email/sendgrid/SendgridMessageProvider.ts +44 -0
- package/apps/agents-server/src/message-providers/email/sendgrid/parseInboundSendgridEmail.ts +49 -0
- package/apps/agents-server/src/message-providers/email/zeptomail/ZeptomailMessageProvider.ts +51 -0
- package/apps/agents-server/src/message-providers/index.ts +13 -0
- package/apps/agents-server/src/message-providers/interfaces/MessageProvider.ts +11 -0
- package/apps/agents-server/src/middleware.ts +19 -23
- package/apps/agents-server/src/tools/$provideBrowserForServer.ts +32 -0
- package/apps/agents-server/src/tools/$provideCdnForServer.ts +7 -2
- package/apps/agents-server/src/utils/auth.ts +117 -17
- package/apps/agents-server/src/utils/cdn/classes/TrackedFilesStorage.ts +57 -0
- package/apps/agents-server/src/utils/cdn/classes/VercelBlobStorage.ts +4 -0
- package/apps/agents-server/src/utils/cdn/interfaces/IFilesStorage.ts +18 -0
- package/apps/agents-server/src/utils/content/extractBodyContentFromHtml.ts +19 -0
- package/apps/agents-server/src/utils/getUserIdFromRequest.ts +35 -0
- package/apps/agents-server/src/utils/handleChatCompletion.ts +65 -5
- package/apps/agents-server/src/utils/messages/sendMessage.ts +91 -0
- package/apps/agents-server/src/utils/messagesAdmin.ts +72 -0
- package/apps/agents-server/src/utils/normalization/filenameToPrompt.test.ts +36 -0
- package/apps/agents-server/src/utils/normalization/filenameToPrompt.ts +25 -0
- package/apps/agents-server/src/utils/validateApiKey.ts +7 -11
- package/esm/index.es.js +2890 -2737
- package/esm/index.es.js.map +1 -1
- package/esm/typings/servers.d.ts +8 -0
- package/esm/typings/src/_packages/core.index.d.ts +2 -0
- package/esm/typings/src/_packages/types.index.d.ts +10 -2
- package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +6 -1
- package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirements.d.ts +6 -6
- package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.closed.test.d.ts +1 -0
- package/esm/typings/src/book-2.0/utils/generatePlaceholderAgentProfileImageUrl.d.ts +3 -3
- package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +5 -1
- package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
- package/esm/typings/src/book-components/Chat/CodeBlock/CodeBlock.d.ts +13 -0
- package/esm/typings/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +1 -0
- package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +7 -11
- package/esm/typings/src/book-components/_common/Dropdown/Dropdown.d.ts +2 -2
- package/esm/typings/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +56 -0
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +21 -11
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +80 -14
- package/esm/typings/src/commitments/DICTIONARY/DICTIONARY.d.ts +46 -0
- package/esm/typings/src/commitments/index.d.ts +2 -1
- package/esm/typings/src/llm-providers/_multiple/MultipleLlmExecutionTools.d.ts +6 -2
- package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +1 -1
- package/esm/typings/src/llm-providers/ollama/OllamaExecutionTools.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +1 -1
- package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +1 -0
- package/esm/typings/src/types/Message.d.ts +49 -0
- package/esm/typings/src/types/ModelRequirements.d.ts +38 -14
- package/esm/typings/src/types/typeAliases.d.ts +23 -1
- package/esm/typings/src/utils/color/utils/colorToDataUrl.d.ts +2 -1
- package/esm/typings/src/utils/environment/$detectRuntimeEnvironment.d.ts +4 -4
- package/esm/typings/src/utils/environment/$isRunningInBrowser.d.ts +1 -1
- package/esm/typings/src/utils/environment/$isRunningInJest.d.ts +1 -1
- package/esm/typings/src/utils/environment/$isRunningInNode.d.ts +1 -1
- package/esm/typings/src/utils/environment/$isRunningInWebWorker.d.ts +1 -1
- package/esm/typings/src/utils/markdown/extractAllBlocksFromMarkdown.d.ts +2 -2
- package/esm/typings/src/utils/markdown/extractOneBlockFromMarkdown.d.ts +2 -2
- package/esm/typings/src/utils/random/$randomBase58.d.ts +12 -0
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +4018 -3865
- package/umd/index.umd.js.map +1 -1
- package/apps/agents-server/package-lock.json +0 -27
- package/apps/agents-server/public/fonts/download-font.js +0 -22
- package/apps/agents-server/src/components/PrintButton/PrintButton.tsx +0 -18
- package/esm/typings/src/book-2.0/utils/generateGravatarUrl.d.ts +0 -10
|
@@ -46,10 +46,10 @@ function getTextPreview(value: unknown, maxLength = 160): string {
|
|
|
46
46
|
typeof value === 'string'
|
|
47
47
|
? value
|
|
48
48
|
: Array.isArray(value)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
? value.map((part) => String(part)).join(' ')
|
|
50
|
+
: typeof value === 'object'
|
|
51
|
+
? JSON.stringify(value)
|
|
52
|
+
: String(value);
|
|
53
53
|
|
|
54
54
|
return text.length > maxLength ? `${text.slice(0, maxLength)}…` : text;
|
|
55
55
|
}
|
|
@@ -205,8 +205,8 @@ export function ChatFeedbackClient({ initialAgentName }: ChatFeedbackClientProps
|
|
|
205
205
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
206
206
|
const thread = (row.chatThread as unknown as any[]).map((msg) => ({
|
|
207
207
|
...msg,
|
|
208
|
-
date: msg.date ? new Date(msg.date) :
|
|
209
|
-
}))
|
|
208
|
+
date: msg.date ? new Date(msg.date) : msg.createdAt ? new Date(msg.createdAt) : undefined,
|
|
209
|
+
})) satisfies Array<ChatMessage>;
|
|
210
210
|
setSelectedThread(thread);
|
|
211
211
|
} catch (e) {
|
|
212
212
|
console.error('Failed to parse chat thread', e);
|
|
@@ -301,292 +301,234 @@ export function ChatFeedbackClient({ initialAgentName }: ChatFeedbackClientProps
|
|
|
301
301
|
</a>
|
|
302
302
|
</div>
|
|
303
303
|
<div>
|
|
304
|
-
<div className="text-xl font-semibold text-gray-900">
|
|
305
|
-
|
|
306
|
-
</div>
|
|
307
|
-
<div className="text-xs uppercase tracking-wide text-gray-400">
|
|
308
|
-
Total feedback entries
|
|
309
|
-
</div>
|
|
304
|
+
<div className="text-xl font-semibold text-gray-900">{total.toLocaleString()}</div>
|
|
305
|
+
<div className="text-xs uppercase tracking-wide text-gray-400">Total feedback entries</div>
|
|
310
306
|
</div>
|
|
311
307
|
</div>
|
|
312
308
|
</div>
|
|
313
309
|
<Card>
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
310
|
+
<div className="flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
|
|
311
|
+
<form onSubmit={handleSearchSubmit} className="flex flex-col gap-2 md:flex-row md:items-end">
|
|
312
|
+
<div className="flex flex-col gap-1">
|
|
313
|
+
<label htmlFor="search" className="text-sm font-medium text-gray-700">
|
|
314
|
+
Search
|
|
315
|
+
</label>
|
|
316
|
+
<input
|
|
317
|
+
id="search"
|
|
318
|
+
type="text"
|
|
319
|
+
value={searchInput}
|
|
320
|
+
onChange={(event) => setSearchInput(event.target.value)}
|
|
321
|
+
placeholder="Search by agent, URL, IP, rating or note"
|
|
322
|
+
className="w-full md:w-72 px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
323
|
+
/>
|
|
324
|
+
</div>
|
|
325
|
+
<button
|
|
326
|
+
type="submit"
|
|
327
|
+
className="mt-2 inline-flex items-center justify-center rounded-md bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 md:mt-0 md:ml-3"
|
|
328
|
+
>
|
|
329
|
+
Apply
|
|
330
|
+
</button>
|
|
331
|
+
</form>
|
|
332
|
+
|
|
333
|
+
<div className="flex flex-col gap-2 md:flex-row md:items-end md:gap-4">
|
|
334
|
+
<div className="flex flex-col gap-1">
|
|
335
|
+
<label htmlFor="agentFilter" className="text-sm font-medium text-gray-700">
|
|
336
|
+
Agent filter
|
|
337
|
+
</label>
|
|
338
|
+
<select
|
|
339
|
+
id="agentFilter"
|
|
340
|
+
value={agentName}
|
|
341
|
+
onChange={handleAgentChange}
|
|
342
|
+
className="w-full md:w-64 px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
332
343
|
>
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
</label>
|
|
342
|
-
<select
|
|
343
|
-
id="agentFilter"
|
|
344
|
-
value={agentName}
|
|
345
|
-
onChange={handleAgentChange}
|
|
346
|
-
className="w-full md:w-64 px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
347
|
-
>
|
|
348
|
-
<option value="">All agents</option>
|
|
349
|
-
{agents.map((agent) => (
|
|
350
|
-
<option key={agent.agentName} value={agent.agentName}>
|
|
351
|
-
{agent.fullname || agent.agentName}
|
|
352
|
-
</option>
|
|
353
|
-
))}
|
|
354
|
-
</select>
|
|
355
|
-
{agentsLoading && (
|
|
356
|
-
<span className="text-xs text-gray-400">Loading agents…</span>
|
|
357
|
-
)}
|
|
358
|
-
</div>
|
|
359
|
-
|
|
360
|
-
<div className="flex flex-col gap-1">
|
|
361
|
-
<label htmlFor="pageSize" className="text-sm font-medium text-gray-700">
|
|
362
|
-
Page size
|
|
363
|
-
</label>
|
|
364
|
-
<select
|
|
365
|
-
id="pageSize"
|
|
366
|
-
value={pageSize}
|
|
367
|
-
onChange={handlePageSizeChange}
|
|
368
|
-
className="w-28 px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
369
|
-
>
|
|
370
|
-
<option value={10}>10</option>
|
|
371
|
-
<option value={20}>20</option>
|
|
372
|
-
<option value={50}>50</option>
|
|
373
|
-
<option value={100}>100</option>
|
|
374
|
-
</select>
|
|
375
|
-
</div>
|
|
344
|
+
<option value="">All agents</option>
|
|
345
|
+
{agents.map((agent) => (
|
|
346
|
+
<option key={agent.agentName} value={agent.agentName}>
|
|
347
|
+
{agent.fullname || agent.agentName}
|
|
348
|
+
</option>
|
|
349
|
+
))}
|
|
350
|
+
</select>
|
|
351
|
+
{agentsLoading && <span className="text-xs text-gray-400">Loading agents…</span>}
|
|
376
352
|
</div>
|
|
377
|
-
</div>
|
|
378
353
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
className="inline-flex items-center justify-center rounded-md border border-red-300 bg-white px-3 py-1.5 text-xs font-medium text-red-700 hover:bg-red-50"
|
|
354
|
+
<div className="flex flex-col gap-1">
|
|
355
|
+
<label htmlFor="pageSize" className="text-sm font-medium text-gray-700">
|
|
356
|
+
Page size
|
|
357
|
+
</label>
|
|
358
|
+
<select
|
|
359
|
+
id="pageSize"
|
|
360
|
+
value={pageSize}
|
|
361
|
+
onChange={handlePageSizeChange}
|
|
362
|
+
className="w-28 px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
389
363
|
>
|
|
390
|
-
|
|
391
|
-
|
|
364
|
+
<option value={10}>10</option>
|
|
365
|
+
<option value={20}>20</option>
|
|
366
|
+
<option value={50}>50</option>
|
|
367
|
+
<option value={100}>100</option>
|
|
368
|
+
</select>
|
|
392
369
|
</div>
|
|
393
|
-
|
|
394
|
-
</
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
|
|
373
|
+
{agentName && (
|
|
374
|
+
<div className="mt-4 flex items-center justify-between gap-4 rounded-md border border-amber-200 bg-amber-50 px-4 py-3">
|
|
375
|
+
<p className="text-sm text-amber-800">
|
|
376
|
+
Showing feedback for agent <span className="font-semibold break-all">{agentName}</span>.
|
|
377
|
+
</p>
|
|
378
|
+
<button
|
|
379
|
+
type="button"
|
|
380
|
+
onClick={handleClearAgentFeedback}
|
|
381
|
+
className="inline-flex items-center justify-center rounded-md border border-red-300 bg-white px-3 py-1.5 text-xs font-medium text-red-700 hover:bg-red-50"
|
|
382
|
+
>
|
|
383
|
+
Clear feedback for this agent
|
|
384
|
+
</button>
|
|
385
|
+
</div>
|
|
386
|
+
)}
|
|
387
|
+
</Card>
|
|
395
388
|
|
|
396
389
|
<Card>
|
|
397
390
|
<div className="flex items-center justify-between mb-4">
|
|
398
|
-
<h2 className="text-lg font-medium text-gray-900">
|
|
399
|
-
Feedback entries ({total})
|
|
400
|
-
</h2>
|
|
391
|
+
<h2 className="text-lg font-medium text-gray-900">Feedback entries ({total})</h2>
|
|
401
392
|
</div>
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
393
|
+
{error && <div className="mb-4 rounded-md bg-red-50 px-4 py-3 text-sm text-red-800">{error}</div>}
|
|
394
|
+
|
|
395
|
+
{loading && items.length === 0 ? (
|
|
396
|
+
<div className="py-8 text-center text-gray-500">Loading feedback…</div>
|
|
397
|
+
) : items.length === 0 ? (
|
|
398
|
+
<div className="py-8 text-center text-gray-500">No feedback found.</div>
|
|
399
|
+
) : (
|
|
400
|
+
<div className="overflow-x-auto">
|
|
401
|
+
<table className="min-w-full divide-y divide-gray-200 text-sm">
|
|
402
|
+
<thead className="bg-gray-50">
|
|
403
|
+
<tr>
|
|
404
|
+
<th className="px-4 py-3 text-left font-medium text-gray-500">
|
|
405
|
+
<button
|
|
406
|
+
type="button"
|
|
407
|
+
onClick={() => handleSortChange('createdAt')}
|
|
408
|
+
className="inline-flex items-center gap-1"
|
|
409
|
+
>
|
|
410
|
+
Time
|
|
411
|
+
{isSortedBy('createdAt') && <span>{sortOrder === 'asc' ? '▲' : '▼'}</span>}
|
|
412
|
+
</button>
|
|
413
|
+
</th>
|
|
414
|
+
<th className="px-4 py-3 text-left font-medium text-gray-500">
|
|
415
|
+
<button
|
|
416
|
+
type="button"
|
|
417
|
+
onClick={() => handleSortChange('agentName')}
|
|
418
|
+
className="inline-flex items-center gap-1"
|
|
419
|
+
>
|
|
420
|
+
Agent
|
|
421
|
+
{isSortedBy('agentName') && <span>{sortOrder === 'asc' ? '▲' : '▼'}</span>}
|
|
422
|
+
</button>
|
|
423
|
+
</th>
|
|
424
|
+
<th className="px-4 py-3 text-left font-medium text-gray-500">Rating</th>
|
|
425
|
+
<th className="px-4 py-3 text-left font-medium text-gray-500">Text rating</th>
|
|
426
|
+
<th className="px-4 py-3 text-left font-medium text-gray-500">User note</th>
|
|
427
|
+
<th className="px-4 py-3 text-left font-medium text-gray-500">Expected answer</th>
|
|
428
|
+
<th className="px-4 py-3 text-left font-medium text-gray-500">URL</th>
|
|
429
|
+
<th className="px-4 py-3 text-left font-medium text-gray-500">IP</th>
|
|
430
|
+
<th className="px-4 py-3 text-left font-medium text-gray-500">Language</th>
|
|
431
|
+
<th className="px-4 py-3 text-left font-medium text-gray-500">Platform</th>
|
|
432
|
+
<th className="px-4 py-3 text-right font-medium text-gray-500">Actions</th>
|
|
433
|
+
</tr>
|
|
434
|
+
</thead>
|
|
435
|
+
<tbody className="divide-y divide-gray-200 bg-white">
|
|
436
|
+
{items.map((row) => (
|
|
437
|
+
<tr key={row.id}>
|
|
438
|
+
<td className="whitespace-nowrap px-4 py-3 text-gray-700">
|
|
439
|
+
{formatDate(row.createdAt)}
|
|
440
|
+
</td>
|
|
441
|
+
<td className="whitespace-nowrap px-4 py-3 text-gray-700">{row.agentName}</td>
|
|
442
|
+
<td className="whitespace-nowrap px-4 py-3 text-gray-700">
|
|
443
|
+
{row.rating || '-'}
|
|
444
|
+
</td>
|
|
445
|
+
<td className="max-w-xs px-4 py-3 text-gray-700">
|
|
446
|
+
<div className="max-h-24 overflow-hidden overflow-ellipsis text-xs leading-snug">
|
|
447
|
+
{row.textRating ? getTextPreview(row.textRating) : '-'}
|
|
448
|
+
</div>
|
|
449
|
+
</td>
|
|
450
|
+
<td className="max-w-xs px-4 py-3 text-gray-700">
|
|
451
|
+
<div className="max-h-24 overflow-hidden overflow-ellipsis text-xs leading-snug">
|
|
452
|
+
{row.userNote ? getTextPreview(row.userNote) : '-'}
|
|
453
|
+
</div>
|
|
454
|
+
</td>
|
|
455
|
+
<td className="max-w-xs px-4 py-3 text-gray-700">
|
|
456
|
+
<div className="max-h-24 overflow-hidden overflow-ellipsis text-xs leading-snug">
|
|
457
|
+
{row.expectedAnswer ? getTextPreview(row.expectedAnswer) : '-'}
|
|
458
|
+
</div>
|
|
459
|
+
</td>
|
|
460
|
+
<td className="max-w-xs px-4 py-3 text-gray-500">
|
|
461
|
+
<div className="truncate text-xs">{row.url || '-'}</div>
|
|
462
|
+
</td>
|
|
463
|
+
<td className="whitespace-nowrap px-4 py-3 text-gray-500">{row.ip || '-'}</td>
|
|
464
|
+
<td className="whitespace-nowrap px-4 py-3 text-gray-500">
|
|
465
|
+
{row.language || '-'}
|
|
466
|
+
</td>
|
|
467
|
+
<td className="max-w-xs px-4 py-3 text-gray-500">
|
|
468
|
+
<div className="truncate text-xs">{row.platform || '-'}</div>
|
|
469
|
+
</td>
|
|
470
|
+
<td className="whitespace-nowrap px-4 py-3 text-right text-xs font-medium space-x-2">
|
|
471
|
+
{row.chatThread && (
|
|
472
|
+
<button
|
|
473
|
+
type="button"
|
|
474
|
+
onClick={() => handleViewChat(row)}
|
|
475
|
+
className="text-blue-600 hover:text-blue-800"
|
|
476
|
+
>
|
|
477
|
+
View Chat
|
|
478
|
+
</button>
|
|
479
|
+
)}
|
|
430
480
|
<button
|
|
431
481
|
type="button"
|
|
432
|
-
onClick={() =>
|
|
433
|
-
className="
|
|
482
|
+
onClick={() => handleDeleteRow(row)}
|
|
483
|
+
className="text-red-600 hover:text-red-800"
|
|
434
484
|
>
|
|
435
|
-
|
|
436
|
-
{isSortedBy('agentName') && (
|
|
437
|
-
<span>{sortOrder === 'asc' ? '▲' : '▼'}</span>
|
|
438
|
-
)}
|
|
485
|
+
Delete
|
|
439
486
|
</button>
|
|
440
|
-
</
|
|
441
|
-
<th className="px-4 py-3 text-left font-medium text-gray-500">
|
|
442
|
-
Rating
|
|
443
|
-
</th>
|
|
444
|
-
<th className="px-4 py-3 text-left font-medium text-gray-500">
|
|
445
|
-
Text rating
|
|
446
|
-
</th>
|
|
447
|
-
<th className="px-4 py-3 text-left font-medium text-gray-500">
|
|
448
|
-
User note
|
|
449
|
-
</th>
|
|
450
|
-
<th className="px-4 py-3 text-left font-medium text-gray-500">
|
|
451
|
-
Expected answer
|
|
452
|
-
</th>
|
|
453
|
-
<th className="px-4 py-3 text-left font-medium text-gray-500">
|
|
454
|
-
URL
|
|
455
|
-
</th>
|
|
456
|
-
<th className="px-4 py-3 text-left font-medium text-gray-500">
|
|
457
|
-
IP
|
|
458
|
-
</th>
|
|
459
|
-
<th className="px-4 py-3 text-left font-medium text-gray-500">
|
|
460
|
-
Language
|
|
461
|
-
</th>
|
|
462
|
-
<th className="px-4 py-3 text-left font-medium text-gray-500">
|
|
463
|
-
Platform
|
|
464
|
-
</th>
|
|
465
|
-
<th className="px-4 py-3 text-right font-medium text-gray-500">
|
|
466
|
-
Actions
|
|
467
|
-
</th>
|
|
487
|
+
</td>
|
|
468
488
|
</tr>
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
<td className="max-w-xs px-4 py-3 text-gray-700">
|
|
488
|
-
<div className="max-h-24 overflow-hidden overflow-ellipsis text-xs leading-snug">
|
|
489
|
-
{row.userNote ? getTextPreview(row.userNote) : '-'}
|
|
490
|
-
</div>
|
|
491
|
-
</td>
|
|
492
|
-
<td className="max-w-xs px-4 py-3 text-gray-700">
|
|
493
|
-
<div className="max-h-24 overflow-hidden overflow-ellipsis text-xs leading-snug">
|
|
494
|
-
{row.expectedAnswer ? getTextPreview(row.expectedAnswer) : '-'}
|
|
495
|
-
</div>
|
|
496
|
-
</td>
|
|
497
|
-
<td className="max-w-xs px-4 py-3 text-gray-500">
|
|
498
|
-
<div className="truncate text-xs">
|
|
499
|
-
{row.url || '-'}
|
|
500
|
-
</div>
|
|
501
|
-
</td>
|
|
502
|
-
<td className="whitespace-nowrap px-4 py-3 text-gray-500">
|
|
503
|
-
{row.ip || '-'}
|
|
504
|
-
</td>
|
|
505
|
-
<td className="whitespace-nowrap px-4 py-3 text-gray-500">
|
|
506
|
-
{row.language || '-'}
|
|
507
|
-
</td>
|
|
508
|
-
<td className="max-w-xs px-4 py-3 text-gray-500">
|
|
509
|
-
<div className="truncate text-xs">
|
|
510
|
-
{row.platform || '-'}
|
|
511
|
-
</div>
|
|
512
|
-
</td>
|
|
513
|
-
<td className="whitespace-nowrap px-4 py-3 text-right text-xs font-medium space-x-2">
|
|
514
|
-
{row.chatThread && (
|
|
515
|
-
<button
|
|
516
|
-
type="button"
|
|
517
|
-
onClick={() => handleViewChat(row)}
|
|
518
|
-
className="text-blue-600 hover:text-blue-800"
|
|
519
|
-
>
|
|
520
|
-
View Chat
|
|
521
|
-
</button>
|
|
522
|
-
)}
|
|
523
|
-
<button
|
|
524
|
-
type="button"
|
|
525
|
-
onClick={() => handleDeleteRow(row)}
|
|
526
|
-
className="text-red-600 hover:text-red-800"
|
|
527
|
-
>
|
|
528
|
-
Delete
|
|
529
|
-
</button>
|
|
530
|
-
</td>
|
|
531
|
-
</tr>
|
|
532
|
-
))}
|
|
533
|
-
</tbody>
|
|
534
|
-
</table>
|
|
535
|
-
</div>
|
|
536
|
-
)}
|
|
537
|
-
|
|
538
|
-
<div className="mt-4 flex flex-col items-center justify-between gap-3 border-t border-gray-100 pt-4 text-xs text-gray-600 md:flex-row">
|
|
539
|
-
<div>
|
|
540
|
-
{total > 0 ? (
|
|
541
|
-
<>
|
|
542
|
-
Showing{' '}
|
|
543
|
-
<span className="font-semibold">
|
|
544
|
-
{Math.min((page - 1) * pageSize + 1, total)}
|
|
545
|
-
</span>{' '}
|
|
546
|
-
–{' '}
|
|
547
|
-
<span className="font-semibold">
|
|
548
|
-
{Math.min(page * pageSize, total)}
|
|
549
|
-
</span>{' '}
|
|
550
|
-
of{' '}
|
|
551
|
-
<span className="font-semibold">
|
|
552
|
-
{total}
|
|
553
|
-
</span>{' '}
|
|
554
|
-
feedback entries
|
|
555
|
-
</>
|
|
556
|
-
) : (
|
|
557
|
-
'No feedback'
|
|
558
|
-
)}
|
|
559
|
-
</div>
|
|
560
|
-
<div className="flex items-center gap-2">
|
|
561
|
-
<button
|
|
562
|
-
type="button"
|
|
563
|
-
onClick={() => setPage((prev) => Math.max(1, prev - 1))}
|
|
564
|
-
disabled={page <= 1}
|
|
565
|
-
className="inline-flex items-center justify-center rounded-md border border-gray-300 px-2 py-1 text-xs font-medium text-gray-700 disabled:cursor-not-allowed disabled:opacity-50"
|
|
566
|
-
>
|
|
567
|
-
Previous
|
|
568
|
-
</button>
|
|
569
|
-
<span>
|
|
570
|
-
Page{' '}
|
|
571
|
-
<span className="font-semibold">
|
|
572
|
-
{page}
|
|
573
|
-
</span>{' '}
|
|
574
|
-
of{' '}
|
|
575
|
-
<span className="font-semibold">
|
|
576
|
-
{totalPages}
|
|
577
|
-
</span>
|
|
578
|
-
</span>
|
|
579
|
-
<button
|
|
580
|
-
type="button"
|
|
581
|
-
onClick={() => setPage((prev) => Math.min(totalPages, prev + 1))}
|
|
582
|
-
disabled={page >= totalPages}
|
|
583
|
-
className="inline-flex items-center justify-center rounded-md border border-gray-300 px-2 py-1 text-xs font-medium text-gray-700 disabled:cursor-not-allowed disabled:opacity-50"
|
|
584
|
-
>
|
|
585
|
-
Next
|
|
586
|
-
</button>
|
|
587
|
-
</div>
|
|
489
|
+
))}
|
|
490
|
+
</tbody>
|
|
491
|
+
</table>
|
|
492
|
+
</div>
|
|
493
|
+
)}
|
|
494
|
+
|
|
495
|
+
<div className="mt-4 flex flex-col items-center justify-between gap-3 border-t border-gray-100 pt-4 text-xs text-gray-600 md:flex-row">
|
|
496
|
+
<div>
|
|
497
|
+
{total > 0 ? (
|
|
498
|
+
<>
|
|
499
|
+
Showing{' '}
|
|
500
|
+
<span className="font-semibold">{Math.min((page - 1) * pageSize + 1, total)}</span> –{' '}
|
|
501
|
+
<span className="font-semibold">{Math.min(page * pageSize, total)}</span> of{' '}
|
|
502
|
+
<span className="font-semibold">{total}</span> feedback entries
|
|
503
|
+
</>
|
|
504
|
+
) : (
|
|
505
|
+
'No feedback'
|
|
506
|
+
)}
|
|
588
507
|
</div>
|
|
589
|
-
|
|
508
|
+
<div className="flex items-center gap-2">
|
|
509
|
+
<button
|
|
510
|
+
type="button"
|
|
511
|
+
onClick={() => setPage((prev) => Math.max(1, prev - 1))}
|
|
512
|
+
disabled={page <= 1}
|
|
513
|
+
className="inline-flex items-center justify-center rounded-md border border-gray-300 px-2 py-1 text-xs font-medium text-gray-700 disabled:cursor-not-allowed disabled:opacity-50"
|
|
514
|
+
>
|
|
515
|
+
Previous
|
|
516
|
+
</button>
|
|
517
|
+
<span>
|
|
518
|
+
Page <span className="font-semibold">{page}</span> of{' '}
|
|
519
|
+
<span className="font-semibold">{totalPages}</span>
|
|
520
|
+
</span>
|
|
521
|
+
<button
|
|
522
|
+
type="button"
|
|
523
|
+
onClick={() => setPage((prev) => Math.min(totalPages, prev + 1))}
|
|
524
|
+
disabled={page >= totalPages}
|
|
525
|
+
className="inline-flex items-center justify-center rounded-md border border-gray-300 px-2 py-1 text-xs font-medium text-gray-700 disabled:cursor-not-allowed disabled:opacity-50"
|
|
526
|
+
>
|
|
527
|
+
Next
|
|
528
|
+
</button>
|
|
529
|
+
</div>
|
|
530
|
+
</div>
|
|
531
|
+
</Card>
|
|
590
532
|
|
|
591
533
|
{selectedThread && (
|
|
592
534
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50 p-4">
|
|
@@ -599,7 +541,12 @@ export function ChatFeedbackClient({ initialAgentName }: ChatFeedbackClientProps
|
|
|
599
541
|
>
|
|
600
542
|
<span className="sr-only">Close</span>
|
|
601
543
|
<svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
602
|
-
<path
|
|
544
|
+
<path
|
|
545
|
+
strokeLinecap="round"
|
|
546
|
+
strokeLinejoin="round"
|
|
547
|
+
strokeWidth={2}
|
|
548
|
+
d="M6 18L18 6M6 6l12 12"
|
|
549
|
+
/>
|
|
603
550
|
</svg>
|
|
604
551
|
</button>
|
|
605
552
|
</div>
|