@promptbook/cli 0.112.0-126 → 0.112.0-127
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/README.md +5 -5
- package/apps/agents-server/README.md +3 -0
- package/apps/agents-server/playwright.config.ts +1 -0
- package/apps/agents-server/public/promptbook-logo-blue.png +0 -0
- package/apps/agents-server/public/promptbook-logo-white.png +0 -0
- package/apps/agents-server/src/app/[agentName]/layout.tsx +1 -0
- package/apps/agents-server/src/app/actions.ts +2 -2
- package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +68 -36
- package/apps/agents-server/src/app/agents/[agentName]/ActiveAgentBreadcrumbBinder.tsx +30 -0
- package/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +2 -0
- package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatHistoryPayloadState.ts +38 -4
- package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatHistorySyncOperations.ts +4 -1
- package/apps/agents-server/src/app/agents/[agentName]/chat/CanonicalAgentChatSurface.tsx +19 -15
- package/apps/agents-server/src/app/agents/[agentName]/chat/useCanonicalAgentChatPanelState.ts +58 -7
- package/apps/agents-server/src/app/agents/[agentName]/layout.tsx +47 -1
- package/apps/agents-server/src/app/api/chat/citation-label/route.ts +133 -0
- package/apps/agents-server/src/app/globals.css +78 -0
- package/apps/agents-server/src/components/Header/ActiveAgentBreadcrumbContext.tsx +82 -0
- package/apps/agents-server/src/components/Header/useHeaderActiveAgent.ts +26 -7
- package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +35 -32
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/ManGoNewAgentWizard.tsx +151 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/ManGoOnboardingNavigation.tsx +50 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/BookLanguagePanel.tsx +125 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/DropZone.tsx +83 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/EmailTestRun.tsx +216 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/KnowledgeList.tsx +79 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/Logo.tsx +20 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/MarkdownBookEditor.tsx +154 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/MarkdownPreview.tsx +188 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/RailStepper.tsx +115 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/StepFrame.tsx +47 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/TestChat.tsx +159 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/WizardShell.tsx +114 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/brand/RailArtwork.tsx +60 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/BookStep.tsx +135 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/DoneStep.tsx +215 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/KnowledgeStep.tsx +152 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/TestStep.tsx +262 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/steps/ZadaniStep.tsx +64 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Badge.tsx +41 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Banner.tsx +69 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Button.tsx +77 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Card.tsx +33 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Field.tsx +103 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/IconButton.tsx +40 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/Spinner.tsx +14 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/ui/tokens.ts +37 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/bookSections.ts +62 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/emailScenarios.ts +22 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/config/steps.ts +46 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/index.ts +11 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/cn.ts +4 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/format.ts +9 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/lib/id.ts +11 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/agentEvalService.ts +30 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/agentTestService.ts +69 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/bookService.ts +21 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/createManGoAgentSource.ts +107 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/draftService.ts +45 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/services/uploadService.ts +27 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/state/OnboardingProvider.tsx +121 -0
- package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/types.ts +52 -0
- package/apps/agents-server/src/components/NewAgentDialog/createNewAgentWizardSource.ts +1 -1
- package/apps/agents-server/src/components/NewAgentDialog/trackNewAgentCreationEvent.ts +1 -1
- package/apps/agents-server/src/components/NewAgentDialog/useNewAgentDialog.tsx +76 -0
- package/apps/agents-server/src/constants/newAgentWizard.ts +17 -8
- package/apps/agents-server/src/database/getMetadata.ts +37 -1
- package/apps/agents-server/src/database/metadataDefaults.ts +18 -7
- package/apps/agents-server/src/database/migrations/2026-06-2200-new-agent-wizard-metadata-key.sql +27 -0
- package/apps/agents-server/src/database/migrations/2026-06-2201-new-agent-wizard-mango-default.sql +11 -0
- package/apps/agents-server/src/generated/reservedPaths.ts +2 -0
- package/apps/agents-server/src/languages/translations/english.yaml +1 -1
- package/apps/agents-server/src/tools/createChatAttachmentToolFunctions.ts +8 -4
- package/apps/agents-server/src/utils/chat/resolveAgentsServerCitationLabel.ts +130 -0
- package/apps/agents-server/src/utils/chat/resolveCitationSourceLabel.ts +436 -0
- package/apps/agents-server/src/utils/knowledge/resolveWebsiteKnowledgeSourcesForServer.ts +10 -1
- package/apps/agents-server/src/utils/session.ts +62 -5
- package/apps/agents-server/src/utils/transpilers/resolveTranspiledTeamExport.ts +10 -10
- package/apps/agents-server/src/utils/userChat/userChatProgressCard.ts +198 -63
- package/apps/agents-server/src/utils/vpsConfiguration.ts +1 -0
- package/apps/agents-server/src/utils/vpsSelfUpdate.ts +81 -8
- package/esm/index.es.js +1052 -455
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -1
- package/esm/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -2
- package/esm/scripts/run-codex-prompts/server/buildCoderServerPromptResponse.d.ts +50 -0
- package/esm/scripts/run-codex-prompts/server/buildCoderServerRunState.d.ts +23 -0
- package/esm/scripts/run-codex-prompts/server/coderServerHtml.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/server/runCoderHttpServer.d.ts +13 -1
- package/esm/scripts/run-codex-prompts/server/updatePromptSection.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +1 -0
- package/esm/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +4 -0
- package/esm/scripts/run-codex-prompts/ui/renderCoderRunUi.d.ts +1 -0
- package/esm/src/_packages/components.index.d.ts +2 -0
- package/esm/src/_packages/types.index.d.ts +2 -0
- package/esm/src/avatars/avatarAnimationScheduler.d.ts +4 -0
- package/esm/src/book-components/Chat/Chat/ChatCitationModal.d.ts +2 -0
- package/esm/src/book-components/Chat/Chat/ChatMessageItem.d.ts +4 -0
- package/esm/src/book-components/Chat/Chat/ChatMessageList.d.ts +4 -0
- package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
- package/esm/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +2 -0
- package/esm/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +3 -1
- package/esm/src/book-components/Chat/Chat/TeamToolCallModalContent.d.ts +2 -0
- package/esm/src/book-components/Chat/SourceChip/SourceChip.d.ts +6 -1
- package/esm/src/book-components/Chat/hooks/useResolvedCitationLabel.d.ts +12 -0
- package/esm/src/book-components/Chat/types/ChatMessage.d.ts +4 -0
- package/esm/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
- package/esm/src/book-components/Chat/types/CitationLabelResolver.d.ts +8 -0
- package/esm/src/book-components/Chat/utils/citationHelpers.d.ts +9 -0
- package/esm/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.d.ts +14 -0
- package/esm/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.test.d.ts +1 -0
- package/esm/src/book-components/Chat/utils/parseCitationsFromContent.d.ts +4 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/_packages/components.index.ts +2 -0
- package/src/_packages/types.index.ts +2 -0
- package/src/avatars/avatarAnimationScheduler.ts +61 -20
- package/src/avatars/visuals/octopus3d2AvatarVisual.ts +106 -21
- package/src/avatars/visuals/octopus3d3AvatarVisual.ts +131 -28
- package/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/augmentAgentModelRequirementsFromSource.ts +18 -2
- package/src/book-2.0/book-language-documentation/renderGroupedCommitmentDocumentationMarkdown.ts +7 -1
- package/src/book-components/Chat/Chat/Chat.tsx +4 -0
- package/src/book-components/Chat/Chat/ChatCitationModal.tsx +17 -3
- package/src/book-components/Chat/Chat/ChatMessageItem.tsx +22 -2
- package/src/book-components/Chat/Chat/ChatMessageList.tsx +6 -0
- package/src/book-components/Chat/Chat/ChatProps.tsx +6 -0
- package/src/book-components/Chat/Chat/ChatToolCallModal.tsx +4 -0
- package/src/book-components/Chat/Chat/ChatToolCallModalContent.tsx +4 -0
- package/src/book-components/Chat/Chat/TeamToolCallModalContent.tsx +16 -3
- package/src/book-components/Chat/Chat/useChatPostprocessedMessages.ts +13 -2
- package/src/book-components/Chat/SourceChip/SourceChip.module.css +8 -0
- package/src/book-components/Chat/SourceChip/SourceChip.tsx +19 -5
- package/src/book-components/Chat/hooks/useResolvedCitationLabel.ts +65 -0
- package/src/book-components/Chat/save/html/htmlSaveFormatDefinition.ts +315 -88
- package/src/book-components/Chat/save/react/reactSaveFormatDefinition.ts +7 -1
- package/src/book-components/Chat/types/ChatMessage.ts +5 -0
- package/src/book-components/Chat/types/ChatParticipant.ts +1 -1
- package/src/book-components/Chat/types/CitationLabelResolver.ts +9 -0
- package/src/book-components/Chat/utils/citationHelpers.ts +90 -2
- package/src/book-components/Chat/utils/createCitationFootnoteRenderModel.ts +3 -0
- package/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.ts +178 -0
- package/src/book-components/Chat/utils/parseCitationsFromContent.ts +6 -0
- package/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.ts +13 -2
- package/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.ts +1 -1
- package/src/cli/cli-commands/coder/run.ts +17 -20
- package/src/cli/cli-commands/coder/server.ts +13 -16
- package/src/cli/common/$deprecateCliCommand.ts +10 -1
- package/src/commitments/GOAL/GOAL.ts +7 -2
- package/src/commitments/LANGUAGE/LANGUAGE.ts +7 -2
- package/src/commitments/TEAM/TEAM.ts +12 -1
- package/src/commitments/USE_PROJECT/createUseProjectToolFunctions.ts +8 -1
- package/src/import-plugins/JsonFileImportPlugin.ts +15 -2
- package/src/import-plugins/TextFileImportPlugin.ts +8 -1
- package/src/llm-providers/_common/register/$registeredLlmToolsMessage.ts +6 -1
- package/src/other/templates/getTemplatesPipelineCollection.ts +681 -837
- package/src/utils/chat/chatAttachments/resolveChatAttachmentContent.ts +8 -1
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/index.umd.js +1055 -458
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -1
- package/umd/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -2
- package/umd/scripts/run-codex-prompts/server/buildCoderServerPromptResponse.d.ts +50 -0
- package/umd/scripts/run-codex-prompts/server/buildCoderServerRunState.d.ts +23 -0
- package/umd/scripts/run-codex-prompts/server/coderServerHtml.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/server/runCoderHttpServer.d.ts +13 -1
- package/umd/scripts/run-codex-prompts/server/updatePromptSection.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +1 -0
- package/umd/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +4 -0
- package/umd/scripts/run-codex-prompts/ui/renderCoderRunUi.d.ts +1 -0
- package/umd/src/_packages/components.index.d.ts +2 -0
- package/umd/src/_packages/types.index.d.ts +2 -0
- package/umd/src/avatars/avatarAnimationScheduler.d.ts +4 -0
- package/umd/src/book-components/Chat/Chat/ChatCitationModal.d.ts +2 -0
- package/umd/src/book-components/Chat/Chat/ChatMessageItem.d.ts +4 -0
- package/umd/src/book-components/Chat/Chat/ChatMessageList.d.ts +4 -0
- package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
- package/umd/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +2 -0
- package/umd/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +3 -1
- package/umd/src/book-components/Chat/Chat/TeamToolCallModalContent.d.ts +2 -0
- package/umd/src/book-components/Chat/SourceChip/SourceChip.d.ts +6 -1
- package/umd/src/book-components/Chat/hooks/useResolvedCitationLabel.d.ts +12 -0
- package/umd/src/book-components/Chat/types/ChatMessage.d.ts +4 -0
- package/umd/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
- package/umd/src/book-components/Chat/types/CitationLabelResolver.d.ts +8 -0
- package/umd/src/book-components/Chat/utils/citationHelpers.d.ts +9 -0
- package/umd/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.d.ts +14 -0
- package/umd/src/book-components/Chat/utils/decodeJsonUnicodeEscapesInMarkdownText.test.d.ts +1 -0
- package/umd/src/book-components/Chat/utils/parseCitationsFromContent.d.ts +4 -0
- package/umd/src/version.d.ts +1 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import type { string_book } from '../../../../../../../src/book-2.0/agent-source/string_book';
|
|
6
|
+
import { BookEditor } from '../../../../../../../src/book-components/BookEditor/BookEditor';
|
|
7
|
+
import { convertToBook } from '../services/bookService';
|
|
8
|
+
import { Badge } from './ui/Badge';
|
|
9
|
+
import { Button } from './ui/Button';
|
|
10
|
+
import { Spinner } from './ui/Spinner';
|
|
11
|
+
|
|
12
|
+
type Phase = 'idle' | 'loading' | 'ready' | 'error';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Converts the editor's markdown draft into canonical Book language via the `generateBook`
|
|
16
|
+
* endpoint and shows the validated result. Optional, on-demand — keeps the free-markdown
|
|
17
|
+
* editing flow intact while exposing the "real" Book artifact.
|
|
18
|
+
*/
|
|
19
|
+
export function BookLanguagePanel({ source }: { readonly source: string }) {
|
|
20
|
+
const [phase, setPhase] = useState<Phase>('idle');
|
|
21
|
+
const [book, setBook] = useState('');
|
|
22
|
+
const [isValid, setIsValid] = useState(true);
|
|
23
|
+
const [error, setError] = useState<string | null>(null);
|
|
24
|
+
const [generatedFrom, setGeneratedFrom] = useState('');
|
|
25
|
+
const [copied, setCopied] = useState(false);
|
|
26
|
+
|
|
27
|
+
async function generate() {
|
|
28
|
+
setPhase('loading');
|
|
29
|
+
setError(null);
|
|
30
|
+
try {
|
|
31
|
+
const result = await convertToBook(source);
|
|
32
|
+
setBook(result.book);
|
|
33
|
+
setIsValid(result.isValid);
|
|
34
|
+
setGeneratedFrom(source);
|
|
35
|
+
setPhase('ready');
|
|
36
|
+
} catch (caught) {
|
|
37
|
+
setError(caught instanceof Error ? caught.message : 'Převod na Book selhal.');
|
|
38
|
+
setPhase('error');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function copy() {
|
|
43
|
+
void navigator.clipboard?.writeText(book).then(() => {
|
|
44
|
+
setCopied(true);
|
|
45
|
+
setTimeout(() => setCopied(false), 1500);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const isStale = phase === 'ready' && source !== generatedFrom;
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<div className="mt-5 rounded-2xl border border-zinc-200/60 bg-white p-5 shadow-[var(--ob-shadow-sm)]">
|
|
53
|
+
<div className="flex items-center justify-between gap-3">
|
|
54
|
+
<div className="min-w-0">
|
|
55
|
+
<div className="text-sm font-semibold text-zinc-800">Book language</div>
|
|
56
|
+
<div className="mt-0.5 text-xs text-zinc-400">
|
|
57
|
+
Kanonická, validovaná podoba agenta vygenerovaná z vašeho draftu.
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
{phase === 'ready' && (
|
|
61
|
+
<Badge tone={isValid ? 'success' : 'warning'} dot>
|
|
62
|
+
{isValid ? 'Validní book' : 'Nevalidní'}
|
|
63
|
+
</Badge>
|
|
64
|
+
)}
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
{phase === 'idle' && (
|
|
68
|
+
<div className="mt-4">
|
|
69
|
+
<Button
|
|
70
|
+
variant="outline"
|
|
71
|
+
size="sm"
|
|
72
|
+
disabled={!source.trim()}
|
|
73
|
+
leadingIcon={<span aria-hidden>✨</span>}
|
|
74
|
+
onClick={() => void generate()}
|
|
75
|
+
>
|
|
76
|
+
Převést na Book language
|
|
77
|
+
</Button>
|
|
78
|
+
</div>
|
|
79
|
+
)}
|
|
80
|
+
|
|
81
|
+
{phase === 'loading' && (
|
|
82
|
+
<div className="mt-4 flex items-center gap-2 text-sm text-zinc-500">
|
|
83
|
+
<Spinner className="h-4 w-4" /> Generuji Book…
|
|
84
|
+
</div>
|
|
85
|
+
)}
|
|
86
|
+
|
|
87
|
+
{phase === 'error' && (
|
|
88
|
+
<div className="mt-4 rounded-xl border border-amber-200 bg-amber-50 px-3.5 py-2.5 text-sm text-amber-800">
|
|
89
|
+
<p>{error}</p>
|
|
90
|
+
<button
|
|
91
|
+
type="button"
|
|
92
|
+
onClick={() => void generate()}
|
|
93
|
+
className="mt-1 font-medium underline underline-offset-2"
|
|
94
|
+
>
|
|
95
|
+
Zkusit znovu
|
|
96
|
+
</button>
|
|
97
|
+
</div>
|
|
98
|
+
)}
|
|
99
|
+
|
|
100
|
+
{phase === 'ready' && (
|
|
101
|
+
<div className="mt-4">
|
|
102
|
+
<BookEditor value={book as string_book} isReadonly />
|
|
103
|
+
{isStale && (
|
|
104
|
+
<p className="mt-2 text-xs text-amber-600">
|
|
105
|
+
Draft se od převodu změnil — přegenerujte pro aktuální book.
|
|
106
|
+
</p>
|
|
107
|
+
)}
|
|
108
|
+
<div className="mt-3 flex items-center gap-2">
|
|
109
|
+
<Button
|
|
110
|
+
variant="outline"
|
|
111
|
+
size="sm"
|
|
112
|
+
leadingIcon={<span aria-hidden>↻</span>}
|
|
113
|
+
onClick={() => void generate()}
|
|
114
|
+
>
|
|
115
|
+
Přegenerovat
|
|
116
|
+
</Button>
|
|
117
|
+
<Button variant="ghost" size="sm" onClick={copy}>
|
|
118
|
+
{copied ? '✓ Zkopírováno' : 'Kopírovat'}
|
|
119
|
+
</Button>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
)}
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
}
|
package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/DropZone.tsx
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useRef, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { cn } from '../lib/cn';
|
|
6
|
+
|
|
7
|
+
type DropZoneProps = {
|
|
8
|
+
readonly onFiles: (files: readonly File[]) => void;
|
|
9
|
+
readonly hint?: string;
|
|
10
|
+
readonly disabled?: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function DropZone({ onFiles, hint, disabled }: DropZoneProps) {
|
|
14
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
15
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
16
|
+
|
|
17
|
+
function emit(fileList: FileList | null) {
|
|
18
|
+
const files = fileList ? Array.from(fileList) : [];
|
|
19
|
+
if (files.length > 0) {
|
|
20
|
+
onFiles(files);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div
|
|
26
|
+
role="button"
|
|
27
|
+
tabIndex={disabled ? -1 : 0}
|
|
28
|
+
aria-disabled={disabled}
|
|
29
|
+
onClick={() => !disabled && inputRef.current?.click()}
|
|
30
|
+
onKeyDown={(event) => {
|
|
31
|
+
if (!disabled && (event.key === 'Enter' || event.key === ' ')) {
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
inputRef.current?.click();
|
|
34
|
+
}
|
|
35
|
+
}}
|
|
36
|
+
onDragEnter={(event) => {
|
|
37
|
+
event.preventDefault();
|
|
38
|
+
if (!disabled) setIsDragging(true);
|
|
39
|
+
}}
|
|
40
|
+
onDragOver={(event) => event.preventDefault()}
|
|
41
|
+
onDragLeave={() => setIsDragging(false)}
|
|
42
|
+
onDrop={(event) => {
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
setIsDragging(false);
|
|
45
|
+
if (!disabled) emit(event.dataTransfer.files);
|
|
46
|
+
}}
|
|
47
|
+
className={cn(
|
|
48
|
+
'group flex flex-col items-center justify-center rounded-2xl border-2 border-dashed px-6 py-12 text-center transition-all duration-200',
|
|
49
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--ob-ring)] focus-visible:ring-offset-2',
|
|
50
|
+
disabled && 'cursor-not-allowed opacity-60',
|
|
51
|
+
!disabled && isDragging
|
|
52
|
+
? 'scale-[1.01] border-[color:var(--ob-accent-500)] bg-[color:var(--ob-accent-50)]'
|
|
53
|
+
: 'cursor-pointer border-zinc-300 bg-zinc-50/60 hover:border-[color:var(--ob-accent-300)] hover:bg-[color:var(--ob-accent-50)]/50',
|
|
54
|
+
)}
|
|
55
|
+
>
|
|
56
|
+
<input
|
|
57
|
+
ref={inputRef}
|
|
58
|
+
type="file"
|
|
59
|
+
multiple
|
|
60
|
+
className="hidden"
|
|
61
|
+
onChange={(event) => {
|
|
62
|
+
emit(event.target.files);
|
|
63
|
+
event.target.value = '';
|
|
64
|
+
}}
|
|
65
|
+
/>
|
|
66
|
+
<span
|
|
67
|
+
className={cn(
|
|
68
|
+
'flex h-12 w-12 items-center justify-center rounded-full text-2xl transition-colors',
|
|
69
|
+
isDragging
|
|
70
|
+
? 'bg-[color:var(--ob-accent-100)]'
|
|
71
|
+
: 'bg-white shadow-[var(--ob-shadow-sm)] group-hover:bg-[color:var(--ob-accent-100)]',
|
|
72
|
+
)}
|
|
73
|
+
aria-hidden
|
|
74
|
+
>
|
|
75
|
+
📂
|
|
76
|
+
</span>
|
|
77
|
+
<p className="mt-3 text-sm text-zinc-700">
|
|
78
|
+
<strong className="font-semibold text-zinc-900">Přetáhněte soubory sem</strong> nebo klikněte pro výběr
|
|
79
|
+
</p>
|
|
80
|
+
{hint && <p className="mt-1 text-xs text-zinc-400">{hint}</p>}
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { createId } from '../lib/id';
|
|
6
|
+
import { cn } from '../lib/cn';
|
|
7
|
+
import { agentTestService } from '../services/agentTestService';
|
|
8
|
+
import { evaluateReply, type ReplyCheck } from '../services/agentEvalService';
|
|
9
|
+
import type { KnowledgeItem } from '../types';
|
|
10
|
+
import { Badge } from './ui/Badge';
|
|
11
|
+
import { Button } from './ui/Button';
|
|
12
|
+
import { CONTROL } from './ui/Field';
|
|
13
|
+
import { Spinner } from './ui/Spinner';
|
|
14
|
+
|
|
15
|
+
type Phase = 'idle' | 'running' | 'done' | 'error';
|
|
16
|
+
|
|
17
|
+
type EmailTestRunProps = {
|
|
18
|
+
readonly email: string;
|
|
19
|
+
readonly onEmailChange: (value: string) => void;
|
|
20
|
+
readonly bookSource: string;
|
|
21
|
+
readonly knowledge: readonly KnowledgeItem[];
|
|
22
|
+
readonly onEditBook: () => void;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function RunStep({
|
|
26
|
+
icon,
|
|
27
|
+
title,
|
|
28
|
+
children,
|
|
29
|
+
done,
|
|
30
|
+
}: {
|
|
31
|
+
readonly icon: string;
|
|
32
|
+
readonly title: string;
|
|
33
|
+
readonly children?: React.ReactNode;
|
|
34
|
+
readonly done?: boolean;
|
|
35
|
+
}) {
|
|
36
|
+
return (
|
|
37
|
+
<div className="flex gap-3 border-b border-zinc-100 py-3.5 last:border-b-0">
|
|
38
|
+
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-zinc-100 text-base" aria-hidden>
|
|
39
|
+
{icon}
|
|
40
|
+
</div>
|
|
41
|
+
<div className="min-w-0 flex-1">
|
|
42
|
+
<div className="flex items-center gap-2">
|
|
43
|
+
<span className="text-[13px] font-semibold text-zinc-800">{title}</span>
|
|
44
|
+
{done && (
|
|
45
|
+
<span className="text-[color:var(--ob-accent-600)]" aria-hidden>
|
|
46
|
+
✓
|
|
47
|
+
</span>
|
|
48
|
+
)}
|
|
49
|
+
</div>
|
|
50
|
+
{children && <div className="mt-1 text-[13px] text-zinc-500">{children}</div>}
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function EmailTestRun({ email, onEmailChange, bookSource, knowledge, onEditBook }: EmailTestRunProps) {
|
|
57
|
+
const [phase, setPhase] = useState<Phase>('idle');
|
|
58
|
+
const [reply, setReply] = useState('');
|
|
59
|
+
const [error, setError] = useState<string | null>(null);
|
|
60
|
+
const [checks, setChecks] = useState<ReplyCheck[] | null>(null);
|
|
61
|
+
const [checksLoading, setChecksLoading] = useState(false);
|
|
62
|
+
|
|
63
|
+
const readyKnowledge = knowledge.filter((item) => item.status === 'ready').length;
|
|
64
|
+
|
|
65
|
+
async function run() {
|
|
66
|
+
const text = email.trim();
|
|
67
|
+
if (!text || phase === 'running') {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
setPhase('running');
|
|
71
|
+
setReply('');
|
|
72
|
+
setChecks(null);
|
|
73
|
+
setError(null);
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const result = await agentTestService.send({
|
|
77
|
+
bookSource,
|
|
78
|
+
knowledge,
|
|
79
|
+
messages: [{ id: createId(), role: 'user', content: text }],
|
|
80
|
+
});
|
|
81
|
+
setReply(result.content);
|
|
82
|
+
setPhase('done');
|
|
83
|
+
|
|
84
|
+
setChecksLoading(true);
|
|
85
|
+
try {
|
|
86
|
+
setChecks(await evaluateReply({ bookSource, customerEmail: text, reply: result.content }));
|
|
87
|
+
} catch {
|
|
88
|
+
setChecks([]);
|
|
89
|
+
} finally {
|
|
90
|
+
setChecksLoading(false);
|
|
91
|
+
}
|
|
92
|
+
} catch (caught) {
|
|
93
|
+
setError(caught instanceof Error ? caught.message : 'Testovací běh selhal.');
|
|
94
|
+
setPhase('error');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<div className="space-y-4">
|
|
100
|
+
<div className="rounded-2xl border border-zinc-200/60 bg-white p-5 shadow-[var(--ob-shadow-sm)]">
|
|
101
|
+
<label htmlFor="email-test-input" className="mb-1.5 block text-[13px] font-semibold text-zinc-700">
|
|
102
|
+
Testovací vstup — e-mail od zákazníka
|
|
103
|
+
</label>
|
|
104
|
+
<textarea
|
|
105
|
+
id="email-test-input"
|
|
106
|
+
rows={4}
|
|
107
|
+
value={email}
|
|
108
|
+
onChange={(event) => onEmailChange(event.target.value)}
|
|
109
|
+
className={cn(CONTROL, 'resize-y')}
|
|
110
|
+
/>
|
|
111
|
+
<div className="mt-3 flex items-center justify-between gap-3">
|
|
112
|
+
<span className="text-xs text-zinc-400">Vlastní text, nebo klikněte na scénář vlevo.</span>
|
|
113
|
+
<Button
|
|
114
|
+
isLoading={phase === 'running'}
|
|
115
|
+
leadingIcon={<span aria-hidden>▶</span>}
|
|
116
|
+
onClick={() => void run()}
|
|
117
|
+
disabled={email.trim().length === 0}
|
|
118
|
+
>
|
|
119
|
+
Spustit testovací běh
|
|
120
|
+
</Button>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
{phase === 'error' && (
|
|
125
|
+
<div className="rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">
|
|
126
|
+
<div className="font-medium">Testovací běh se nezdařil.</div>
|
|
127
|
+
<p className="mt-1">{error}</p>
|
|
128
|
+
<button type="button" onClick={() => void run()} className="mt-1 font-medium underline underline-offset-2">
|
|
129
|
+
Zkusit znovu
|
|
130
|
+
</button>
|
|
131
|
+
</div>
|
|
132
|
+
)}
|
|
133
|
+
|
|
134
|
+
{(phase === 'running' || phase === 'done') && (
|
|
135
|
+
<div className="overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-[var(--ob-shadow-md)]">
|
|
136
|
+
<div className="flex items-center gap-2 border-b border-zinc-200 bg-zinc-50/80 px-4 py-2.5 text-[13px] font-medium text-zinc-600">
|
|
137
|
+
<span className="relative flex h-2 w-2" aria-hidden>
|
|
138
|
+
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-400 opacity-75" />
|
|
139
|
+
<span className="relative inline-flex h-2 w-2 rounded-full bg-emerald-500" />
|
|
140
|
+
</span>
|
|
141
|
+
Záznam testovacího běhu
|
|
142
|
+
<span className="ml-auto">
|
|
143
|
+
<Badge tone="success" dot>
|
|
144
|
+
Naživo
|
|
145
|
+
</Badge>
|
|
146
|
+
</span>
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
<div className="px-4">
|
|
150
|
+
<RunStep icon="📨" title="Vstup přijat: e-mail zákazníka" done>
|
|
151
|
+
E-mail předán agentovi ke zpracování.
|
|
152
|
+
</RunStep>
|
|
153
|
+
<RunStep icon="🧠" title="Prohledání znalostí" done>
|
|
154
|
+
{readyKnowledge > 0
|
|
155
|
+
? `${readyKnowledge} ${readyKnowledge === 1 ? 'zdroj' : 'zdroje/ů'} připojeno k agentovi.`
|
|
156
|
+
: 'Bez znalostní báze — agent vychází jen z booku.'}
|
|
157
|
+
</RunStep>
|
|
158
|
+
<RunStep icon="✍️" title="Návrh odpovědi">
|
|
159
|
+
{phase === 'running' ? (
|
|
160
|
+
<span className="inline-flex items-center gap-2 text-zinc-500">
|
|
161
|
+
<Spinner className="h-4 w-4" /> Generuji odpověď…
|
|
162
|
+
</span>
|
|
163
|
+
) : (
|
|
164
|
+
<>
|
|
165
|
+
<div className="mt-1 whitespace-pre-wrap rounded-xl border border-zinc-200 bg-zinc-50 p-3.5 text-[13px] leading-relaxed text-zinc-700">
|
|
166
|
+
{reply}
|
|
167
|
+
</div>
|
|
168
|
+
<p className="mt-2 text-[11px] text-zinc-400">
|
|
169
|
+
Toto je návrh — agent nic neodesílá, odpověď schvaluje operátor.
|
|
170
|
+
</p>
|
|
171
|
+
</>
|
|
172
|
+
)}
|
|
173
|
+
</RunStep>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
{phase === 'done' && (
|
|
177
|
+
<div className="border-t border-zinc-200 bg-zinc-50/60 px-4 py-3.5">
|
|
178
|
+
<div className="mb-2 text-xs font-semibold text-zinc-500">Kontroly výsledku</div>
|
|
179
|
+
{checksLoading ? (
|
|
180
|
+
<div className="flex items-center gap-2 text-[13px] text-zinc-500">
|
|
181
|
+
<Spinner className="h-4 w-4" /> Hodnotím odpověď proti booku…
|
|
182
|
+
</div>
|
|
183
|
+
) : checks && checks.length > 0 ? (
|
|
184
|
+
<ul className="space-y-1.5">
|
|
185
|
+
{checks.map((check, index) => (
|
|
186
|
+
<li
|
|
187
|
+
key={index}
|
|
188
|
+
className={cn(
|
|
189
|
+
'flex items-start gap-2 text-[13px]',
|
|
190
|
+
check.status === 'ok' ? 'text-emerald-700' : 'text-amber-700',
|
|
191
|
+
)}
|
|
192
|
+
>
|
|
193
|
+
<span aria-hidden>{check.status === 'ok' ? '✓' : '⚠'}</span>
|
|
194
|
+
<span>{check.text}</span>
|
|
195
|
+
</li>
|
|
196
|
+
))}
|
|
197
|
+
</ul>
|
|
198
|
+
) : (
|
|
199
|
+
<div className="text-[13px] text-zinc-400">Bez připomínek.</div>
|
|
200
|
+
)}
|
|
201
|
+
|
|
202
|
+
<div className="mt-3 flex flex-wrap gap-2">
|
|
203
|
+
<Button variant="outline" size="sm" onClick={onEditBook}>
|
|
204
|
+
✏️ Upravit book
|
|
205
|
+
</Button>
|
|
206
|
+
<Button variant="ghost" size="sm" leadingIcon={<span aria-hidden>↻</span>} onClick={() => void run()}>
|
|
207
|
+
Spustit znovu
|
|
208
|
+
</Button>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
)}
|
|
212
|
+
</div>
|
|
213
|
+
)}
|
|
214
|
+
</div>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { KnowledgeItem, KnowledgeItemStatus } from '../types';
|
|
2
|
+
import { cn } from '../lib/cn';
|
|
3
|
+
import { formatFileSize } from '../lib/format';
|
|
4
|
+
import { Badge } from './ui/Badge';
|
|
5
|
+
import { IconButton } from './ui/IconButton';
|
|
6
|
+
import { Spinner } from './ui/Spinner';
|
|
7
|
+
|
|
8
|
+
function StatusChip({ status }: { readonly status: KnowledgeItemStatus }) {
|
|
9
|
+
if (status === 'uploading') {
|
|
10
|
+
return (
|
|
11
|
+
<span className="inline-flex items-center gap-1.5 text-xs text-zinc-500">
|
|
12
|
+
<Spinner className="h-3.5 w-3.5" /> Nahrávám…
|
|
13
|
+
</span>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
if (status === 'error') {
|
|
17
|
+
return <Badge tone="error">Chyba</Badge>;
|
|
18
|
+
}
|
|
19
|
+
return (
|
|
20
|
+
<Badge tone="success" dot>
|
|
21
|
+
Připraveno
|
|
22
|
+
</Badge>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type KnowledgeListProps = {
|
|
27
|
+
readonly items: readonly KnowledgeItem[];
|
|
28
|
+
readonly onRemove: (id: string) => void;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export function KnowledgeList({ items, onRemove }: KnowledgeListProps) {
|
|
32
|
+
if (items.length === 0) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<ul className="space-y-2">
|
|
38
|
+
{items.map((item) => (
|
|
39
|
+
<li
|
|
40
|
+
key={item.id}
|
|
41
|
+
className={cn(
|
|
42
|
+
'group flex items-center justify-between gap-3 rounded-xl border bg-white px-3.5 py-2.5 shadow-[var(--ob-shadow-xs)] transition-colors',
|
|
43
|
+
item.status === 'error'
|
|
44
|
+
? 'border-red-200 bg-red-50/40'
|
|
45
|
+
: 'border-zinc-200 hover:border-zinc-300',
|
|
46
|
+
)}
|
|
47
|
+
>
|
|
48
|
+
<div className="flex min-w-0 items-center gap-2.5">
|
|
49
|
+
<span
|
|
50
|
+
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-zinc-100 text-base"
|
|
51
|
+
aria-hidden
|
|
52
|
+
>
|
|
53
|
+
{item.kind === 'file' ? '📄' : '🔗'}
|
|
54
|
+
</span>
|
|
55
|
+
<div className="min-w-0">
|
|
56
|
+
<div className="truncate text-sm font-medium text-zinc-800">
|
|
57
|
+
{item.kind === 'file' ? item.name : item.url}
|
|
58
|
+
</div>
|
|
59
|
+
{item.kind === 'file' && (
|
|
60
|
+
<div className="text-xs text-zinc-400">{formatFileSize(item.size)}</div>
|
|
61
|
+
)}
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<div className="flex flex-shrink-0 items-center gap-2">
|
|
65
|
+
<StatusChip status={item.status} />
|
|
66
|
+
<IconButton
|
|
67
|
+
size="sm"
|
|
68
|
+
label="Odebrat zdroj"
|
|
69
|
+
onClick={() => onRemove(item.id)}
|
|
70
|
+
className="opacity-60 hover:text-red-600 group-hover:opacity-100"
|
|
71
|
+
>
|
|
72
|
+
×
|
|
73
|
+
</IconButton>
|
|
74
|
+
</div>
|
|
75
|
+
</li>
|
|
76
|
+
))}
|
|
77
|
+
</ul>
|
|
78
|
+
);
|
|
79
|
+
}
|
package/apps/agents-server/src/components/NewAgentDialog/ManGoNewAgentWizard/components/Logo.tsx
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Image from 'next/image';
|
|
2
|
+
|
|
3
|
+
import { cn } from '../lib/cn';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Official Promptbook logo (symbol PNG from the brand kit) + wordmark in Outfit.
|
|
7
|
+
* Per the brand rules the mark itself is never recolored — we only switch between the
|
|
8
|
+
* provided variants: `white` for dark surfaces, `blue` for light ones.
|
|
9
|
+
*/
|
|
10
|
+
export function Logo({ variant = 'white', className }: { readonly variant?: 'white' | 'blue'; readonly className?: string }) {
|
|
11
|
+
const src = variant === 'white' ? '/promptbook-logo-white.png' : '/promptbook-logo-blue.png';
|
|
12
|
+
return (
|
|
13
|
+
<span className={cn('inline-flex select-none items-center gap-2 text-lg tracking-tight', className)}>
|
|
14
|
+
<Image src={src} alt="Promptbook" width={28} height={28} className="h-7 w-7" />
|
|
15
|
+
<span className="ob-display font-medium">
|
|
16
|
+
Prompt<b className="font-semibold">book</b>
|
|
17
|
+
</span>
|
|
18
|
+
</span>
|
|
19
|
+
);
|
|
20
|
+
}
|