@promptbook/cli 0.104.0-1 → 0.104.0-11
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/files/FilesGalleryClient.tsx +263 -0
- package/apps/agents-server/src/app/admin/files/actions.ts +61 -0
- package/apps/agents-server/src/app/admin/files/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/image-generator-test/ImageGeneratorTestClient.tsx +169 -0
- package/apps/agents-server/src/app/admin/image-generator-test/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/images/ImagesGalleryClient.tsx +256 -0
- package/apps/agents-server/src/app/admin/images/actions.ts +60 -0
- package/apps/agents-server/src/app/admin/images/page.tsx +13 -0
- 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/admin/search-engine-test/SearchEngineTestClient.tsx +109 -0
- package/apps/agents-server/src/app/admin/search-engine-test/actions.ts +17 -0
- package/apps/agents-server/src/app/admin/search-engine-test/page.tsx +13 -0
- 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 +128 -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/AgentCapabilityChips.tsx +38 -0
- package/apps/agents-server/src/components/AgentProfile/AgentProfile.tsx +44 -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 +130 -40
- package/apps/agents-server/src/components/Homepage/AgentCard.tsx +150 -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/$getTableName.ts +1 -0
- 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/migrations/2025-12-0830-image-purpose.sql +5 -0
- package/apps/agents-server/src/database/migrations/2025-12-0890-file-agent-id.sql +5 -0
- package/apps/agents-server/src/database/schema.ts +244 -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 +1534 -1330
- 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 +16 -2
- package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +29 -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 +9 -13
- package/esm/typings/src/book-components/_common/Dropdown/Dropdown.d.ts +3 -3
- package/esm/typings/src/book-components/_common/HamburgerMenu/HamburgerMenu.d.ts +1 -1
- package/esm/typings/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +56 -0
- package/esm/typings/src/book-components/icons/AboutIcon.d.ts +1 -1
- package/esm/typings/src/book-components/icons/AttachmentIcon.d.ts +1 -1
- package/esm/typings/src/book-components/icons/CameraIcon.d.ts +1 -1
- package/esm/typings/src/book-components/icons/DownloadIcon.d.ts +1 -1
- package/esm/typings/src/book-components/icons/MenuIcon.d.ts +1 -1
- package/esm/typings/src/book-components/icons/SaveIcon.d.ts +1 -1
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +22 -12
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +27 -15
- 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/_common/utils/count-total-usage/countUsage.d.ts +1 -1
- package/esm/typings/src/llm-providers/_multiple/MultipleLlmExecutionTools.d.ts +6 -2
- package/esm/typings/src/llm-providers/agent/Agent.d.ts +6 -1
- 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/remote-server/ui/ServerApp.d.ts +1 -1
- package/esm/typings/src/search-engines/SearchEngine.d.ts +9 -0
- package/esm/typings/src/search-engines/SearchResult.d.ts +18 -0
- package/esm/typings/src/search-engines/bing/BingSearchEngine.d.ts +15 -0
- package/esm/typings/src/search-engines/dummy/DummySearchEngine.d.ts +15 -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/$randomAgentPersona.d.ts +3 -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 +1542 -1338
- 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
|
@@ -1,46 +1,124 @@
|
|
|
1
1
|
// Client Component for rendering and deleting agents
|
|
2
2
|
'use client';
|
|
3
3
|
|
|
4
|
-
import React, { useState } from 'react';
|
|
5
4
|
import { TrashIcon } from 'lucide-react';
|
|
6
5
|
import Link from 'next/link';
|
|
6
|
+
import { useRouter } from 'next/navigation';
|
|
7
|
+
import { useState } from 'react';
|
|
7
8
|
import { AddAgentButton } from '../../app/AddAgentButton';
|
|
8
9
|
import { AgentCard } from './AgentCard';
|
|
9
10
|
import { Section } from './Section';
|
|
10
11
|
|
|
11
12
|
import { AgentBasicInformation } from '../../../../../src/book-2.0/agent-source/AgentBasicInformation';
|
|
12
13
|
|
|
14
|
+
type AgentWithVisibility = AgentBasicInformation & {
|
|
15
|
+
visibility?: 'PUBLIC' | 'PRIVATE';
|
|
16
|
+
};
|
|
17
|
+
|
|
13
18
|
type AgentsListProps = {
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
/**
|
|
20
|
+
* @@@
|
|
21
|
+
*/
|
|
22
|
+
readonly agents: AgentWithVisibility[];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @@@
|
|
26
|
+
*/
|
|
27
|
+
readonly isAdmin: boolean;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Base URL of the agents server
|
|
31
|
+
*/
|
|
32
|
+
readonly publicUrl: URL;
|
|
16
33
|
};
|
|
17
34
|
|
|
18
|
-
export function AgentsList(
|
|
35
|
+
export function AgentsList(props: AgentsListProps) {
|
|
36
|
+
const { agents: initialAgents, isAdmin, publicUrl } = props;
|
|
37
|
+
const router = useRouter();
|
|
19
38
|
const [agents, setAgents] = useState(Array.from(initialAgents));
|
|
20
39
|
|
|
21
|
-
const handleDelete = async (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
40
|
+
const handleDelete = async (agentIdentifier: string) => {
|
|
41
|
+
const agent = agents.find((a) => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
42
|
+
if (!agent) return;
|
|
43
|
+
if (!window.confirm(`Delete agent "${agent.agentName}"? It will be moved to Recycle Bin.`)) return;
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const response = await fetch(`/api/agents/${encodeURIComponent(agentIdentifier)}`, { method: 'DELETE' });
|
|
47
|
+
if (response.ok) {
|
|
48
|
+
// Update local state immediately
|
|
49
|
+
setAgents(agents.filter((a) => a.permanentId !== agent.permanentId && a.agentName !== agent.agentName));
|
|
50
|
+
// Note: router.refresh() is not needed here as the local state update is sufficient
|
|
51
|
+
// and prevents the brief empty list issue during refresh
|
|
52
|
+
} else {
|
|
53
|
+
alert('Failed to delete agent');
|
|
54
|
+
}
|
|
55
|
+
} catch (error) {
|
|
56
|
+
alert('Failed to delete agent');
|
|
57
|
+
}
|
|
25
58
|
};
|
|
26
59
|
|
|
27
|
-
const handleClone = async (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
60
|
+
const handleClone = async (agentIdentifier: string) => {
|
|
61
|
+
const agent = agents.find((a) => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
62
|
+
if (!agent) return;
|
|
63
|
+
if (!window.confirm(`Clone agent "${agent.agentName}"?`)) return;
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const response = await fetch(`/api/agents/${encodeURIComponent(agentIdentifier)}/clone`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
});
|
|
69
|
+
if (response.ok) {
|
|
70
|
+
const newAgent = await response.json();
|
|
71
|
+
setAgents([...agents, newAgent]);
|
|
72
|
+
router.refresh(); // Refresh server data to ensure consistency
|
|
73
|
+
} else {
|
|
74
|
+
alert('Failed to clone agent');
|
|
75
|
+
}
|
|
76
|
+
} catch (error) {
|
|
77
|
+
alert('Failed to clone agent');
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const handleToggleVisibility = async (agentIdentifier: string) => {
|
|
82
|
+
const agent = agents.find((a) => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
83
|
+
if (!agent) return;
|
|
84
|
+
|
|
85
|
+
const newVisibility = agent.visibility === 'PUBLIC' ? 'PRIVATE' : 'PUBLIC';
|
|
86
|
+
if (!window.confirm(`Make agent "${agent.agentName}" ${newVisibility.toLowerCase()}?`)) return;
|
|
87
|
+
|
|
88
|
+
const response = await fetch(`/api/agents/${encodeURIComponent(agentIdentifier)}`, {
|
|
89
|
+
method: 'PATCH',
|
|
90
|
+
headers: { 'Content-Type': 'application/json' },
|
|
91
|
+
body: JSON.stringify({ visibility: newVisibility }),
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (response.ok) {
|
|
95
|
+
// Update the local state
|
|
96
|
+
setAgents(
|
|
97
|
+
agents.map((a) =>
|
|
98
|
+
a.permanentId === agent.permanentId || a.agentName === agent.agentName
|
|
99
|
+
? { ...a, visibility: newVisibility }
|
|
100
|
+
: a,
|
|
101
|
+
),
|
|
102
|
+
);
|
|
103
|
+
router.refresh(); // Refresh server data to ensure consistency
|
|
104
|
+
} else {
|
|
105
|
+
alert('Failed to update agent visibility');
|
|
106
|
+
}
|
|
32
107
|
};
|
|
33
108
|
|
|
34
109
|
return (
|
|
35
110
|
<Section title={`Agents (${agents.length})`}>
|
|
36
111
|
{agents.map((agent) => (
|
|
37
112
|
<AgentCard
|
|
38
|
-
key={agent.agentName}
|
|
113
|
+
key={agent.permanentId || agent.agentName}
|
|
39
114
|
agent={agent}
|
|
40
|
-
|
|
115
|
+
publicUrl={publicUrl}
|
|
116
|
+
href={`/agents/${encodeURIComponent(agent.permanentId || agent.agentName)}`}
|
|
41
117
|
isAdmin={isAdmin}
|
|
42
118
|
onDelete={handleDelete}
|
|
43
119
|
onClone={handleClone}
|
|
120
|
+
onToggleVisibility={handleToggleVisibility}
|
|
121
|
+
visibility={agent.visibility}
|
|
44
122
|
/>
|
|
45
123
|
))}
|
|
46
124
|
{isAdmin && <AddAgentButton />}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Client Component for rendering deleted agents
|
|
2
|
+
'use client';
|
|
3
|
+
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import { AgentCard } from './AgentCard';
|
|
6
|
+
|
|
7
|
+
import { AgentBasicInformation } from '../../../../../src/book-2.0/agent-source/AgentBasicInformation';
|
|
8
|
+
|
|
9
|
+
type DeletedAgentsListProps = {
|
|
10
|
+
/**
|
|
11
|
+
* @@@
|
|
12
|
+
*/
|
|
13
|
+
readonly agents: readonly AgentBasicInformation[];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @@@
|
|
17
|
+
*/
|
|
18
|
+
readonly isAdmin: boolean;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Base URL of the agents server
|
|
22
|
+
*/
|
|
23
|
+
readonly publicUrl: URL;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export function DeletedAgentsList(props: DeletedAgentsListProps) {
|
|
27
|
+
const { agents: initialAgents, isAdmin, publicUrl } = props;
|
|
28
|
+
const [agents, setAgents] = useState(Array.from(initialAgents));
|
|
29
|
+
|
|
30
|
+
const handleRestore = async (agentIdentifier: string) => {
|
|
31
|
+
const agent = agents.find((a) => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
32
|
+
if (!agent) return;
|
|
33
|
+
if (!window.confirm(`Restore agent "${agent.agentName}"?`)) return;
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const response = await fetch(`/api/agents/${encodeURIComponent(agentIdentifier)}/restore`, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
});
|
|
39
|
+
if (response.ok) {
|
|
40
|
+
// Update local state immediately
|
|
41
|
+
setAgents(agents.filter((a) => a.permanentId !== agent.permanentId && a.agentName !== agent.agentName));
|
|
42
|
+
// Note: router.refresh() is not needed here as the local state update is sufficient
|
|
43
|
+
// and prevents the brief empty list issue during refresh
|
|
44
|
+
} else {
|
|
45
|
+
alert('Failed to restore agent');
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
alert('Failed to restore agent');
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
|
54
|
+
{agents.map((agent) => (
|
|
55
|
+
<AgentCard
|
|
56
|
+
key={agent.permanentId || agent.agentName}
|
|
57
|
+
agent={agent}
|
|
58
|
+
publicUrl={publicUrl}
|
|
59
|
+
href={`/agents/${encodeURIComponent(agent.permanentId || agent.agentName)}`}
|
|
60
|
+
isAdmin={isAdmin}
|
|
61
|
+
onRestore={handleRestore}
|
|
62
|
+
/>
|
|
63
|
+
))}
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
@@ -3,16 +3,25 @@ import { AgentCard } from './AgentCard';
|
|
|
3
3
|
import { Section } from './Section';
|
|
4
4
|
|
|
5
5
|
type ExternalAgentsSectionProps = {
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @@@
|
|
8
|
+
*/
|
|
9
|
+
readonly agentsByServer: AgentsByServer[];
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Base URL of the agents server
|
|
13
|
+
*/
|
|
14
|
+
readonly publicUrl: URL;
|
|
7
15
|
};
|
|
8
16
|
|
|
9
|
-
export function ExternalAgentsSection(
|
|
17
|
+
export function ExternalAgentsSection(props: ExternalAgentsSectionProps) {
|
|
18
|
+
const { agentsByServer, publicUrl } = props;
|
|
10
19
|
return (
|
|
11
20
|
<>
|
|
12
21
|
{agentsByServer.map(({ serverUrl, agents }) => (
|
|
13
22
|
<Section key={serverUrl} title={`Agents from ${new URL(serverUrl).hostname} (${agents.length})`}>
|
|
14
23
|
{agents.map((agent) => (
|
|
15
|
-
<AgentCard key={agent.url} agent={agent} href={agent.url} />
|
|
24
|
+
<AgentCard key={agent.url} agent={agent} href={agent.url} publicUrl={publicUrl} />
|
|
16
25
|
))}
|
|
17
26
|
</Section>
|
|
18
27
|
))}
|
|
@@ -15,7 +15,15 @@ type ServerState = {
|
|
|
15
15
|
error?: string;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
type ExternalAgentsSectionClientProps = {
|
|
19
|
+
/**
|
|
20
|
+
* Base URL of the agents server
|
|
21
|
+
*/
|
|
22
|
+
readonly publicUrl: URL;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function ExternalAgentsSectionClient(props: ExternalAgentsSectionClientProps) {
|
|
26
|
+
const { publicUrl } = props;
|
|
19
27
|
const [servers, setServers] = useState<Record<string, ServerState>>({});
|
|
20
28
|
const [initialLoading, setInitialLoading] = useState(true);
|
|
21
29
|
|
|
@@ -26,24 +34,23 @@ export function ExternalAgentsSectionClient() {
|
|
|
26
34
|
try {
|
|
27
35
|
const response = await fetch('/api/federated-agents');
|
|
28
36
|
if (!response.ok) throw new Error('Failed to fetch federated servers');
|
|
29
|
-
|
|
37
|
+
|
|
30
38
|
const data: FederatedServersResponse = await response.json();
|
|
31
|
-
|
|
39
|
+
|
|
32
40
|
if (isCancelled) return;
|
|
33
41
|
|
|
34
42
|
const initialServerState: Record<string, ServerState> = {};
|
|
35
|
-
data.federatedServers.forEach(serverUrl => {
|
|
43
|
+
data.federatedServers.forEach((serverUrl) => {
|
|
36
44
|
initialServerState[serverUrl] = { status: 'loading', agents: [] };
|
|
37
45
|
});
|
|
38
|
-
|
|
46
|
+
|
|
39
47
|
setServers(initialServerState);
|
|
40
48
|
setInitialLoading(false);
|
|
41
49
|
|
|
42
50
|
// Fetch agents for each server independently
|
|
43
|
-
data.federatedServers.forEach(serverUrl => {
|
|
51
|
+
data.federatedServers.forEach((serverUrl) => {
|
|
44
52
|
fetchAgentsForServer(serverUrl);
|
|
45
53
|
});
|
|
46
|
-
|
|
47
54
|
} catch (error) {
|
|
48
55
|
console.error('Failed to load federated servers list', error);
|
|
49
56
|
if (!isCancelled) setInitialLoading(false);
|
|
@@ -80,7 +87,9 @@ export function ExternalAgentsSectionClient() {
|
|
|
80
87
|
const response = await fetch(proxyUrl);
|
|
81
88
|
|
|
82
89
|
if (!response.ok) {
|
|
83
|
-
throw new Error(
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Failed to fetch agents from ${serverUrl} via proxy (Status: ${response.status})`,
|
|
92
|
+
);
|
|
84
93
|
}
|
|
85
94
|
|
|
86
95
|
const data = await response.json();
|
|
@@ -134,7 +143,7 @@ export function ExternalAgentsSectionClient() {
|
|
|
134
143
|
|
|
135
144
|
return (
|
|
136
145
|
<>
|
|
137
|
-
{serverUrls.map(serverUrl => {
|
|
146
|
+
{serverUrls.map((serverUrl) => {
|
|
138
147
|
const state = servers[serverUrl];
|
|
139
148
|
const hostname = (() => {
|
|
140
149
|
try {
|
|
@@ -169,7 +178,7 @@ export function ExternalAgentsSectionClient() {
|
|
|
169
178
|
return (
|
|
170
179
|
<Section key={serverUrl} title={`Agents from ${hostname} (${state.agents.length})`}>
|
|
171
180
|
{state.agents.map((agent) => (
|
|
172
|
-
<AgentCard key={agent.url} agent={agent} href={agent.url} />
|
|
181
|
+
<AgentCard key={agent.url} agent={agent} href={agent.url} publicUrl={publicUrl} />
|
|
173
182
|
))}
|
|
174
183
|
</Section>
|
|
175
184
|
);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { usePathname, useSearchParams } from 'next/navigation';
|
|
4
4
|
import { AgentBasicInformation } from '../../../../../src/book-2.0/agent-source/AgentBasicInformation';
|
|
5
|
+
import { MenuHoistingProvider } from '../../../../../src/book-components/_common/MenuHoisting/MenuHoistingContext';
|
|
5
6
|
import type { UserInfo } from '../../utils/getCurrentUser';
|
|
6
7
|
import { Footer, type FooterLink } from '../Footer/Footer';
|
|
7
8
|
import { Header } from '../Header/Header';
|
|
@@ -41,7 +42,7 @@ export function LayoutWrapper({
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
return (
|
|
44
|
-
|
|
45
|
+
<MenuHoistingProvider>
|
|
45
46
|
<Header
|
|
46
47
|
isAdmin={isAdmin}
|
|
47
48
|
currentUser={currentUser}
|
|
@@ -52,6 +53,6 @@ export function LayoutWrapper({
|
|
|
52
53
|
/>
|
|
53
54
|
<main className={`pt-[60px]`}>{children}</main>
|
|
54
55
|
{isFooterShown && !isFooterHiddenOnPage && <Footer extraLinks={footerLinks} />}
|
|
55
|
-
|
|
56
|
+
</MenuHoistingProvider>
|
|
56
57
|
);
|
|
57
58
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { loginAction } from '@/src/app/actions';
|
|
4
|
+
import { ForgottenPasswordDialog } from '../ForgottenPasswordDialog/ForgottenPasswordDialog';
|
|
5
|
+
import { RegisterUserDialog } from '../RegisterUserDialog/RegisterUserDialog';
|
|
4
6
|
import { Loader2, Lock, User } from 'lucide-react';
|
|
5
|
-
import { useState } from 'react';
|
|
7
|
+
import { useEffect, useState } from 'react';
|
|
6
8
|
|
|
7
9
|
type LoginFormProps = {
|
|
8
10
|
onSuccess?: () => void;
|
|
@@ -13,6 +15,24 @@ export function LoginForm(props: LoginFormProps) {
|
|
|
13
15
|
const { onSuccess, className } = props;
|
|
14
16
|
const [isLoading, setIsLoading] = useState(false);
|
|
15
17
|
const [error, setError] = useState<string | null>(null);
|
|
18
|
+
const [adminEmail, setAdminEmail] = useState<string>('support@ptbk.io');
|
|
19
|
+
const [isForgottenPasswordOpen, setIsForgottenPasswordOpen] = useState(false);
|
|
20
|
+
const [isRegisterUserOpen, setIsRegisterUserOpen] = useState(false);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
// Fetch admin email on component mount
|
|
24
|
+
fetch('/api/admin-email')
|
|
25
|
+
.then(response => response.json())
|
|
26
|
+
.then(data => {
|
|
27
|
+
if (data.adminEmail) {
|
|
28
|
+
setAdminEmail(data.adminEmail);
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
.catch(error => {
|
|
32
|
+
console.error('Failed to fetch admin email:', error);
|
|
33
|
+
// Keep default value
|
|
34
|
+
});
|
|
35
|
+
}, []);
|
|
16
36
|
|
|
17
37
|
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
|
18
38
|
event.preventDefault();
|
|
@@ -104,6 +124,35 @@ export function LoginForm(props: LoginFormProps) {
|
|
|
104
124
|
'Log in'
|
|
105
125
|
)}
|
|
106
126
|
</button>
|
|
127
|
+
|
|
128
|
+
<div className="flex justify-between text-sm">
|
|
129
|
+
<button
|
|
130
|
+
type="button"
|
|
131
|
+
onClick={() => setIsForgottenPasswordOpen(true)}
|
|
132
|
+
className="text-promptbook-blue hover:text-promptbook-blue-dark underline focus:outline-none focus:ring-2 focus:ring-promptbook-blue focus:ring-offset-2 rounded-sm"
|
|
133
|
+
>
|
|
134
|
+
Forgotten password?
|
|
135
|
+
</button>
|
|
136
|
+
<button
|
|
137
|
+
type="button"
|
|
138
|
+
onClick={() => setIsRegisterUserOpen(true)}
|
|
139
|
+
className="text-promptbook-blue hover:text-promptbook-blue-dark underline focus:outline-none focus:ring-2 focus:ring-promptbook-blue focus:ring-offset-2 rounded-sm"
|
|
140
|
+
>
|
|
141
|
+
Register new user
|
|
142
|
+
</button>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<ForgottenPasswordDialog
|
|
146
|
+
isOpen={isForgottenPasswordOpen}
|
|
147
|
+
onClose={() => setIsForgottenPasswordOpen(false)}
|
|
148
|
+
adminEmail={adminEmail}
|
|
149
|
+
/>
|
|
150
|
+
|
|
151
|
+
<RegisterUserDialog
|
|
152
|
+
isOpen={isRegisterUserOpen}
|
|
153
|
+
onClose={() => setIsRegisterUserOpen(false)}
|
|
154
|
+
adminEmail={adminEmail}
|
|
155
|
+
/>
|
|
107
156
|
</form>
|
|
108
157
|
);
|
|
109
158
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { string_book } from '@promptbook-local/types';
|
|
4
|
+
import { X } from 'lucide-react';
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
import { BookEditor } from '../../../../../src/book-components/BookEditor/BookEditor';
|
|
7
|
+
import { Portal } from '../Portal/Portal';
|
|
8
|
+
|
|
9
|
+
type NewAgentDialogProps = {
|
|
10
|
+
isOpen: boolean;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
initialAgentSource: string_book;
|
|
13
|
+
onCreate: (agentSource: string_book) => Promise<void>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function NewAgentDialog(props: NewAgentDialogProps) {
|
|
17
|
+
const { isOpen, onClose, initialAgentSource, onCreate } = props;
|
|
18
|
+
const [agentSource, setAgentSource] = useState(initialAgentSource);
|
|
19
|
+
const [isCreating, setIsCreating] = useState(false);
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
setAgentSource(initialAgentSource);
|
|
23
|
+
}, [initialAgentSource]);
|
|
24
|
+
|
|
25
|
+
if (!isOpen) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const handleCreate = async () => {
|
|
30
|
+
setIsCreating(true);
|
|
31
|
+
try {
|
|
32
|
+
await onCreate(agentSource);
|
|
33
|
+
} finally {
|
|
34
|
+
setIsCreating(false);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<Portal>
|
|
40
|
+
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/50 backdrop-blur-sm animate-in fade-in duration-200">
|
|
41
|
+
<div className="relative w-full max-w-4xl h-[80vh] bg-white rounded-lg shadow-lg border border-gray-200 flex flex-col animate-in zoom-in-95 duration-200">
|
|
42
|
+
<div className="flex items-center justify-between p-4 border-b border-gray-200">
|
|
43
|
+
<h2 className="text-xl font-semibold text-gray-900">Create New Agent</h2>
|
|
44
|
+
<button
|
|
45
|
+
onClick={onClose}
|
|
46
|
+
className="text-gray-400 hover:text-gray-500 transition-colors"
|
|
47
|
+
>
|
|
48
|
+
<X className="w-5 h-5" />
|
|
49
|
+
<span className="sr-only">Close</span>
|
|
50
|
+
</button>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div className="flex-1 overflow-hidden p-4">
|
|
54
|
+
<BookEditor
|
|
55
|
+
agentSource={agentSource}
|
|
56
|
+
onChange={(source) => setAgentSource(source)}
|
|
57
|
+
height="100%"
|
|
58
|
+
isVerbose={false}
|
|
59
|
+
/>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div className="flex items-center justify-end gap-3 p-4 border-t border-gray-200 bg-gray-50 rounded-b-lg">
|
|
63
|
+
<button
|
|
64
|
+
onClick={onClose}
|
|
65
|
+
className="px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 rounded-md transition-colors"
|
|
66
|
+
>
|
|
67
|
+
Cancel
|
|
68
|
+
</button>
|
|
69
|
+
<button
|
|
70
|
+
onClick={handleCreate}
|
|
71
|
+
disabled={isCreating}
|
|
72
|
+
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
|
|
73
|
+
>
|
|
74
|
+
{isCreating ? (
|
|
75
|
+
<>
|
|
76
|
+
<span className="inline-block h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" />
|
|
77
|
+
Creating...
|
|
78
|
+
</>
|
|
79
|
+
) : (
|
|
80
|
+
'Create Agent'
|
|
81
|
+
)}
|
|
82
|
+
</button>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</Portal>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
|
+
import { HomeIcon } from 'lucide-react';
|
|
1
2
|
import Link from 'next/link';
|
|
2
3
|
import { ErrorPage } from '../ErrorPage/ErrorPage';
|
|
3
4
|
|
|
4
5
|
export function NotFoundPage() {
|
|
5
6
|
return (
|
|
6
|
-
<ErrorPage
|
|
7
|
+
<ErrorPage
|
|
8
|
+
title="Agent Not Found :("
|
|
9
|
+
message="The agent you are looking for does not exist, but you can create your own!"
|
|
10
|
+
>
|
|
7
11
|
<div className="flex justify-center">
|
|
8
12
|
<Link
|
|
9
13
|
href="/"
|
|
10
14
|
className="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
|
11
15
|
>
|
|
12
|
-
|
|
16
|
+
<HomeIcon className="inline w-5 h-5 mr-2" />
|
|
17
|
+
Home
|
|
13
18
|
</Link>
|
|
14
19
|
</div>
|
|
15
20
|
</ErrorPage>
|
|
@@ -1,19 +1,28 @@
|
|
|
1
|
+
import { string_char_emoji } from '@promptbook-local/types';
|
|
1
2
|
import { DetailedHTMLProps, HTMLAttributes } from 'react';
|
|
2
3
|
|
|
3
4
|
type OpenMojiIconProps = DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> & {
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The OpenMoji character to display
|
|
7
|
+
*/
|
|
8
|
+
icon: string_char_emoji | string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @default 'black'
|
|
12
|
+
*/
|
|
13
|
+
variant?: 'black' | 'color';
|
|
5
14
|
};
|
|
6
15
|
|
|
7
16
|
/**
|
|
8
17
|
* Renders an emoji using the OpenMoji black and white font
|
|
9
18
|
*/
|
|
10
|
-
export function OpenMojiIcon(
|
|
19
|
+
export function OpenMojiIcon(props: OpenMojiIconProps) {
|
|
20
|
+
const { icon, variant = 'black', className, style, ...rest } = props;
|
|
21
|
+
|
|
22
|
+
const fontFamily = variant === 'black' ? '"OpenMojiBlack", sans-serif' : '"OpenMojiColor", sans-serif';
|
|
23
|
+
|
|
11
24
|
return (
|
|
12
|
-
<span
|
|
13
|
-
className={className}
|
|
14
|
-
style={{ ...style, fontFamily: '"OpenMojiBlack", sans-serif' }}
|
|
15
|
-
{...rest}
|
|
16
|
-
>
|
|
25
|
+
<span className={className} style={{ ...style, fontFamily }} {...rest}>
|
|
17
26
|
{icon}
|
|
18
27
|
</span>
|
|
19
28
|
);
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export function PrintHeader({ title }: { title?: string }) {
|
|
2
2
|
return (
|
|
3
|
-
<div className="hidden print:block mb-
|
|
3
|
+
<div className="hidden print:block mb-6 border-b-2 border-blue-600 pb-2">
|
|
4
4
|
<div className="flex justify-between items-end">
|
|
5
5
|
<div>
|
|
6
|
-
<h1 className="text-
|
|
6
|
+
<h1 className="text-2xl font-bold text-gray-900 font-poppins">Agents Server</h1>
|
|
7
7
|
<div className="text-sm text-gray-500 mt-1 flex items-center gap-1">
|
|
8
8
|
Powered by <span className="font-semibold text-blue-600">Promptbook</span>
|
|
9
9
|
</div>
|
|
10
10
|
</div>
|
|
11
|
-
{title && <h2 className="text-
|
|
11
|
+
{title && <h2 className="text-lg font-semibold text-gray-700">{title}</h2>}
|
|
12
12
|
</div>
|
|
13
|
-
<div className="text-xs text-gray-400 mt-
|
|
13
|
+
<div className="text-xs text-gray-400 mt-1 text-right">
|
|
14
14
|
{new Date().toLocaleDateString()}
|
|
15
15
|
</div>
|
|
16
16
|
</div>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { X } from 'lucide-react';
|
|
4
|
+
import { Portal } from '../Portal/Portal';
|
|
5
|
+
|
|
6
|
+
type RegisterUserDialogProps = {
|
|
7
|
+
isOpen: boolean;
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
adminEmail: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function RegisterUserDialog(props: RegisterUserDialogProps) {
|
|
13
|
+
const { isOpen, onClose, adminEmail } = props;
|
|
14
|
+
|
|
15
|
+
if (!isOpen) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<Portal>
|
|
21
|
+
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/50 backdrop-blur-sm animate-in fade-in duration-200">
|
|
22
|
+
<div className="relative w-full max-w-md bg-white rounded-lg shadow-lg border border-gray-200 p-6 animate-in zoom-in-95 duration-200">
|
|
23
|
+
<button
|
|
24
|
+
onClick={onClose}
|
|
25
|
+
className="absolute top-4 right-4 text-gray-400 hover:text-gray-500 transition-colors"
|
|
26
|
+
>
|
|
27
|
+
<X className="w-5 h-5" />
|
|
28
|
+
<span className="sr-only">Close</span>
|
|
29
|
+
</button>
|
|
30
|
+
|
|
31
|
+
<div className="mb-6">
|
|
32
|
+
<h2 className="text-xl font-semibold text-gray-900">Register New User</h2>
|
|
33
|
+
<p className="text-sm text-gray-500 mt-1">Create a new user account</p>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div className="space-y-4">
|
|
37
|
+
<div className="p-4 bg-blue-50 border border-blue-200 rounded-md">
|
|
38
|
+
<p className="text-sm text-blue-800">
|
|
39
|
+
This Promptbook server has no email capability. Please contact the administrator at{' '}
|
|
40
|
+
<a
|
|
41
|
+
href={`mailto:${adminEmail}`}
|
|
42
|
+
className="font-medium text-blue-900 underline hover:text-blue-800"
|
|
43
|
+
>
|
|
44
|
+
{adminEmail}
|
|
45
|
+
</a>{' '}
|
|
46
|
+
to register new user.
|
|
47
|
+
</p>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<button
|
|
51
|
+
onClick={onClose}
|
|
52
|
+
className="w-full inline-flex items-center justify-center rounded-md text-sm font-medium h-10 px-4 py-2 bg-gray-100 text-gray-900 hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 transition-colors"
|
|
53
|
+
>
|
|
54
|
+
Close
|
|
55
|
+
</button>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</Portal>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
NEXT_PUBLIC_SITE_URL,
|
|
2
3
|
NEXT_PUBLIC_VERCEL_BRANCH_URL,
|
|
3
4
|
NEXT_PUBLIC_VERCEL_ENV,
|
|
4
5
|
NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_LOGIN,
|
|
@@ -24,6 +25,7 @@ import { TechInfoCard } from '../Homepage/TechInfoCard';
|
|
|
24
25
|
export default function VercelDeploymentCard() {
|
|
25
26
|
return (
|
|
26
27
|
<TechInfoCard title="Vercel Deployment">
|
|
28
|
+
<p className="text-gray-600">NEXT_PUBLIC_SITE_URL: {NEXT_PUBLIC_SITE_URL?.href || 'undefined'}</p>
|
|
27
29
|
<p className="text-gray-600">NEXT_PUBLIC_VERCEL_ENV: {NEXT_PUBLIC_VERCEL_ENV}</p>
|
|
28
30
|
<p className="text-gray-600">NEXT_PUBLIC_VERCEL_TARGET_ENV: {NEXT_PUBLIC_VERCEL_TARGET_ENV}</p>
|
|
29
31
|
<p className="text-gray-600">NEXT_PUBLIC_VERCEL_URL: {NEXT_PUBLIC_VERCEL_URL}</p>
|