@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
|
@@ -6,7 +6,7 @@ import { NextResponse } from 'next/server';
|
|
|
6
6
|
export const dynamic = 'force-dynamic';
|
|
7
7
|
|
|
8
8
|
export async function GET() {
|
|
9
|
-
const txt = generateHumansTxt();
|
|
9
|
+
const txt = await generateHumansTxt();
|
|
10
10
|
return new NextResponse(txt, {
|
|
11
11
|
headers: {
|
|
12
12
|
'Content-Type': 'text/plain',
|
|
@@ -83,31 +83,36 @@ export default async function RootLayout({
|
|
|
83
83
|
console.error('Failed to parse FOOTER_LINKS', error);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
// Fetch federated servers and add to footerLinks
|
|
86
|
+
// Fetch federated servers and add to footerLinks (only if user is authenticated or SHOW_FEDERATED_SERVERS_PUBLICLY is true)
|
|
87
87
|
let federatedServers: Array<{ url: string; title: string; logoUrl: string | null }> = [];
|
|
88
88
|
try {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
89
|
+
const showFederatedServersPublicly = ((await getMetadata('SHOW_FEDERATED_SERVERS_PUBLICLY')) || 'false') === 'true';
|
|
90
|
+
|
|
91
|
+
// Only show federated servers in footer if user is authenticated or if SHOW_FEDERATED_SERVERS_PUBLICLY is true
|
|
92
|
+
if (currentUser || showFederatedServersPublicly) {
|
|
93
|
+
const federatedServersRaw = await getFederatedServersFromMetadata();
|
|
94
|
+
federatedServers = await Promise.all(
|
|
95
|
+
federatedServersRaw.map(async (url: string) => {
|
|
96
|
+
let logoUrl: string | null = null;
|
|
97
|
+
try {
|
|
98
|
+
// Try to fetch logo from metadata endpoint if available
|
|
99
|
+
const res = await fetch(`${url}/api/metadata`);
|
|
100
|
+
if (res.ok) {
|
|
101
|
+
const meta = await res.json();
|
|
102
|
+
logoUrl = meta.SERVER_LOGO_URL || null;
|
|
103
|
+
}
|
|
104
|
+
} catch {
|
|
105
|
+
logoUrl = null;
|
|
99
106
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
);
|
|
110
|
-
footerLinks = [...footerLinks, ...federatedServers];
|
|
107
|
+
return {
|
|
108
|
+
title: `Federated: ${new URL(url).hostname}`,
|
|
109
|
+
url,
|
|
110
|
+
logoUrl,
|
|
111
|
+
};
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
footerLinks = [...footerLinks, ...federatedServers];
|
|
115
|
+
}
|
|
111
116
|
} catch (error) {
|
|
112
117
|
console.error('Failed to fetch federated servers for footer', error);
|
|
113
118
|
}
|
|
@@ -12,10 +12,13 @@ import { Section } from '../components/Homepage/Section';
|
|
|
12
12
|
import { TechInfoCard } from '../components/Homepage/TechInfoCard';
|
|
13
13
|
import { UsersList } from '../components/UsersList/UsersList';
|
|
14
14
|
import VercelDeploymentCard from '../components/VercelDeploymentCard/VercelDeploymentCard';
|
|
15
|
+
import { $getTableName } from '../database/$getTableName';
|
|
16
|
+
import { $provideSupabaseForServer } from '../database/$provideSupabaseForServer';
|
|
15
17
|
import { getLongRunningTask } from '../deamons/longRunningTask';
|
|
16
18
|
import { $provideAgentCollectionForServer } from '../tools/$provideAgentCollectionForServer';
|
|
17
19
|
import { $provideExecutionToolsForServer } from '../tools/$provideExecutionToolsForServer';
|
|
18
20
|
import { $provideServer } from '../tools/$provideServer';
|
|
21
|
+
import { getCurrentUser } from '../utils/getCurrentUser';
|
|
19
22
|
import { isUserAdmin } from '../utils/isUserAdmin';
|
|
20
23
|
|
|
21
24
|
// Add calendar formats that include seconds
|
|
@@ -31,10 +34,57 @@ const calendarWithSeconds = {
|
|
|
31
34
|
export default async function HomePage() {
|
|
32
35
|
$sideEffect(/* Note: [🐶] This will ensure dynamic rendering of page and avoid Next.js pre-render */ headers());
|
|
33
36
|
|
|
37
|
+
const { publicUrl } = await $provideServer();
|
|
38
|
+
|
|
39
|
+
const currentUser = await getCurrentUser();
|
|
34
40
|
const isAdmin = await isUserAdmin(); /* <- TODO: [👹] Here should be user permissions */
|
|
35
41
|
|
|
36
42
|
const collection = await $provideAgentCollectionForServer();
|
|
37
|
-
const
|
|
43
|
+
const allAgents = await collection.listAgents();
|
|
44
|
+
|
|
45
|
+
// Filter agents based on visibility and user authentication
|
|
46
|
+
const supabase = $provideSupabaseForServer();
|
|
47
|
+
// const { tablePrefix } = await $provideServer();
|
|
48
|
+
|
|
49
|
+
// Get visibility for all agents
|
|
50
|
+
const visibilityResult = await supabase
|
|
51
|
+
.from(await $getTableName(`Agent`))
|
|
52
|
+
.select('agentName, visibility')
|
|
53
|
+
.is('deletedAt', null);
|
|
54
|
+
|
|
55
|
+
let agents: typeof allAgents;
|
|
56
|
+
if (visibilityResult.error) {
|
|
57
|
+
console.error('Error fetching agent visibility:', visibilityResult.error);
|
|
58
|
+
// Fallback to showing all agents if visibility fetch fails
|
|
59
|
+
agents = allAgents;
|
|
60
|
+
} else {
|
|
61
|
+
const visibilityMap = new Map(
|
|
62
|
+
visibilityResult.data.map((item: { agentName: string; visibility: 'PUBLIC' | 'PRIVATE' }) => [
|
|
63
|
+
item.agentName,
|
|
64
|
+
item.visibility,
|
|
65
|
+
]),
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Filter agents based on user authentication and visibility
|
|
69
|
+
agents = allAgents
|
|
70
|
+
.filter((agent) => {
|
|
71
|
+
const visibility = visibilityMap.get(agent.agentName);
|
|
72
|
+
if (!visibility) return false; // If no visibility info, hide the agent
|
|
73
|
+
|
|
74
|
+
// Admins can see all agents
|
|
75
|
+
if (currentUser?.isAdmin) return true;
|
|
76
|
+
|
|
77
|
+
// Authenticated users can see PUBLIC and PRIVATE agents
|
|
78
|
+
if (currentUser) return true;
|
|
79
|
+
|
|
80
|
+
// Unauthenticated users can only see PUBLIC agents
|
|
81
|
+
return visibility === 'PUBLIC';
|
|
82
|
+
})
|
|
83
|
+
.map((agent) => ({
|
|
84
|
+
...agent,
|
|
85
|
+
visibility: visibilityMap.get(agent.agentName) as 'PUBLIC' | 'PRIVATE',
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
38
88
|
|
|
39
89
|
const longRunningTask = getLongRunningTask();
|
|
40
90
|
|
|
@@ -46,15 +96,13 @@ export default async function HomePage() {
|
|
|
46
96
|
return (
|
|
47
97
|
<div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-purple-50">
|
|
48
98
|
<div className="container mx-auto px-4 py-16">
|
|
49
|
-
<AgentsList agents={[...agents]} isAdmin={isAdmin} />
|
|
99
|
+
<AgentsList agents={[...agents]} isAdmin={isAdmin} publicUrl={publicUrl} />
|
|
50
100
|
|
|
51
|
-
<ExternalAgentsSectionClient />
|
|
101
|
+
<ExternalAgentsSectionClient publicUrl={publicUrl} />
|
|
52
102
|
|
|
53
103
|
{isAdmin && <UsersList allowCreate={false} />}
|
|
54
104
|
|
|
55
|
-
{isAdmin &&
|
|
56
|
-
<ModelsSection models={models} maxVisible={11} showViewAllLink />
|
|
57
|
-
)}
|
|
105
|
+
{isAdmin && <ModelsSection models={models} maxVisible={11} showViewAllLink />}
|
|
58
106
|
|
|
59
107
|
{isAdmin && (
|
|
60
108
|
<>
|
|
@@ -2,25 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
4
4
|
import { revalidatePath } from 'next/cache';
|
|
5
|
+
import { isUserAdmin } from '../../utils/isUserAdmin';
|
|
5
6
|
|
|
6
7
|
export async function restoreDeletedAgent(agentName: string) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// Find the latest history item for this agent
|
|
10
|
-
const history = await collection.listAgentHistory(agentName);
|
|
11
|
-
|
|
12
|
-
if (history.length === 0) {
|
|
13
|
-
throw new Error(`No history found for agent ${agentName}`);
|
|
8
|
+
if (!(await isUserAdmin())) {
|
|
9
|
+
throw new Error('You are not authorized to restore agents');
|
|
14
10
|
}
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
|
|
12
|
+
const collection = await $provideAgentCollectionForServer();
|
|
13
|
+
|
|
14
|
+
await collection.restoreAgent(agentName);
|
|
15
|
+
|
|
16
|
+
revalidatePath('/recycle-bin');
|
|
17
|
+
revalidatePath(`/agents/${agentName}`);
|
|
18
|
+
revalidatePath('/');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function deleteAgent(agentName: string) {
|
|
22
|
+
if (!(await isUserAdmin())) {
|
|
23
|
+
throw new Error('You are not authorized to delete agents');
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
await
|
|
23
|
-
|
|
26
|
+
const collection = await $provideAgentCollectionForServer();
|
|
27
|
+
|
|
28
|
+
await collection.deleteAgent(agentName);
|
|
29
|
+
|
|
24
30
|
revalidatePath('/recycle-bin');
|
|
25
31
|
revalidatePath(`/agents/${agentName}`);
|
|
26
32
|
revalidatePath('/');
|
|
@@ -1,58 +1,44 @@
|
|
|
1
1
|
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
2
|
+
import { $provideServer } from '@/src/tools/$provideServer';
|
|
2
3
|
import { TrashIcon } from 'lucide-react';
|
|
3
4
|
import Link from 'next/link';
|
|
4
|
-
import {
|
|
5
|
+
import { DeletedAgentsList } from '../../components/Homepage/DeletedAgentsList';
|
|
6
|
+
import { isUserAdmin } from '../../utils/isUserAdmin';
|
|
5
7
|
|
|
6
8
|
export const metadata = {
|
|
7
9
|
title: 'Recycle Bin',
|
|
8
10
|
};
|
|
9
11
|
|
|
10
12
|
export default async function RecycleBinPage() {
|
|
13
|
+
const { publicUrl } = await $provideServer();
|
|
11
14
|
const collection = await $provideAgentCollectionForServer();
|
|
12
15
|
const deletedAgents = await collection.listDeletedAgents();
|
|
16
|
+
const isAdmin = await isUserAdmin();
|
|
13
17
|
|
|
14
18
|
return (
|
|
15
|
-
<div className="
|
|
16
|
-
<
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
<div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-purple-50">
|
|
20
|
+
<div className="container mx-auto px-4 py-16">
|
|
21
|
+
<header className="flex items-center gap-4 mb-8">
|
|
22
|
+
<div className="bg-red-100 p-3 rounded-full">
|
|
23
|
+
<TrashIcon className="w-8 h-8 text-red-600" />
|
|
24
|
+
</div>
|
|
25
|
+
<div>
|
|
26
|
+
<h1 className="text-3xl font-bold text-gray-900">Recycle Bin</h1>
|
|
27
|
+
<p className="text-gray-600">Restore deleted agents from here.</p>
|
|
28
|
+
</div>
|
|
29
|
+
</header>
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
key={agentName}
|
|
38
|
-
className="bg-white p-4 rounded-lg shadow-sm border border-gray-200 flex items-center justify-between hover:shadow-md transition-shadow"
|
|
39
|
-
>
|
|
40
|
-
<div className="flex items-center gap-3">
|
|
41
|
-
<div className="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center text-gray-500 font-bold text-lg">
|
|
42
|
-
{agentName.charAt(0).toUpperCase()}
|
|
43
|
-
</div>
|
|
44
|
-
<div>
|
|
45
|
-
<h3 className="font-semibold text-lg text-gray-900">{agentName}</h3>
|
|
46
|
-
<p className="text-sm text-gray-500">Deleted agent</p>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
<div className="flex gap-2">
|
|
50
|
-
<RestoreAgentButton agentName={agentName} />
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
))}
|
|
54
|
-
</div>
|
|
55
|
-
)}
|
|
31
|
+
{deletedAgents.length === 0 ? (
|
|
32
|
+
<div className="text-center py-12 bg-gray-50 rounded-lg border border-dashed border-gray-300">
|
|
33
|
+
<p className="text-gray-500 text-lg">Recycle bin is empty</p>
|
|
34
|
+
<Link href="/" className="text-blue-600 hover:underline mt-2 inline-block">
|
|
35
|
+
Go back to agents
|
|
36
|
+
</Link>
|
|
37
|
+
</div>
|
|
38
|
+
) : (
|
|
39
|
+
<DeletedAgentsList agents={deletedAgents} isAdmin={isAdmin} publicUrl={publicUrl} />
|
|
40
|
+
)}
|
|
41
|
+
</div>
|
|
56
42
|
</div>
|
|
57
43
|
);
|
|
58
44
|
}
|
|
@@ -6,7 +6,7 @@ import { NextResponse } from 'next/server';
|
|
|
6
6
|
export const dynamic = 'force-dynamic';
|
|
7
7
|
|
|
8
8
|
export async function GET() {
|
|
9
|
-
const txt = generateRobotsTxt();
|
|
9
|
+
const txt = await generateRobotsTxt();
|
|
10
10
|
return new NextResponse(txt, {
|
|
11
11
|
headers: {
|
|
12
12
|
'Content-Type': 'text/plain',
|
|
@@ -6,7 +6,7 @@ import { NextResponse } from 'next/server';
|
|
|
6
6
|
export const dynamic = 'force-dynamic';
|
|
7
7
|
|
|
8
8
|
export async function GET() {
|
|
9
|
-
const txt = generateSecurityTxt();
|
|
9
|
+
const txt = await generateSecurityTxt();
|
|
10
10
|
return new NextResponse(txt, {
|
|
11
11
|
headers: {
|
|
12
12
|
'Content-Type': 'text/plain',
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
// Dynamic sitemap.xml for Agents Server
|
|
2
2
|
|
|
3
|
-
import { NEXT_PUBLIC_SITE_URL } from '@/config';
|
|
4
3
|
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
4
|
+
import { $provideServer } from '@/src/tools/$provideServer';
|
|
5
5
|
import { spaceTrim } from '@promptbook-local/utils';
|
|
6
6
|
import { NextResponse } from 'next/server';
|
|
7
7
|
|
|
8
8
|
export const dynamic = 'force-dynamic';
|
|
9
9
|
|
|
10
10
|
export async function GET() {
|
|
11
|
+
const { publicUrl } = await $provideServer();
|
|
12
|
+
|
|
11
13
|
const collection = await $provideAgentCollectionForServer();
|
|
12
14
|
|
|
13
15
|
// Assume collection.listAgents() returns an array of agent names
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
// Get base URL from environment or config
|
|
17
|
-
const baseUrl = NEXT_PUBLIC_SITE_URL?.href || process.env.PUBLIC_URL || 'https://ptbk.io';
|
|
16
|
+
const agents = await collection.listAgents();
|
|
18
17
|
|
|
19
|
-
const urls =
|
|
20
|
-
.map(
|
|
18
|
+
const urls = agents
|
|
19
|
+
.map(
|
|
20
|
+
({ permanentId, agentName }) =>
|
|
21
|
+
`<url><loc>${publicUrl.href}agents/${encodeURIComponent(permanentId || agentName)}</loc></url>`,
|
|
22
|
+
)
|
|
21
23
|
.join('\n');
|
|
22
24
|
|
|
23
25
|
const xml = spaceTrim(
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import dynamic from 'next/dynamic';
|
|
4
|
+
import 'swagger-ui-react/swagger-ui.css';
|
|
5
|
+
|
|
6
|
+
const SwaggerUI = dynamic(() => import('swagger-ui-react'), { ssr: false });
|
|
7
|
+
|
|
8
|
+
export default function SwaggerPage() {
|
|
9
|
+
return (
|
|
10
|
+
<div className="swagger-container bg-white min-h-screen">
|
|
11
|
+
<SwaggerUI url="/swagger.json" />
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { colorToDataUrl } from '@promptbook-local/color';
|
|
4
|
+
import { generatePlaceholderAgentProfileImageUrl } from '@promptbook-local/core';
|
|
5
|
+
import { AgentBasicInformation, string_agent_permanent_id } from '@promptbook-local/types';
|
|
4
6
|
import { RepeatIcon } from 'lucide-react';
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import { Color } from '../../../../../src/utils/color/Color';
|
|
8
|
-
import { darken } from '../../../../../src/utils/color/operators/darken';
|
|
9
|
-
import { lighten } from '../../../../../src/utils/color/operators/lighten';
|
|
7
|
+
import { useState } from 'react';
|
|
8
|
+
import { AgentProfileImage } from './AgentProfileImage';
|
|
10
9
|
import { AgentQrCode } from './AgentQrCode';
|
|
11
10
|
import { QrCodeModal } from './QrCodeModal';
|
|
11
|
+
import { useAgentBackground } from './useAgentBackground';
|
|
12
12
|
|
|
13
13
|
type AgentProfileProps = {
|
|
14
14
|
/**
|
|
@@ -16,6 +16,11 @@ type AgentProfileProps = {
|
|
|
16
16
|
*/
|
|
17
17
|
readonly agent: AgentBasicInformation;
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* The permanent ID of the agent
|
|
21
|
+
*/
|
|
22
|
+
readonly permanentId: string_agent_permanent_id;
|
|
23
|
+
|
|
19
24
|
/**
|
|
20
25
|
* URL of the agent page
|
|
21
26
|
*
|
|
@@ -23,6 +28,11 @@ type AgentProfileProps = {
|
|
|
23
28
|
*/
|
|
24
29
|
readonly agentUrl?: string;
|
|
25
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Base URL of the agents server
|
|
33
|
+
*/
|
|
34
|
+
readonly publicUrl: URL;
|
|
35
|
+
|
|
26
36
|
/**
|
|
27
37
|
* Email of the agent
|
|
28
38
|
*/
|
|
@@ -61,16 +71,19 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
61
71
|
agent,
|
|
62
72
|
agentUrl = '',
|
|
63
73
|
agentEmail = '',
|
|
74
|
+
publicUrl,
|
|
75
|
+
permanentId,
|
|
64
76
|
renderMenu,
|
|
65
77
|
children,
|
|
66
78
|
actions,
|
|
67
79
|
isHeadless = false,
|
|
68
80
|
className,
|
|
69
81
|
} = props;
|
|
82
|
+
|
|
70
83
|
const { meta, agentName } = agent;
|
|
71
84
|
const fullname = (meta.fullname as string) || agentName || 'Agent';
|
|
72
85
|
const personaDescription = agent.personaDescription || '';
|
|
73
|
-
const imageUrl =
|
|
86
|
+
const imageUrl = meta.image || generatePlaceholderAgentProfileImageUrl(permanentId, publicUrl);
|
|
74
87
|
|
|
75
88
|
const [isQrModalOpen, setIsQrModalOpen] = useState(false);
|
|
76
89
|
const [isFlipped, setIsFlipped] = useState(false);
|
|
@@ -81,102 +94,14 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
81
94
|
|
|
82
95
|
if (fontString) {
|
|
83
96
|
// [🧠] TODO: Properly parse font string to get family name
|
|
84
|
-
const primaryFont = fontString.split(',')[0].trim().replace(/['"]/g, '');
|
|
97
|
+
// const primaryFont = fontString.split(',')[0].trim().replace(/['"]/g, '');
|
|
85
98
|
fontStyle = {
|
|
86
99
|
fontFamily: fontString,
|
|
87
100
|
};
|
|
88
101
|
}
|
|
89
102
|
|
|
90
103
|
// Compute Colors and Background
|
|
91
|
-
const { brandColorHex, brandColorLightHex, brandColorDarkHex, backgroundImage } =
|
|
92
|
-
// [🧠] Default color should be imported constant, but for now hardcoded fallback
|
|
93
|
-
const PROMPTBOOK_COLOR_HEX = '#f15b24'; // TODO: Import PROMPTBOOK_COLOR
|
|
94
|
-
const brandColorString = meta.color || PROMPTBOOK_COLOR_HEX;
|
|
95
|
-
|
|
96
|
-
let brandColor;
|
|
97
|
-
try {
|
|
98
|
-
brandColor = Color.fromSafe(brandColorString.split(',')[0].trim());
|
|
99
|
-
} catch {
|
|
100
|
-
brandColor = Color.fromHex(PROMPTBOOK_COLOR_HEX);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const brandColorHex = brandColor.toHex();
|
|
104
|
-
const brandColorLightHex = brandColor.then(lighten(0.2)).toHex();
|
|
105
|
-
const brandColorDarkHex = brandColor.then(darken(0.15)).toHex();
|
|
106
|
-
|
|
107
|
-
// Generate Noisy SVG Background
|
|
108
|
-
const color1 = brandColor;
|
|
109
|
-
// const color2 = brandColors[1] || brandColors[0]!; // Use secondary color if available?
|
|
110
|
-
// For simplicity using primary color for now or derive second one
|
|
111
|
-
const color2 = brandColor;
|
|
112
|
-
|
|
113
|
-
// [🧠] Make colors much lighter for the background
|
|
114
|
-
const color1Light = color1.then(lighten(0.3)).toHex();
|
|
115
|
-
const color1Main = color1.toHex();
|
|
116
|
-
const color1Dark = color1.then(darken(0.3)).toHex();
|
|
117
|
-
|
|
118
|
-
const color2Light = color2.then(lighten(0.3)).toHex();
|
|
119
|
-
const color2Main = color2.toHex();
|
|
120
|
-
const color2Dark = color2.then(darken(0.3)).toHex();
|
|
121
|
-
|
|
122
|
-
const svgContent = spaceTrim(`
|
|
123
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
124
|
-
viewBox="0 0 1920 1080"
|
|
125
|
-
width="1920" height="1080"
|
|
126
|
-
preserveAspectRatio="xMidYMid slice">
|
|
127
|
-
<defs>
|
|
128
|
-
<!-- Bottom-left -->
|
|
129
|
-
<radialGradient id="grad1" cx="0%" cy="100%" r="90%">
|
|
130
|
-
<stop offset="0%" stop-color="${color1Light}" />
|
|
131
|
-
<stop offset="50%" stop-color="${color1Main}" />
|
|
132
|
-
<stop offset="100%" stop-color="${color1Dark}" />
|
|
133
|
-
</radialGradient>
|
|
134
|
-
|
|
135
|
-
<!-- Bottom-right -->
|
|
136
|
-
<radialGradient id="grad2" cx="100%" cy="100%" r="90%">
|
|
137
|
-
<stop offset="0%" stop-color="${color2Light}" />
|
|
138
|
-
<stop offset="50%" stop-color="${color2Main}" />
|
|
139
|
-
<stop offset="100%" stop-color="${color2Dark}" />
|
|
140
|
-
</radialGradient>
|
|
141
|
-
|
|
142
|
-
<!-- White top fade -->
|
|
143
|
-
<linearGradient id="whiteTopGrad" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
144
|
-
<stop offset="0%" stop-color="#ffffff" stop-opacity="1" />
|
|
145
|
-
<stop offset="100%" stop-color="#ffffff" stop-opacity="0.3" />
|
|
146
|
-
</linearGradient>
|
|
147
|
-
|
|
148
|
-
<!-- Strong grain -->
|
|
149
|
-
<filter id="grain" x="-10%" y="-10%" width="120%" height="120%">
|
|
150
|
-
<feTurbulence type="fractalNoise" baseFrequency="3.5" numOctaves="3" seed="8" result="noise" />
|
|
151
|
-
<feComponentTransfer>
|
|
152
|
-
<feFuncR type="linear" slope="3.5" intercept="-1.2" />
|
|
153
|
-
<feFuncG type="linear" slope="3.5" intercept="-1.2" />
|
|
154
|
-
<feFuncB type="linear" slope="3.5" intercept="-1.2" />
|
|
155
|
-
<feFuncA type="table" tableValues="0 0.8" />
|
|
156
|
-
</feComponentTransfer>
|
|
157
|
-
</filter>
|
|
158
|
-
</defs>
|
|
159
|
-
|
|
160
|
-
<!-- White base -->
|
|
161
|
-
<rect width="100%" height="100%" fill="#ffffff" />
|
|
162
|
-
|
|
163
|
-
<!-- Gradients -->
|
|
164
|
-
<rect width="100%" height="100%" fill="url(#grad1)" />
|
|
165
|
-
<rect width="100%" height="100%" fill="url(#grad2)" style="mix-blend-mode:screen; opacity:0.85" />
|
|
166
|
-
|
|
167
|
-
<!-- White fade on top -->
|
|
168
|
-
<rect width="100%" height="100%" fill="url(#whiteTopGrad)" />
|
|
169
|
-
|
|
170
|
-
<!-- Strong visible noise -->
|
|
171
|
-
<rect width="100%" height="100%" filter="url(#grain)"
|
|
172
|
-
style="mix-blend-mode:soft-light; opacity:1.2" />
|
|
173
|
-
</svg>
|
|
174
|
-
`);
|
|
175
|
-
|
|
176
|
-
const backgroundImage = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgContent)}`;
|
|
177
|
-
|
|
178
|
-
return { brandColorHex, brandColorLightHex, brandColorDarkHex, backgroundImage };
|
|
179
|
-
}, [meta.color]);
|
|
104
|
+
const { brandColorHex, brandColorLightHex, brandColorDarkHex, backgroundImage } = useAgentBackground(meta.color);
|
|
180
105
|
|
|
181
106
|
return (
|
|
182
107
|
<>
|
|
@@ -208,14 +133,14 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
208
133
|
)}
|
|
209
134
|
|
|
210
135
|
{/* Main profile content */}
|
|
211
|
-
<div className="relative z-10 grid grid-cols-[auto_1fr] gap-
|
|
136
|
+
<div className="relative z-10 flex flex-col md:grid md:grid-cols-[auto_1fr] gap-y-6 md:gap-y-4 md:gap-x-12 max-w-5xl w-full items-center md:items-start">
|
|
212
137
|
{/* Agent image card (Flippable) */}
|
|
213
138
|
<div
|
|
214
|
-
className="flex-shrink-0 perspective-1000 group row-start-1 col-start-1 md:row-span-3"
|
|
139
|
+
className="flex-shrink-0 perspective-1000 group w-full md:w-auto md:row-start-1 md:col-start-1 md:row-span-3"
|
|
215
140
|
style={{ perspective: '1000px' }}
|
|
216
141
|
>
|
|
217
142
|
<div
|
|
218
|
-
className="relative w-
|
|
143
|
+
className="relative w-full md:w-80 transition-all duration-700 transform-style-3d cursor-pointer max-w-sm mx-auto md:max-w-none md:mx-0"
|
|
219
144
|
style={{
|
|
220
145
|
aspectRatio: '1 / 1.618', // Golden Ratio
|
|
221
146
|
transformStyle: 'preserve-3d',
|
|
@@ -230,19 +155,21 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
230
155
|
backfaceVisibility: 'hidden',
|
|
231
156
|
backgroundColor: brandColorDarkHex,
|
|
232
157
|
boxShadow: `0 25px 50px -12px rgba(0, 0, 0, 0.25), 0 0 0 1px ${brandColorLightHex}40`,
|
|
158
|
+
|
|
159
|
+
// Note: Make it squircle
|
|
160
|
+
// borderRadius: '50%',
|
|
161
|
+
// ['cornerShape' as really_any /* <- Note: `cornerShape` is non standard CSS property */]: 'squircle ',
|
|
233
162
|
}}
|
|
234
163
|
>
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
</div>
|
|
245
|
-
)}
|
|
164
|
+
<AgentProfileImage
|
|
165
|
+
src={imageUrl}
|
|
166
|
+
alt={fullname}
|
|
167
|
+
className="w-full h-full object-cover"
|
|
168
|
+
style={{
|
|
169
|
+
objectFit: 'cover',
|
|
170
|
+
backgroundImage: `url(${colorToDataUrl(brandColorLightHex)})`,
|
|
171
|
+
}}
|
|
172
|
+
/>
|
|
246
173
|
|
|
247
174
|
{/* Flip hint icon */}
|
|
248
175
|
<div className="absolute bottom-2 md:bottom-4 right-2 md:right-4 bg-black/30 p-1 md:p-2 rounded-full text-white/80 backdrop-blur-md opacity-0 group-hover:opacity-100 transition-opacity">
|
|
@@ -280,7 +207,7 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
280
207
|
</div>
|
|
281
208
|
|
|
282
209
|
{/* Agent info - Header Area */}
|
|
283
|
-
<div className="row-start-1 col-start-2 flex flex-col justify-center md:justify-start
|
|
210
|
+
<div className="w-full md:w-auto md:row-start-1 md:col-start-2 flex flex-col justify-center md:justify-start items-center md:items-start h-auto gap-4 md:gap-6 text-center md:text-left">
|
|
284
211
|
{/* Agent name with custom font */}
|
|
285
212
|
<h1
|
|
286
213
|
className="text-2xl md:text-5xl lg:text-6xl font-bold text-gray-900 tracking-tight leading-tight"
|
|
@@ -298,13 +225,11 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
298
225
|
</div>
|
|
299
226
|
|
|
300
227
|
{/* Chat Area */}
|
|
301
|
-
<div className="
|
|
302
|
-
{children}
|
|
303
|
-
</div>
|
|
228
|
+
<div className="w-full md:col-span-1 md:col-start-2 mt-4 md:mt-0">{children}</div>
|
|
304
229
|
|
|
305
230
|
{/* Secondary Actions */}
|
|
306
231
|
{!isHeadless && (
|
|
307
|
-
<div className="
|
|
232
|
+
<div className="w-full md:col-span-1 md:col-start-2 flex flex-wrap justify-center md:justify-start items-center gap-4 md:gap-6 mt-4 md:mt-2">
|
|
308
233
|
{actions}
|
|
309
234
|
</div>
|
|
310
235
|
)}
|