@promptbook/cli 0.112.0-125 → 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 +696 -941
- package/src/utils/chat/chatAttachments/resolveChatAttachmentContent.ts +8 -1
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -1
- 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
package/README.md
CHANGED
|
@@ -543,7 +543,7 @@ Prompts marked with `[-]` are not ready yet, prompts containing `@@@` are treate
|
|
|
543
543
|
- **Multi-runner execution:** `openai-codex`, `github-copilot`, `cline`, `claude-code`, `opencode`, `gemini`
|
|
544
544
|
- **Context injection:** `--agent agents/coding/developer.book --context AGENTS.md` or inline extra instructions
|
|
545
545
|
- **Reasoning control:** `--thinking-level low|medium|high|xhigh` for supported runners
|
|
546
|
-
- **
|
|
546
|
+
- **Unattended or interactive runs:** default auto mode, or `--no-auto` to wait for user confirmation before each prompt
|
|
547
547
|
- **Git safety:** clean working tree check by default, optional `--ignore-git-changes`
|
|
548
548
|
- **Opt-in remote pushes:** commits stay local unless you explicitly pass `--auto-push`
|
|
549
549
|
- **Prompt triage:** `--priority` to process only more important tasks first
|
|
@@ -565,7 +565,7 @@ npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gp
|
|
|
565
565
|
|
|
566
566
|
npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --auto-push
|
|
567
567
|
|
|
568
|
-
npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --ignore-git-changes
|
|
568
|
+
npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --ignore-git-changes
|
|
569
569
|
|
|
570
570
|
npx ts-node ./src/cli/test/ptbk.ts coder find-refactor-candidates
|
|
571
571
|
|
|
@@ -591,7 +591,7 @@ ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh -
|
|
|
591
591
|
|
|
592
592
|
ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --auto-push
|
|
593
593
|
|
|
594
|
-
ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --test npm run test --ignore-git-changes
|
|
594
|
+
ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --agent agents/coding/developer.book --context AGENTS.md --test npm run test --ignore-git-changes
|
|
595
595
|
|
|
596
596
|
ptbk coder find-refactor-candidates
|
|
597
597
|
|
|
@@ -621,7 +621,7 @@ ptbk coder verify
|
|
|
621
621
|
| `--context <text-or-file>` | Appends extra instructions inline or from a file like `AGENTS.md`. |
|
|
622
622
|
| `--test <command>` | Runs a verification command after each prompt attempt and feeds failing output back for retries. |
|
|
623
623
|
| `--thinking-level <level>` | Sets reasoning effort for supported runners. |
|
|
624
|
-
| `--no-
|
|
624
|
+
| `--no-auto` | Waits for user confirmation before each prompt instead of running automatically through the queue. |
|
|
625
625
|
| `--ignore-git-changes` | Disables the clean-working-tree guard. |
|
|
626
626
|
| `--priority <n>` | Runs only prompts at or above the given priority. |
|
|
627
627
|
| `--dry-run` | Prints which prompts are ready instead of executing them. |
|
|
@@ -634,7 +634,7 @@ ptbk coder verify
|
|
|
634
634
|
1. Initialize once with `ptbk coder init`.
|
|
635
635
|
2. Customize `prompts/templates/*.md` if needed, then create or write prompt files in `prompts/`.
|
|
636
636
|
3. Customize the starter `AGENTS.md` with repository-specific instructions, then pass `--agent agents/coding/developer.book --context AGENTS.md`.
|
|
637
|
-
4. Run
|
|
637
|
+
4. Run unattended batches by default, or pass `--no-auto` to confirm each prompt interactively.
|
|
638
638
|
5. Finish with `ptbk coder verify` so resolved prompts are archived and broken ones get explicit repair follow-ups.
|
|
639
639
|
|
|
640
640
|
|
|
@@ -41,6 +41,9 @@ ptbk agents-server start --harness github-copilot --model gpt-5.4 --thinking-lev
|
|
|
41
41
|
<a id="agents-server-env-admin-password"></a>
|
|
42
42
|
- `ADMIN_PASSWORD`: Password for the built-in `admin` login on a self-hosted Agents Server. Choose a private value before using the admin UI.
|
|
43
43
|
|
|
44
|
+
<a id="agents-server-env-session-secret"></a>
|
|
45
|
+
- `SESSION_SECRET`: HMAC signing key used to sign the session cookie. Must be set explicitly in production — the server refuses to start session signing when missing instead of falling back to a hardcoded default. Use a long random string, for example the output of `openssl rand -hex 32`. Keep it separate from `ADMIN_PASSWORD` so a leak of either credential cannot forge the other.
|
|
46
|
+
|
|
44
47
|
## Creating servers
|
|
45
48
|
|
|
46
49
|
When creating new Agents server, search across the repository for [☁]
|
|
@@ -26,6 +26,7 @@ const APP_URL = `http://127.0.0.1:${APP_PORT}`;
|
|
|
26
26
|
*/
|
|
27
27
|
const APP_E2E_ENV = {
|
|
28
28
|
ADMIN_PASSWORD: 'e2e-admin-password',
|
|
29
|
+
SESSION_SECRET: 'e2e-session-secret-must-differ-from-admin-password',
|
|
29
30
|
NEXT_DIST_DIR: '.next-e2e',
|
|
30
31
|
NEXT_PUBLIC_SITE_URL: APP_URL,
|
|
31
32
|
PTBK_AGENTS_SERVER_DATABASE: 'supabase',
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, generateMetadata } from '../agents/[agentName]/layout';
|
|
@@ -5,7 +5,7 @@ import { string_agent_name, string_book } from '@promptbook-local/types';
|
|
|
5
5
|
import { revalidatePath } from 'next/cache';
|
|
6
6
|
import { string_agent_permanent_id } from '../../../../src/types/typeAliases';
|
|
7
7
|
import { DEFAULT_NAME_POOL, NAME_POOL_METADATA_KEY, parseNamePool } from '../constants/namePool';
|
|
8
|
-
import {
|
|
8
|
+
import { NEW_AGENT_WIZARD_METADATA_KEY, parseNewAgentWizardMode } from '../constants/newAgentWizard';
|
|
9
9
|
import { getMetadata } from '../database/getMetadata';
|
|
10
10
|
import { $provideAgentCollectionForServer } from '../tools/$provideAgentCollectionForServer';
|
|
11
11
|
import { invalidateCachedActiveOrganizationSnapshots } from '../utils/agentOrganization/loadAgentOrganizationState';
|
|
@@ -73,7 +73,7 @@ export async function $getNewAgentCreationSettingsAction(): Promise<{
|
|
|
73
73
|
defaultVisibility: AgentVisibility;
|
|
74
74
|
}> {
|
|
75
75
|
return {
|
|
76
|
-
mode: parseNewAgentWizardMode(await getMetadata(
|
|
76
|
+
mode: parseNewAgentWizardMode(await getMetadata(NEW_AGENT_WIZARD_METADATA_KEY)),
|
|
77
77
|
defaultVisibility: parseAgentVisibility(await getMetadata('DEFAULT_VISIBILITY')),
|
|
78
78
|
};
|
|
79
79
|
}
|
|
@@ -67,32 +67,44 @@ export function UpdateClient() {
|
|
|
67
67
|
/**
|
|
68
68
|
* Loads the latest self-update overview from the server.
|
|
69
69
|
*/
|
|
70
|
-
const loadOverview = useCallback(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
70
|
+
const loadOverview = useCallback(
|
|
71
|
+
async (options?: { readonly isSilent?: boolean; readonly isRestartExpected?: boolean }): Promise<void> => {
|
|
72
|
+
try {
|
|
73
|
+
if (!options?.isSilent) {
|
|
74
|
+
setIsLoading(true);
|
|
75
|
+
}
|
|
76
|
+
setErrorMessage(null);
|
|
77
|
+
|
|
78
|
+
const response = await fetch('/api/admin/update', { cache: 'no-store' });
|
|
79
|
+
const payload = (await response.json()) as UpdateOverview;
|
|
80
|
+
|
|
81
|
+
if (!response.ok) {
|
|
82
|
+
throw new Error(payload.error || 'Failed to load the update overview.');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
setOverview(payload);
|
|
86
|
+
setSelectedEnvironmentId(
|
|
87
|
+
(currentSelectedEnvironmentId) => currentSelectedEnvironmentId || payload.currentEnvironment.id,
|
|
88
|
+
);
|
|
89
|
+
if (payload.job.status === 'succeeded') {
|
|
90
|
+
setSuccessMessage(getUpdateJobSuccessMessage(payload.job));
|
|
91
|
+
} else if (payload.job.status === 'failed') {
|
|
92
|
+
setSuccessMessage(null);
|
|
93
|
+
}
|
|
94
|
+
} catch (error) {
|
|
95
|
+
if (options?.isRestartExpected) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setErrorMessage(error instanceof Error ? error.message : 'Failed to load the update overview.');
|
|
100
|
+
} finally {
|
|
101
|
+
if (!options?.isSilent) {
|
|
102
|
+
setIsLoading(false);
|
|
103
|
+
}
|
|
82
104
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
currentSelectedEnvironmentId || payload.currentEnvironment.id,
|
|
87
|
-
);
|
|
88
|
-
} catch (error) {
|
|
89
|
-
setErrorMessage(error instanceof Error ? error.message : 'Failed to load the update overview.');
|
|
90
|
-
} finally {
|
|
91
|
-
if (!options?.isSilent) {
|
|
92
|
-
setIsLoading(false);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}, []);
|
|
105
|
+
},
|
|
106
|
+
[],
|
|
107
|
+
);
|
|
96
108
|
|
|
97
109
|
useEffect(() => {
|
|
98
110
|
void loadOverview();
|
|
@@ -104,7 +116,7 @@ export function UpdateClient() {
|
|
|
104
116
|
}
|
|
105
117
|
|
|
106
118
|
const interval = window.setInterval(() => {
|
|
107
|
-
void loadOverview({ isSilent: true });
|
|
119
|
+
void loadOverview({ isSilent: true, isRestartExpected: true });
|
|
108
120
|
}, 4000);
|
|
109
121
|
|
|
110
122
|
return () => {
|
|
@@ -365,10 +377,10 @@ export function UpdateClient() {
|
|
|
365
377
|
overview?.job.status === 'running'
|
|
366
378
|
? 'border-blue-200 bg-blue-50 text-blue-700'
|
|
367
379
|
: overview?.job.status === 'failed'
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
380
|
+
? 'border-rose-200 bg-rose-50 text-rose-700'
|
|
381
|
+
: overview?.job.status === 'succeeded'
|
|
382
|
+
? 'border-emerald-200 bg-emerald-50 text-emerald-700'
|
|
383
|
+
: 'border-slate-200 bg-slate-50 text-slate-500'
|
|
372
384
|
}`}
|
|
373
385
|
>
|
|
374
386
|
{overview?.job.status || 'idle'}
|
|
@@ -394,14 +406,14 @@ export function UpdateClient() {
|
|
|
394
406
|
</div>
|
|
395
407
|
</dl>
|
|
396
408
|
|
|
397
|
-
{overview?.job.
|
|
398
|
-
<div className="rounded-xl border border-
|
|
399
|
-
{overview.job
|
|
409
|
+
{overview?.job.status === 'succeeded' && (
|
|
410
|
+
<div className="rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-700">
|
|
411
|
+
{getUpdateJobSuccessMessage(overview.job)}
|
|
400
412
|
</div>
|
|
401
413
|
)}
|
|
402
|
-
{overview?.job.
|
|
403
|
-
<div className="rounded-xl border border-
|
|
404
|
-
|
|
414
|
+
{overview?.job.status === 'failed' && (
|
|
415
|
+
<div className="rounded-xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">
|
|
416
|
+
{getUpdateJobFailureMessage(overview.job)}
|
|
405
417
|
</div>
|
|
406
418
|
)}
|
|
407
419
|
{overview?.job.logFilePath && (
|
|
@@ -424,6 +436,26 @@ export function UpdateClient() {
|
|
|
424
436
|
);
|
|
425
437
|
}
|
|
426
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Builds the success message for a finished standalone VPS update.
|
|
441
|
+
*
|
|
442
|
+
* @param job - Completed update job snapshot.
|
|
443
|
+
* @returns Human-readable success message.
|
|
444
|
+
*/
|
|
445
|
+
function getUpdateJobSuccessMessage(job: UpdateJobSnapshot): string {
|
|
446
|
+
return job.currentStep || 'Standalone VPS update finished successfully.';
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Builds the failure message for a failed standalone VPS update.
|
|
451
|
+
*
|
|
452
|
+
* @param job - Failed update job snapshot.
|
|
453
|
+
* @returns Human-readable failure message.
|
|
454
|
+
*/
|
|
455
|
+
function getUpdateJobFailureMessage(job: UpdateJobSnapshot): string {
|
|
456
|
+
return job.errorMessage || 'The standalone VPS update failed. Review the installer log for details.';
|
|
457
|
+
}
|
|
458
|
+
|
|
427
459
|
/**
|
|
428
460
|
* Formats optional timestamps for the status cards.
|
|
429
461
|
*
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
useRegisterActiveAgentBreadcrumbInfo,
|
|
5
|
+
type ActiveAgentBreadcrumbInfo,
|
|
6
|
+
} from '../../../components/Header/ActiveAgentBreadcrumbContext';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Props for the active-agent breadcrumb binder.
|
|
10
|
+
*
|
|
11
|
+
* @private type of agent routes
|
|
12
|
+
*/
|
|
13
|
+
type ActiveAgentBreadcrumbBinderProps = {
|
|
14
|
+
/**
|
|
15
|
+
* Resolved active agent that should be shown in the Header breadcrumb.
|
|
16
|
+
*/
|
|
17
|
+
readonly agent: ActiveAgentBreadcrumbInfo;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Registers the active agent with the Header breadcrumb context while the agent route is mounted.
|
|
22
|
+
* Renders nothing on its own; its sole purpose is to make sure the Header can render the agent's
|
|
23
|
+
* human-readable name instead of falling back to its URL identifier.
|
|
24
|
+
*
|
|
25
|
+
* @private function of agent routes
|
|
26
|
+
*/
|
|
27
|
+
export function ActiveAgentBreadcrumbBinder({ agent }: ActiveAgentBreadcrumbBinderProps) {
|
|
28
|
+
useRegisterActiveAgentBreadcrumbInfo(agent);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
@@ -21,6 +21,7 @@ import { useSoundSystem } from '../../../components/SoundSystemProvider/SoundSys
|
|
|
21
21
|
import { fetchCalendarOAuthStatus, type CalendarOAuthStatusResponse } from '../../../utils/calendarOAuthClient';
|
|
22
22
|
import { createDefaultChatEffects } from '../../../utils/chat/createDefaultChatEffects';
|
|
23
23
|
import { executeQuickActionButton } from '../../../utils/chat/executeQuickActionButton';
|
|
24
|
+
import { resolveAgentsServerCitationLabel } from '../../../utils/chat/resolveAgentsServerCitationLabel';
|
|
24
25
|
import {
|
|
25
26
|
isChatFeedbackEnabled,
|
|
26
27
|
toChatComponentFeedbackMode,
|
|
@@ -458,6 +459,7 @@ export function AgentChatWrapper(props: AgentChatWrapperProps) {
|
|
|
458
459
|
onReset={onStartNewChat}
|
|
459
460
|
resetMode={onStartNewChat ? 'delegate' : undefined}
|
|
460
461
|
teamAgentProfiles={teamAgentProfiles}
|
|
462
|
+
resolveCitationLabel={resolveAgentsServerCitationLabel}
|
|
461
463
|
>
|
|
462
464
|
{allowFileAttachments && !fileUploadAvailability.isUploadAvailable && (
|
|
463
465
|
<FileUploadUnavailableNotice className="mx-4 mt-4" />
|
|
@@ -34,6 +34,7 @@ export const AgentChatHistoryPayloadState = {
|
|
|
34
34
|
applySnapshotStateUpdate,
|
|
35
35
|
clearActiveChatRuntimeState,
|
|
36
36
|
replaceChatInList,
|
|
37
|
+
sortUserChatSummariesByTimeDescending,
|
|
37
38
|
};
|
|
38
39
|
|
|
39
40
|
/**
|
|
@@ -175,7 +176,7 @@ function applySnapshotStateUpdate(params: {
|
|
|
175
176
|
} = params;
|
|
176
177
|
|
|
177
178
|
const reason = options.reason || 'snapshot-update';
|
|
178
|
-
setChats(snapshot.chats);
|
|
179
|
+
setChats(sortUserChatSummariesByTimeDescending(snapshot.chats));
|
|
179
180
|
if (!snapshot.activeChatId) {
|
|
180
181
|
if (options.allowSelectionAdoption !== true) {
|
|
181
182
|
logChatSelection('selection_skip_snapshot_missing_active_chat', {
|
|
@@ -616,11 +617,44 @@ function applyResolvedChatPayload(params: {
|
|
|
616
617
|
}
|
|
617
618
|
|
|
618
619
|
/**
|
|
619
|
-
*
|
|
620
|
+
* Inserts or updates one chat summary in the sidebar list while keeping the list ordered
|
|
621
|
+
* by latest activity time (newest first), so the currently selected chat stays in its
|
|
622
|
+
* chronological position instead of being hoisted to the top.
|
|
620
623
|
*
|
|
621
624
|
* @private function of useAgentChatHistoryClientState
|
|
622
625
|
*/
|
|
623
626
|
function replaceChatInList(chats: ReadonlyArray<UserChatSummary>, targetChat: UserChatSummary): Array<UserChatSummary> {
|
|
624
|
-
const
|
|
625
|
-
|
|
627
|
+
const hasExistingEntry = chats.some((chat) => chat.id === targetChat.id);
|
|
628
|
+
const updatedChats = hasExistingEntry
|
|
629
|
+
? chats.map((chat) => (chat.id === targetChat.id ? targetChat : chat))
|
|
630
|
+
: [...chats, targetChat];
|
|
631
|
+
return sortUserChatSummariesByTimeDescending(updatedChats);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Resolves the timestamp used to order one chat summary in the sidebar tray.
|
|
636
|
+
*
|
|
637
|
+
* Prefers the latest message timestamp, falls back to the chat's last update time, and finally
|
|
638
|
+
* to its creation time. This mirrors the timestamp displayed next to each chat row.
|
|
639
|
+
*
|
|
640
|
+
* @private function of useAgentChatHistoryClientState
|
|
641
|
+
*/
|
|
642
|
+
function resolveUserChatSummaryOrderTime(chat: UserChatSummary): number {
|
|
643
|
+
const timestamp = chat.lastMessageAt || chat.updatedAt || chat.createdAt;
|
|
644
|
+
const parsedTime = new Date(timestamp).getTime();
|
|
645
|
+
return Number.isFinite(parsedTime) ? parsedTime : 0;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Returns one new array of chat summaries sorted by latest activity time, newest first.
|
|
650
|
+
*
|
|
651
|
+
* @private function of useAgentChatHistoryClientState
|
|
652
|
+
*/
|
|
653
|
+
function sortUserChatSummariesByTimeDescending(
|
|
654
|
+
chats: ReadonlyArray<UserChatSummary>,
|
|
655
|
+
): Array<UserChatSummary> {
|
|
656
|
+
return [...chats].sort(
|
|
657
|
+
(leftChat, rightChat) =>
|
|
658
|
+
resolveUserChatSummaryOrderTime(rightChat) - resolveUserChatSummaryOrderTime(leftChat),
|
|
659
|
+
);
|
|
626
660
|
}
|
package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatHistorySyncOperations.ts
CHANGED
|
@@ -90,7 +90,10 @@ async function createBootstrapChatFromSnapshot(params: {
|
|
|
90
90
|
currentInitialOptimisticChatBootstrap.optimisticChatId,
|
|
91
91
|
createdChat.chat,
|
|
92
92
|
)
|
|
93
|
-
:
|
|
93
|
+
: AgentChatHistoryPayloadState.sortUserChatSummariesByTimeDescending([
|
|
94
|
+
createdChat.chat,
|
|
95
|
+
...snapshot.chats.filter((chat) => chat.id !== createdChat.chat.id),
|
|
96
|
+
]),
|
|
94
97
|
);
|
|
95
98
|
}
|
|
96
99
|
|
|
@@ -15,8 +15,9 @@ import { ChatThreadLoadingSkeleton } from '../../../../components/Skeleton/ChatT
|
|
|
15
15
|
import { useSoundSystem } from '../../../../components/SoundSystemProvider/SoundSystemProvider';
|
|
16
16
|
import { usePromptbookTheme } from '../../../../components/ThemeMode/usePromptbookTheme';
|
|
17
17
|
import { createDefaultChatEffects } from '../../../../utils/chat/createDefaultChatEffects';
|
|
18
|
-
import { downloadChatPdfFromServer } from '../../../../utils/chatExport/downloadChatPdfFromServer';
|
|
19
18
|
import { executeQuickActionButton } from '../../../../utils/chat/executeQuickActionButton';
|
|
19
|
+
import { resolveAgentsServerCitationLabel } from '../../../../utils/chat/resolveAgentsServerCitationLabel';
|
|
20
|
+
import { downloadChatPdfFromServer } from '../../../../utils/chatExport/downloadChatPdfFromServer';
|
|
20
21
|
import {
|
|
21
22
|
isChatFeedbackEnabled,
|
|
22
23
|
toChatComponentFeedbackMode,
|
|
@@ -127,6 +128,7 @@ export function CanonicalAgentChatSurface({
|
|
|
127
128
|
agentAvatarSrc: state.agentAvatarSrc,
|
|
128
129
|
agentAvatarVisualId: state.agentAvatarVisualId,
|
|
129
130
|
agentDisplayName: state.agentDisplayName,
|
|
131
|
+
agentKnowledgeSources: state.agentKnowledgeSources,
|
|
130
132
|
brandColorHex,
|
|
131
133
|
}),
|
|
132
134
|
[
|
|
@@ -135,6 +137,7 @@ export function CanonicalAgentChatSurface({
|
|
|
135
137
|
state.agentAvatarSrc,
|
|
136
138
|
state.agentAvatarVisualId,
|
|
137
139
|
state.agentDisplayName,
|
|
140
|
+
state.agentKnowledgeSources,
|
|
138
141
|
],
|
|
139
142
|
);
|
|
140
143
|
const { language, t: translateText } = useServerLanguage();
|
|
@@ -181,20 +184,17 @@ export function CanonicalAgentChatSurface({
|
|
|
181
184
|
</button>
|
|
182
185
|
);
|
|
183
186
|
}, [cancellableJob, isReadOnly, onCancelActiveJob, translateText]);
|
|
184
|
-
const handlePdfSaveFormat = useCallback(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
},
|
|
196
|
-
[],
|
|
197
|
-
);
|
|
187
|
+
const handlePdfSaveFormat = useCallback(async ({ title, messages, participants }: ChatSaveFormatHandlerOptions) => {
|
|
188
|
+
try {
|
|
189
|
+
await downloadChatPdfFromServer({
|
|
190
|
+
title,
|
|
191
|
+
messages,
|
|
192
|
+
participants,
|
|
193
|
+
});
|
|
194
|
+
} catch (error) {
|
|
195
|
+
notifyError(error instanceof Error ? error.message : 'Failed to export chat as PDF.');
|
|
196
|
+
}
|
|
197
|
+
}, []);
|
|
198
198
|
const saveFormatHandlers = useMemo(
|
|
199
199
|
() => ({
|
|
200
200
|
pdf: handlePdfSaveFormat,
|
|
@@ -266,6 +266,7 @@ export function CanonicalAgentChatSurface({
|
|
|
266
266
|
teamAgentProfiles={state.teamAgentProfiles}
|
|
267
267
|
extraActions={extraActionNodes}
|
|
268
268
|
saveFormatHandlers={saveFormatHandlers}
|
|
269
|
+
resolveCitationLabel={resolveAgentsServerCitationLabel}
|
|
269
270
|
theme={promptbookTheme}
|
|
270
271
|
>
|
|
271
272
|
{!isReadOnly && areFileAttachmentsEnabled && !fileUploadAvailability.isUploadAvailable && (
|
|
@@ -322,12 +323,14 @@ function createCanonicalAgentChatParticipants({
|
|
|
322
323
|
agentAvatarDefinition,
|
|
323
324
|
agentAvatarSrc,
|
|
324
325
|
agentAvatarVisualId,
|
|
326
|
+
agentKnowledgeSources,
|
|
325
327
|
brandColorHex,
|
|
326
328
|
}: {
|
|
327
329
|
agentDisplayName: string;
|
|
328
330
|
agentAvatarDefinition: CanonicalAgentChatPanelState['surface']['agentAvatarDefinition'];
|
|
329
331
|
agentAvatarSrc: CanonicalAgentChatPanelState['surface']['agentAvatarSrc'];
|
|
330
332
|
agentAvatarVisualId: CanonicalAgentChatPanelState['surface']['agentAvatarVisualId'];
|
|
333
|
+
agentKnowledgeSources: CanonicalAgentChatPanelState['surface']['agentKnowledgeSources'];
|
|
331
334
|
brandColorHex: string;
|
|
332
335
|
}): ReadonlyArray<ChatParticipant> {
|
|
333
336
|
return [
|
|
@@ -339,6 +342,7 @@ function createCanonicalAgentChatParticipants({
|
|
|
339
342
|
avatarVisualId: agentAvatarVisualId || undefined,
|
|
340
343
|
color: brandColorHex,
|
|
341
344
|
isMe: false,
|
|
345
|
+
knowledgeSources: agentKnowledgeSources,
|
|
342
346
|
},
|
|
343
347
|
{
|
|
344
348
|
name: 'USER',
|
package/apps/agents-server/src/app/agents/[agentName]/chat/useCanonicalAgentChatPanelState.ts
CHANGED
|
@@ -60,6 +60,23 @@ type CanonicalAgentChatFeedback = {
|
|
|
60
60
|
url: string;
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Knowledge source metadata passed from the remote agent profile into Chat participants.
|
|
65
|
+
*
|
|
66
|
+
* @private type of CanonicalAgentChatPanel
|
|
67
|
+
*/
|
|
68
|
+
type CanonicalAgentKnowledgeSource = {
|
|
69
|
+
/**
|
|
70
|
+
* Fetchable source URL.
|
|
71
|
+
*/
|
|
72
|
+
readonly url: string;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Filename used by model citations.
|
|
76
|
+
*/
|
|
77
|
+
readonly filename: string;
|
|
78
|
+
};
|
|
79
|
+
|
|
63
80
|
/**
|
|
64
81
|
* Inputs required to orchestrate the canonical durable-chat panel state.
|
|
65
82
|
*
|
|
@@ -109,6 +126,7 @@ export type CanonicalAgentChatPanelState = {
|
|
|
109
126
|
readonly agentAvatarSrc: string | null;
|
|
110
127
|
readonly agentAvatarVisualId: AvatarVisualId | null;
|
|
111
128
|
readonly agentDisplayName: string;
|
|
129
|
+
readonly agentKnowledgeSources: ReadonlyArray<CanonicalAgentKnowledgeSource>;
|
|
112
130
|
readonly elevenLabsVoiceId: string | undefined;
|
|
113
131
|
readonly initialMessage: string | undefined;
|
|
114
132
|
readonly isSpeechPlaybackEnabled: boolean;
|
|
@@ -343,6 +361,7 @@ export function useCanonicalAgentChatPanelState(
|
|
|
343
361
|
});
|
|
344
362
|
|
|
345
363
|
const agentDisplayName = useMemo(() => resolveAgentDisplayName(agent, agentName), [agent, agentName]);
|
|
364
|
+
const agentKnowledgeSources = useMemo(() => resolveAgentKnowledgeSources(agent), [agent]);
|
|
346
365
|
const resolvedAgentAvatar = useMemo(
|
|
347
366
|
() => resolveResolvedAgentAvatar(agent, agentName, agentUrl),
|
|
348
367
|
[agent, agentName, agentUrl],
|
|
@@ -400,11 +419,11 @@ export function useCanonicalAgentChatPanelState(
|
|
|
400
419
|
|
|
401
420
|
return {
|
|
402
421
|
surface: {
|
|
403
|
-
agentAvatarDefinition:
|
|
404
|
-
resolvedAgentAvatar?.type === 'visual' ? resolvedAgentAvatar.avatarDefinition : null,
|
|
422
|
+
agentAvatarDefinition: resolvedAgentAvatar?.type === 'visual' ? resolvedAgentAvatar.avatarDefinition : null,
|
|
405
423
|
agentAvatarSrc: resolvedAgentAvatar?.type === 'image' ? resolvedAgentAvatar.imageUrl : null,
|
|
406
424
|
agentAvatarVisualId: resolvedAgentAvatar?.type === 'visual' ? resolvedAgentAvatar.visualId : null,
|
|
407
425
|
agentDisplayName,
|
|
426
|
+
agentKnowledgeSources,
|
|
408
427
|
elevenLabsVoiceId: agent?.meta.voice,
|
|
409
428
|
initialMessage,
|
|
410
429
|
isSpeechPlaybackEnabled: agent?.isVoiceTtsSttEnabled ?? false,
|
|
@@ -658,15 +677,47 @@ function resolveAgentDisplayName(agent: RemoteAgent | null | undefined, agentNam
|
|
|
658
677
|
}
|
|
659
678
|
|
|
660
679
|
/**
|
|
661
|
-
* Resolves
|
|
680
|
+
* Resolves valid knowledge sources exposed by the remote agent profile.
|
|
681
|
+
*
|
|
682
|
+
* @param agent - Connected remote agent.
|
|
683
|
+
* @returns Knowledge sources usable by the shared Chat citation URL resolver.
|
|
662
684
|
*
|
|
663
685
|
* @private function of CanonicalAgentChatPanel
|
|
664
686
|
*/
|
|
665
|
-
function
|
|
687
|
+
function resolveAgentKnowledgeSources(
|
|
666
688
|
agent: RemoteAgent | null | undefined,
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
) {
|
|
689
|
+
): ReadonlyArray<CanonicalAgentKnowledgeSource> {
|
|
690
|
+
const knowledgeSources = (agent as { knowledgeSources?: unknown } | null | undefined)?.knowledgeSources;
|
|
691
|
+
if (!Array.isArray(knowledgeSources)) {
|
|
692
|
+
return [];
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
return knowledgeSources.filter(isCanonicalAgentKnowledgeSource);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Checks whether one remote profile value is a usable knowledge source.
|
|
700
|
+
*
|
|
701
|
+
* @param value - Candidate knowledge source.
|
|
702
|
+
* @returns True when the candidate has URL and filename strings.
|
|
703
|
+
*
|
|
704
|
+
* @private function of CanonicalAgentChatPanel
|
|
705
|
+
*/
|
|
706
|
+
function isCanonicalAgentKnowledgeSource(value: unknown): value is CanonicalAgentKnowledgeSource {
|
|
707
|
+
return (
|
|
708
|
+
typeof value === 'object' &&
|
|
709
|
+
value !== null &&
|
|
710
|
+
typeof (value as CanonicalAgentKnowledgeSource).url === 'string' &&
|
|
711
|
+
typeof (value as CanonicalAgentKnowledgeSource).filename === 'string'
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Resolves the avatar shown for the agent participant in the chat thread.
|
|
717
|
+
*
|
|
718
|
+
* @private function of CanonicalAgentChatPanel
|
|
719
|
+
*/
|
|
720
|
+
function resolveResolvedAgentAvatar(agent: RemoteAgent | null | undefined, agentName: string, agentUrl: string) {
|
|
670
721
|
return resolveAgentAvatar({
|
|
671
722
|
agent: {
|
|
672
723
|
agentName: agent?.agentName || agentName,
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
'use server';
|
|
2
2
|
|
|
3
3
|
import type { Metadata } from 'next';
|
|
4
|
+
import { resolveAgentRouteTarget } from '../../../utils/agentRouting/resolveAgentRouteTarget';
|
|
5
|
+
import { ActiveAgentBreadcrumbBinder } from './ActiveAgentBreadcrumbBinder';
|
|
6
|
+
import { getAgentName, getAgentProfile } from './_utils';
|
|
4
7
|
import { generateAgentMetadata } from './generateAgentMetadata';
|
|
8
|
+
import type { ActiveAgentBreadcrumbInfo } from '../../../components/Header/ActiveAgentBreadcrumbContext';
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
11
|
* Generates shared branded metadata for all pages under `/agents/[agentName]`.
|
|
@@ -13,13 +17,55 @@ export async function generateMetadata({ params }: { params: Promise<{ agentName
|
|
|
13
17
|
return generateAgentMetadata({ params });
|
|
14
18
|
}
|
|
15
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Resolves the breadcrumb info for the route's active agent so the Header can show its name
|
|
22
|
+
* instead of falling back to the URL identifier. Failures are swallowed because the layout
|
|
23
|
+
* must keep rendering even when the agent cannot be resolved (the page will handle the error).
|
|
24
|
+
*
|
|
25
|
+
* @param rawAgentIdentifier - Decoded route parameter for the active agent.
|
|
26
|
+
* @returns Breadcrumb info for the active agent or `null` when unavailable.
|
|
27
|
+
*
|
|
28
|
+
* @private function of agent routes
|
|
29
|
+
*/
|
|
30
|
+
async function tryResolveActiveAgentBreadcrumbInfo(
|
|
31
|
+
rawAgentIdentifier: string,
|
|
32
|
+
): Promise<ActiveAgentBreadcrumbInfo | null> {
|
|
33
|
+
try {
|
|
34
|
+
const routeTarget = await resolveAgentRouteTarget(rawAgentIdentifier);
|
|
35
|
+
if (!routeTarget || routeTarget.kind !== 'local') {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const agentProfile = await getAgentProfile(routeTarget.canonicalAgentId);
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
agentName: agentProfile.agentName,
|
|
43
|
+
agentHash: agentProfile.agentHash,
|
|
44
|
+
permanentId: agentProfile.permanentId,
|
|
45
|
+
meta: agentProfile.meta,
|
|
46
|
+
};
|
|
47
|
+
} catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
16
52
|
/**
|
|
17
53
|
* Shared route layout for all pages under `/agents/[agentName]`.
|
|
18
54
|
*/
|
|
19
55
|
export default async function AgentLayout({
|
|
20
56
|
children,
|
|
57
|
+
params,
|
|
21
58
|
}: Readonly<{
|
|
22
59
|
children: React.ReactNode;
|
|
60
|
+
params: Promise<{ agentName: string }>;
|
|
23
61
|
}>) {
|
|
24
|
-
|
|
62
|
+
const rawAgentIdentifier = await getAgentName(params);
|
|
63
|
+
const activeAgentBreadcrumbInfo = await tryResolveActiveAgentBreadcrumbInfo(rawAgentIdentifier);
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<>
|
|
67
|
+
{activeAgentBreadcrumbInfo && <ActiveAgentBreadcrumbBinder agent={activeAgentBreadcrumbInfo} />}
|
|
68
|
+
{children}
|
|
69
|
+
</>
|
|
70
|
+
);
|
|
25
71
|
}
|