From 3b1288097da457752cc4b6624f4ea53e22c4be32 Mon Sep 17 00:00:00 2001
From: arc53-machine <232052973+arc53-machine@users.noreply.github.com>
Date: Mon, 28 Sep 2026 22:31:26 +0100
Subject: [PATCH] One vocabulary: Knowledge, tools, and connectors in plain
words
- Sources (the collection) are called Knowledge: the settings page (now
/settings/knowledge; /settings/sources redirects), the composer and
agent pickers, Add knowledge, and "syncs into Knowledge" on connectors.
Citations keep "sources". All seven locales.
- Connector cards describe what they do ("Syncs into Knowledge", "Looks
things up", "Takes actions") and drop publisher labels ("Built in",
"Preset"). Filters read "Files & storage" and "Docs & wikis" so
"knowledge" means one thing.
- Custom tools are tools: "Add custom tool". The agent picker no longer
splits built-in tools into "Built-in" and "Default".
- Confluence is one card: syncing pages into Knowledge and the Jira &
Confluence MCP actions (part_of on the preset) share a page. The part
shows on its own when Confluence sync is not set up.
---
docs/content/Guides/Connectors.mdx | 4 +-
docsgpt/connectors/catalog.py | 5 ++
docsgpt/connectors/presets/mcp.yaml | 4 +-
.../components/SourcesPopoverFooter.test.tsx | 2 +-
.../src/components/SourcesPopoverFooter.tsx | 2 +-
.../message-input/SourcesTrigger.tsx | 2 +-
frontend/src/connectors/ConnectionDrawer.tsx | 73 ++++++++++++++---
frontend/src/connectors/ConnectorCard.tsx | 19 ++---
frontend/src/connectors/types.ts | 2 +
frontend/src/locale/de.json | 64 ++++++++-------
frontend/src/locale/en.json | 64 ++++++++-------
frontend/src/locale/es.json | 64 ++++++++-------
frontend/src/locale/jp.json | 64 ++++++++-------
frontend/src/locale/ru.json | 64 ++++++++-------
frontend/src/locale/zh-TW.json | 64 ++++++++-------
frontend/src/locale/zh.json | 64 ++++++++-------
frontend/src/navigation/sections.ts | 2 +-
frontend/src/settings/Connectors.test.tsx | 78 ++++++++++++++++++-
frontend/src/settings/Connectors.tsx | 43 +++++++++-
frontend/src/settings/index.tsx | 12 ++-
tests/connectors/test_catalog.py | 10 +++
21 files changed, 462 insertions(+), 244 deletions(-)
diff --git a/docs/content/Guides/Connectors.mdx b/docs/content/Guides/Connectors.mdx
index 6cb651e4..5cd658c8 100644
--- a/docs/content/Guides/Connectors.mdx
+++ b/docs/content/Guides/Connectors.mdx
@@ -1,6 +1,6 @@
---
title: Connectors
-description: Connect DocsGPT to the services your team uses. One connection can sync content into Sources and give agents tools, with credentials encrypted on the server.
+description: Connect DocsGPT to the services your team uses. One connection can sync content into Knowledge and give agents tools, with credentials encrypted on the server.
---
import { Callout } from 'nextra/components'
@@ -20,7 +20,7 @@ Open **Settings > Connectors**. Filters narrow the list by category, and **Conne
2. Choose what the connection sets up. File services offer a synced source (pick files or folders, then how often to sync: never, daily, weekly or monthly). Tool services create their tools right away.
3. Adjust what the tools may do. Each action is **Read** or **Write**, and each can be **Always allow**, **Needs approval** or **Off**. Writes default to needing approval.
-The **Add Source** and **Add Tool** dialogs, the composer's Sources and Tools menus, and the agent builder all start the same flow, and list tools grouped by the connection they use.
+**Knowledge** (formerly Sources) is what the assistant searches: uploads, links, and content synced from your connections. The **Add knowledge** and **Add Tool** dialogs, the composer's Knowledge and Tools menus, and the agent builder all start the same flow, and list tools grouped by the connection they use. A service offered two ways appears as one card: Confluence syncs pages into Knowledge and, through **Jira & Confluence**, lets agents search and update Jira and Confluence.
Click a connected card to see its account, the sources and tools that use it, and to **Reconnect** or **Disconnect**. Disconnecting keeps a source's indexed content but stops its sync.
diff --git a/docsgpt/connectors/catalog.py b/docsgpt/connectors/catalog.py
index dcc4e39a..1f0f5925 100644
--- a/docsgpt/connectors/catalog.py
+++ b/docsgpt/connectors/catalog.py
@@ -76,6 +76,8 @@ class ConnectorDefinition:
publisher: ``built_in``, ``preset`` or ``custom``.
docs_url: Setup guide for admins.
oauth_scopes: Scopes an MCP preset requests.
+ part_of: Another connector this one is shown under, for one service
+ offered two ways (the Atlassian MCP preset under Confluence).
"""
key: str
@@ -96,6 +98,7 @@ class ConnectorDefinition:
publisher: str = "built_in"
docs_url: Optional[str] = None
oauth_scopes: tuple[str, ...] = ()
+ part_of: Optional[str] = None
@property
def missing_settings(self) -> list[str]:
@@ -132,6 +135,7 @@ class ConnectorDefinition:
"publisher": self.publisher,
"docs_url": self.docs_url,
"oauth_scopes": list(self.oauth_scopes),
+ "part_of": self.part_of,
}
@@ -328,6 +332,7 @@ def _load_presets(path: Optional[Path] = None) -> tuple[ConnectorDefinition, ...
publisher="preset",
docs_url=entry.get("docs_url"),
oauth_scopes=tuple(entry.get("oauth_scopes") or ()),
+ part_of=entry.get("part_of"),
)
)
return tuple(presets)
diff --git a/docsgpt/connectors/presets/mcp.yaml b/docsgpt/connectors/presets/mcp.yaml
index c9642c80..96d984c9 100644
--- a/docsgpt/connectors/presets/mcp.yaml
+++ b/docsgpt/connectors/presets/mcp.yaml
@@ -31,10 +31,12 @@
docs_url: https://linear.app/docs/mcp
- key: mcp:atlassian
- name: Atlassian (Jira and Confluence)
+ name: Jira & Confluence
description: Search and update Jira issues and Confluence pages.
icon: atlassian
category: dev
+ # Shown on the Confluence card, next to syncing pages into Knowledge.
+ part_of: confluence
mcp_url: https://mcp.atlassian.com/v1/mcp
auth_kind: mcp_oauth
capabilities: [read, write]
diff --git a/frontend/src/components/SourcesPopoverFooter.test.tsx b/frontend/src/components/SourcesPopoverFooter.test.tsx
index 4ed7e827..5e7db7b5 100644
--- a/frontend/src/components/SourcesPopoverFooter.test.tsx
+++ b/frontend/src/components/SourcesPopoverFooter.test.tsx
@@ -54,7 +54,7 @@ describe('SourcesPopoverFooter', () => {
it('renders the sources link as an inline link Button', async () => {
await renderFooter();
const [link, connect] = Array.from(container.querySelectorAll('a'));
- expect(link.getAttribute('href')).toBe('/settings/sources');
+ expect(link.getAttribute('href')).toBe('/settings/knowledge');
expect(connect.getAttribute('href')).toBe(
'/settings/connectors?capability=sync',
);
diff --git a/frontend/src/components/SourcesPopoverFooter.tsx b/frontend/src/components/SourcesPopoverFooter.tsx
index 27378bad..441de6f1 100644
--- a/frontend/src/components/SourcesPopoverFooter.tsx
+++ b/frontend/src/components/SourcesPopoverFooter.tsx
@@ -26,7 +26,7 @@ export default function SourcesPopoverFooter({
-
+
{t('settings.sources.goToSources')}
diff --git a/frontend/src/components/message-input/SourcesTrigger.tsx b/frontend/src/components/message-input/SourcesTrigger.tsx
index 448fe4d4..c0837e6f 100644
--- a/frontend/src/components/message-input/SourcesTrigger.tsx
+++ b/frontend/src/components/message-input/SourcesTrigger.tsx
@@ -69,7 +69,7 @@ export default function SourcesTrigger({
: t('conversation.sources.selectedCount', {
count: selectedDocs.length,
})
- : t('conversation.sources.title')}
+ : t('conversation.sources.knowledge')}
}
diff --git a/frontend/src/connectors/ConnectionDrawer.tsx b/frontend/src/connectors/ConnectionDrawer.tsx
index c820027b..ffc9d510 100644
--- a/frontend/src/connectors/ConnectionDrawer.tsx
+++ b/frontend/src/connectors/ConnectionDrawer.tsx
@@ -381,10 +381,13 @@ function AccountSection({
*/
export default function ConnectionDrawer({
connector,
+ parts = [],
onClose,
onConnect,
}: {
connector: ConnectorDefinition | null;
+ /** The same service offered another way, shown here (Jira & Confluence). */
+ parts?: ConnectorDefinition[];
onClose: () => void;
onConnect: (connector: ConnectorDefinition, options?: LaunchOptions) => void;
}) {
@@ -401,8 +404,9 @@ export default function ConnectionDrawer({
);
const [toRemove, setToRemove] = useState
(null);
+ const keys = [connector?.key, ...parts.map((part) => part.key)];
const accountIds = connections
- .filter((connection) => connection.connector_key === connector?.key)
+ .filter((connection) => keys.includes(connection.connector_key))
.map((connection) => `${connection.id}:${connection.status}`)
.join(',');
@@ -458,8 +462,12 @@ export default function ConnectionDrawer({
const reconnect = (detail: ConnectionDetail) => {
if (!connector) return;
+ // A part's account (Jira & Confluence under Confluence) reconnects
+ // through its own connector.
+ const target =
+ parts.find((part) => part.key === detail.connector_key) ?? connector;
const mcpTool = detail.tools.find((tool) => tool.name === 'mcp_tool');
- onConnect(connector, {
+ onConnect(target, {
mode: 'reconnect',
connectionId: detail.id,
mcpServer:
@@ -497,6 +505,9 @@ export default function ConnectionDrawer({
if (!connector) return null;
const name = connectorName(t, connector);
+ const ownDetails = details.filter(
+ (detail) => detail.connector_key === connector.key,
+ );
return (
<>
@@ -509,16 +520,11 @@ export default function ConnectionDrawer({
>
{/* pr-12 keeps the header clear of the close X. */}
-
+
-
-
{name}
-
- {t(`settings.connectors.publisher.${connector.publisher}`)}
-
-
+
{name}
{connectorDescription(t, connector)}
@@ -544,7 +550,7 @@ export default function ConnectionDrawer({
size="xs"
title={t('settings.connectors.detail.accounts')}
actions={
- connector.available && details.length > 0 ? (
+ connector.available && ownDetails.length > 0 ? (
}
/>
- ) : details.length === 0 ? (
+ ) : ownDetails.length === 0 ? (
) : (
- {details.map((detail) => (
+ {ownDetails.map((detail) => (
)}
+
+ {parts.map((part) => {
+ const partDetails = details.filter(
+ (detail) => detail.connector_key === part.key,
+ );
+ return (
+
+ onConnect(part)}
+ >
+ {t('settings.connectors.status.connect')}
+
+ ) : undefined
+ }
+ />
+
+ {partDetails.map((detail) => (
+
+ onConnect(part, { mode: 'sync', connectionId: d.id })
+ }
+ onRefreshTools={refreshTools}
+ />
+ ))}
+
+ );
+ })}
diff --git a/frontend/src/connectors/ConnectorCard.tsx b/frontend/src/connectors/ConnectorCard.tsx
index 9f73188a..30c14b12 100644
--- a/frontend/src/connectors/ConnectorCard.tsx
+++ b/frontend/src/connectors/ConnectorCard.tsx
@@ -22,10 +22,10 @@ export function CapabilityBadges({
return (
{capabilities.map((capability) => (
- // Capabilities are categories, not states: neutral, so the status
- // hues stay free for the state badge (DESIGN.md "Colour tokens").
+ // What it does, in plain words; categories, not states, so neutral and
+ // the status hues stay free for the state badge.
- {t(`settings.connectors.capability.${capability}`)}
+ {t(`settings.connectors.capabilityPlain.${capability}`)}
))}
@@ -108,16 +108,9 @@ export default function ConnectorCard({
>
-
-
- {name}
-
- {connector.publisher !== 'built_in' && (
-
- {t(`settings.connectors.publisher.${connector.publisher}`)}
-
- )}
-
+
+ {name}
+
{connectorDescription(t, connector)}
diff --git a/frontend/src/connectors/types.ts b/frontend/src/connectors/types.ts
index 557e4491..0d17d464 100644
--- a/frontend/src/connectors/types.ts
+++ b/frontend/src/connectors/types.ts
@@ -51,6 +51,8 @@ export type ConnectorDefinition = {
publisher: 'built_in' | 'preset' | 'custom';
docs_url: string | null;
oauth_scopes: string[];
+ /** Shown under this connector's card (one service offered two ways). */
+ part_of?: string | null;
available: boolean;
disabled: boolean;
needs_setup: boolean;
diff --git a/frontend/src/locale/de.json b/frontend/src/locale/de.json
index 1bfaebdc..7c8970a5 100644
--- a/frontend/src/locale/de.json
+++ b/frontend/src/locale/de.json
@@ -98,15 +98,15 @@
"sources": {
"title": "Hier kannst du alle verfügbaren Quelldateien verwalten, die dir zur Verfügung stehen und die du hochgeladen hast.",
"subtitle": "Inhalte, die DocsGPT durchsuchen und zitieren kann: Uploads, Websites, Wikis und aus deinen Verbindungen synchronisierte Inhalte.",
- "label": "Quellen",
+ "label": "Wissen",
"name": "Quellenname",
"date": "Vektor-Datum",
"type": "Typ",
"tokenUsage": "Token-Verbrauch",
- "noData": "Keine vorhandenen Quellen",
+ "noData": "Noch kein Wissen",
"searchPlaceholder": "Suchen...",
"addNew": "Neu hinzufügen",
- "addSource": "Quelle hinzufügen",
+ "addSource": "Wissen hinzufügen",
"addChunk": "Chunk hinzufügen",
"preLoaded": "Vorgeladen",
"private": "Privat",
@@ -294,7 +294,7 @@
"chunks": "Chunks",
"noChunks": "Keine Chunks gefunden",
"noChunksAlt": "Keine Chunks gefunden",
- "goToSources": "Zu den Quellen",
+ "goToSources": "Zum Wissen",
"uploadNew": "Neu hochladen",
"noResults": "Keine Ergebnisse gefunden",
"fileName": "Name",
@@ -1093,9 +1093,9 @@
},
"connectors": {
"label": "Konnektoren",
- "subtitle": "Verbinde DocsGPT mit den Diensten, die dein Team nutzt. Eine Verbindung kann Inhalte in Quellen synchronisieren und Agenten Werkzeuge geben.",
+ "subtitle": "Verbinde DocsGPT mit den Diensten, die dein Team nutzt. Eine Verbindung kann Inhalte ins Wissen synchronisieren und Agenten Werkzeuge geben.",
"search": "Konnektoren suchen...",
- "addCustom": "Eigenen Konnektor hinzufügen",
+ "addCustom": "Eigenes Werkzeug hinzufügen",
"custom": {
"custom_mcp": "MCP-Server",
"custom_openapi": "OpenAPI / REST"
@@ -1104,8 +1104,8 @@
"categories": {
"all": "Alle",
"connected": "Verbunden",
- "files": "Dateien und Dokumente",
- "knowledge": "Wissensdatenbanken",
+ "files": "Dateien & Speicher",
+ "knowledge": "Dokus & Wikis",
"dev": "Entwicklerwerkzeuge",
"messaging": "Nachrichten",
"database": "Datenbanken",
@@ -1139,11 +1139,11 @@
"custom": "Eigener"
},
"descriptions": {
- "google_drive": "Docs, Tabellen und PDFs in Quellen synchronisieren.",
- "share_point": "Dateien aus SharePoint-Sites und OneDrive in Quellen synchronisieren.",
- "confluence": "Confluence-Bereiche und -Seiten in Quellen synchronisieren.",
- "s3": "Dokumente aus einem S3-Bucket in Quellen synchronisieren.",
- "reddit": "Reddit-Beiträge zu deinen Suchen in Quellen synchronisieren.",
+ "google_drive": "Docs, Tabellen und PDFs ins Wissen synchronisieren.",
+ "share_point": "Dateien aus SharePoint-Sites und OneDrive ins Wissen synchronisieren.",
+ "confluence": "Confluence-Bereiche und -Seiten ins Wissen synchronisieren.",
+ "s3": "Dokumente aus einem S3-Bucket ins Wissen synchronisieren.",
+ "reddit": "Reddit-Beiträge zu deinen Suchen ins Wissen synchronisieren.",
"brave": "Web und Bilder mit der Brave Search API durchsuchen.",
"telegram": "Nachrichten und Bilder an einen Telegram-Chat senden.",
"ntfy": "Push-Benachrichtigungen über einen ntfy-Server senden.",
@@ -1168,7 +1168,7 @@
"accounts": "Konten",
"connectedAs": "Verbunden als {{account}}",
"connectAnother": "Weiteres Konto verbinden",
- "sources": "Quellen aus dieser Verbindung",
+ "sources": "Wissen aus dieser Verbindung",
"tools": "Werkzeuge aus dieser Verbindung",
"noAccounts": "Noch kein Konto verbunden.",
"failed": "Diese Verbindung konnte nicht geladen werden.",
@@ -1284,17 +1284,22 @@
},
"createFailed": "Der Konnektor konnte nicht hinzugefügt werden. Versuche es erneut.",
"capabilityFilter": {
- "sync": "Angezeigt werden Konnektoren, die Inhalte in Quellen synchronisieren.",
+ "sync": "Angezeigt werden Konnektoren, die Inhalte ins Wissen synchronisieren.",
"tools": "Angezeigt werden Konnektoren, die Agenten Werkzeuge geben.",
"showAll": "Alle anzeigen"
+ },
+ "capabilityPlain": {
+ "sync": "Synchronisiert ins Wissen",
+ "read": "Schlägt nach",
+ "write": "Führt Aktionen aus"
}
}
},
"modals": {
"uploadDoc": {
- "label": "Quelle hinzufügen",
+ "label": "Wissen hinzufügen",
"select": "Wähle, wie du dein Dokument zu DocsGPT hochladen möchtest",
- "selectSource": "Quelle hinzufügen",
+ "selectSource": "Wissen hinzufügen",
"selectedFiles": "Ausgewählte Dateien",
"noFilesSelected": "Keine Dateien ausgewählt",
"file": "Vom Gerät hochladen",
@@ -1309,7 +1314,7 @@
"filesRejected": "Nicht hinzugefügt (größer als 25 MB oder kein unterstützter Dateityp): {{files}}",
"uploadedFiles": "Hochgeladene Dateien",
"cancel": "Abbrechen",
- "train": "Quelle hinzufügen",
+ "train": "Zum Wissen hinzufügen",
"create": "Erstellen",
"link": "Link",
"urlLink": "URL-Link",
@@ -1659,17 +1664,18 @@
},
"sources": {
"title": "Quellen",
- "text": "Wähle deine Quellen",
+ "text": "Wissen auswählen",
"link": "Quellen-Link",
"view_more_one": "{{count}} weitere Quelle",
"view_more_other": "{{count}} weitere Quellen",
- "noSourcesAvailable": "Keine Quellen verfügbar",
+ "noSourcesAvailable": "Noch kein Wissen",
"selectedCount": "{{count}} Quellen ausgewählt",
"groupOwn": "Deine Quellen",
"groupTeam": "Mit dem Team geteilt",
"connectMore": "Weitere verbinden",
"fromConnector": "Aus {{name}}",
- "fromConnectorTitle": "Aus {{name}}: {{title}}"
+ "fromConnectorTitle": "Aus {{name}}: {{title}}",
+ "knowledge": "Wissen"
},
"attachments": {
"attach": "Anhängen",
@@ -1894,7 +1900,7 @@
"placeholders": {
"agentName": "Agentenname",
"describeAgent": "Beschreibe deinen Agenten",
- "selectSources": "Quellen auswählen",
+ "selectSources": "Wissen auswählen",
"chunksPerQuery": "Chunks pro Anfrage",
"selectType": "Typ auswählen",
"selectTools": "Werkzeuge auswählen",
@@ -1904,19 +1910,19 @@
"enterRequestLimit": "Anfrage-Limit eingeben"
},
"sourcePopup": {
- "title": "Quellen auswählen",
- "searchPlaceholder": "Quellen suchen...",
- "noOptionsMessage": "Keine Quellen verfügbar",
+ "title": "Wissen auswählen",
+ "searchPlaceholder": "Wissen durchsuchen...",
+ "noOptionsMessage": "Noch kein Wissen",
"groupOwn": "Deine Quellen",
"groupTeam": "Mit dem Team geteilt",
- "noSourceHint": "Optional. Ohne Quelle antwortet der Agent nur anhand des Modells und seiner Werkzeuge."
+ "noSourceHint": "Optional. Ohne Wissen antwortet der Agent nur mit dem Modell und seinen Werkzeugen."
},
"toolsPopup": {
"title": "Werkzeuge auswählen",
"searchPlaceholder": "Werkzeuge suchen...",
"noOptionsMessage": "Keine Werkzeuge verfügbar",
"groupBuiltin": "Integriert",
- "groupDefault": "Standard",
+ "groupDefault": "Integriert",
"groupCustom": "Benutzerdefiniert",
"groupConnection": "{{name}} · {{account}}"
},
@@ -1938,7 +1944,7 @@
"defaultModel": "Standardmodell",
"name": "Name",
"description": "Beschreibung",
- "sources": "Quellen",
+ "sources": "Wissen",
"avatar": "Avatar"
},
"advanced": {
@@ -2317,7 +2323,7 @@
"outputVariable": "Ausgabevariable",
"outputVariablePlaceholder": "Variablenname für die Ausgabe",
"streamToUser": "Ausgabe an Nutzer streamen",
- "sources": "Quellen",
+ "sources": "Wissen",
"documents": "Dokumente",
"documentsHint": "Dokumente, die diesem Agenten aus Uploads oder vorgelagerten Knoten übergeben werden.",
"filePassing": "Dateiübergabe",
diff --git a/frontend/src/locale/en.json b/frontend/src/locale/en.json
index 2281af8f..53ea673c 100644
--- a/frontend/src/locale/en.json
+++ b/frontend/src/locale/en.json
@@ -102,15 +102,15 @@
"sources": {
"title": "Here you can manage all of the source file that are available to you and those you have uploaded.",
"subtitle": "Content DocsGPT can search and cite: uploads, websites, wikis and content synced from your connections.",
- "label": "Sources",
+ "label": "Knowledge",
"name": "Source Name",
"date": "Vector Date",
"type": "Type",
"tokenUsage": "Token Usage",
- "noData": "No existing Sources",
+ "noData": "No knowledge yet",
"searchPlaceholder": "Search...",
"addNew": "Add New",
- "addSource": "Add Source",
+ "addSource": "Add knowledge",
"addChunk": "Add Chunk",
"preLoaded": "Pre-loaded",
"private": "Private",
@@ -299,7 +299,7 @@
"chunks": "Chunks",
"noChunks": "No chunks found",
"noChunksAlt": "No chunks found",
- "goToSources": "Go to Sources",
+ "goToSources": "Go to Knowledge",
"uploadNew": "Upload new",
"noResults": "No results found",
"fileName": "Name",
@@ -1099,9 +1099,9 @@
},
"connectors": {
"label": "Connectors",
- "subtitle": "Connect DocsGPT to the services your team uses. A connection can sync content into Sources and give agents tools.",
+ "subtitle": "Connect DocsGPT to the services your team uses. A connection can sync content into Knowledge and give agents tools.",
"search": "Search connectors...",
- "addCustom": "Add custom connector",
+ "addCustom": "Add custom tool",
"custom": {
"custom_mcp": "MCP server",
"custom_openapi": "OpenAPI / REST"
@@ -1110,8 +1110,8 @@
"categories": {
"all": "All",
"connected": "Connected",
- "files": "Files and docs",
- "knowledge": "Knowledge bases",
+ "files": "Files & storage",
+ "knowledge": "Docs & wikis",
"dev": "Developer tools",
"messaging": "Messaging",
"database": "Databases",
@@ -1145,11 +1145,11 @@
"custom": "Custom"
},
"descriptions": {
- "google_drive": "Sync Docs, Sheets and PDFs into Sources.",
- "share_point": "Sync files from SharePoint sites and OneDrive into Sources.",
- "confluence": "Sync Confluence spaces and pages into Sources.",
- "s3": "Sync documents from an S3 bucket into Sources.",
- "reddit": "Sync Reddit posts that match your searches into Sources.",
+ "google_drive": "Sync Docs, Sheets and PDFs into Knowledge.",
+ "share_point": "Sync files from SharePoint sites and OneDrive into Knowledge.",
+ "confluence": "Sync Confluence spaces and pages into Knowledge.",
+ "s3": "Sync documents from an S3 bucket into Knowledge.",
+ "reddit": "Sync Reddit posts that match your searches into Knowledge.",
"brave": "Search the web and images with the Brave Search API.",
"telegram": "Send messages and images to a Telegram chat.",
"ntfy": "Send push notifications through an ntfy server.",
@@ -1174,7 +1174,7 @@
"accounts": "Accounts",
"connectedAs": "Connected as {{account}}",
"connectAnother": "Connect another account",
- "sources": "Sources from this connection",
+ "sources": "Knowledge from this connection",
"tools": "Tools from this connection",
"noAccounts": "No account connected yet.",
"failed": "Could not load this connection.",
@@ -1290,17 +1290,22 @@
},
"createFailed": "Could not add the connector. Try again.",
"capabilityFilter": {
- "sync": "Showing connectors that sync content into Sources.",
+ "sync": "Showing connectors that sync content into Knowledge.",
"tools": "Showing connectors that give agents tools.",
"showAll": "Show all"
+ },
+ "capabilityPlain": {
+ "sync": "Syncs into Knowledge",
+ "read": "Looks things up",
+ "write": "Takes actions"
}
}
},
"modals": {
"uploadDoc": {
- "label": "Add a source",
+ "label": "Add knowledge",
"select": "Choose how to upload your document to DocsGPT",
- "selectSource": "Add a source",
+ "selectSource": "Add knowledge",
"selectedFiles": "Selected Files",
"noFilesSelected": "No files selected",
"file": "Upload from device",
@@ -1315,7 +1320,7 @@
"filesRejected": "Not added (over 25 MB or not a supported type): {{files}}",
"uploadedFiles": "Uploaded Files",
"cancel": "Cancel",
- "train": "Add source",
+ "train": "Add to Knowledge",
"create": "Create",
"link": "Link",
"urlLink": "URL Link",
@@ -1665,17 +1670,18 @@
},
"sources": {
"title": "Sources",
- "text": "Choose Your Sources",
+ "text": "Choose knowledge",
"link": "Source link",
"view_more_one": "{{count}} more source",
"view_more_other": "{{count}} more sources",
- "noSourcesAvailable": "No sources available",
+ "noSourcesAvailable": "No knowledge yet",
"selectedCount": "{{count}} sources selected",
"groupOwn": "Your sources",
"groupTeam": "Shared with team",
"connectMore": "Connect more",
"fromConnector": "From {{name}}",
- "fromConnectorTitle": "From {{name}}: {{title}}"
+ "fromConnectorTitle": "From {{name}}: {{title}}",
+ "knowledge": "Knowledge"
},
"attachments": {
"attach": "Attach",
@@ -1910,7 +1916,7 @@
"placeholders": {
"agentName": "Agent name",
"describeAgent": "Describe your agent",
- "selectSources": "Select sources",
+ "selectSources": "Select knowledge",
"chunksPerQuery": "Chunks per query",
"selectType": "Select type",
"selectTools": "Select tools",
@@ -1920,19 +1926,19 @@
"enterRequestLimit": "Enter request limit"
},
"sourcePopup": {
- "title": "Select Sources",
- "searchPlaceholder": "Search sources...",
- "noOptionsMessage": "No sources available",
+ "title": "Select knowledge",
+ "searchPlaceholder": "Search knowledge...",
+ "noOptionsMessage": "No knowledge yet",
"groupOwn": "Your sources",
"groupTeam": "Shared with team",
- "noSourceHint": "Optional. Without a source the agent answers from the model and its tools only."
+ "noSourceHint": "Optional. Without knowledge the agent answers from the model and its tools only."
},
"toolsPopup": {
"title": "Select Tools",
"searchPlaceholder": "Search tools...",
"noOptionsMessage": "No tools available",
"groupBuiltin": "Built-in",
- "groupDefault": "Default",
+ "groupDefault": "Built-in",
"groupCustom": "Custom",
"groupConnection": "{{name}} · {{account}}"
},
@@ -1954,7 +1960,7 @@
"defaultModel": "Default Model",
"name": "Name",
"description": "Description",
- "sources": "Sources",
+ "sources": "Knowledge",
"avatar": "Avatar"
},
"advanced": {
@@ -2352,7 +2358,7 @@
"outputVariable": "Output Variable",
"outputVariablePlaceholder": "Variable name for output",
"streamToUser": "Stream output to user",
- "sources": "Sources",
+ "sources": "Knowledge",
"documents": "Documents",
"documentsHint": "Documents passed to this agent from uploads or upstream nodes.",
"filePassing": "File passing",
diff --git a/frontend/src/locale/es.json b/frontend/src/locale/es.json
index 767ce974..37cc4b8b 100644
--- a/frontend/src/locale/es.json
+++ b/frontend/src/locale/es.json
@@ -98,15 +98,15 @@
"sources": {
"title": "Aquí puedes gestionar todos los archivos fuente que están disponibles para ti y los que has subido.",
"subtitle": "Contenido que DocsGPT puede buscar y citar: archivos subidos, sitios web, wikis y contenido sincronizado desde tus conexiones.",
- "label": "Fuentes",
+ "label": "Conocimiento",
"name": "Nombre de la Fuente",
"date": "Fecha de Vector",
"type": "Tipo",
"tokenUsage": "Uso de Tokens",
- "noData": "No hay fuentes existentes",
+ "noData": "Aún no hay conocimiento",
"searchPlaceholder": "Buscar...",
"addNew": "Agregar Nuevo",
- "addSource": "Agregar Fuente",
+ "addSource": "Añadir conocimiento",
"addChunk": "Agregar Fragmento",
"preLoaded": "Precargado",
"private": "Privado",
@@ -294,7 +294,7 @@
"chunks": "Fragmentos",
"noChunks": "No se encontraron fragmentos",
"noChunksAlt": "No se encontraron fragmentos",
- "goToSources": "Ir a Fuentes",
+ "goToSources": "Ir a Conocimiento",
"uploadNew": "Subir nuevo",
"noResults": "No se encontraron resultados",
"fileName": "Nombre",
@@ -1093,9 +1093,9 @@
},
"connectors": {
"label": "Conectores",
- "subtitle": "Conecta DocsGPT a los servicios que usa tu equipo. Una conexión puede sincronizar contenido en Fuentes y dar herramientas a los agentes.",
+ "subtitle": "Conecta DocsGPT a los servicios que usa tu equipo. Una conexión puede sincronizar contenido en Conocimiento y dar herramientas a los agentes.",
"search": "Buscar conectores...",
- "addCustom": "Añadir conector personalizado",
+ "addCustom": "Añadir herramienta propia",
"custom": {
"custom_mcp": "Servidor MCP",
"custom_openapi": "OpenAPI / REST"
@@ -1104,8 +1104,8 @@
"categories": {
"all": "Todos",
"connected": "Conectados",
- "files": "Archivos y documentos",
- "knowledge": "Bases de conocimiento",
+ "files": "Archivos y almacenamiento",
+ "knowledge": "Documentos y wikis",
"dev": "Herramientas de desarrollo",
"messaging": "Mensajería",
"database": "Bases de datos",
@@ -1139,11 +1139,11 @@
"custom": "Personalizado"
},
"descriptions": {
- "google_drive": "Sincroniza Docs, Hojas de cálculo y PDF en Fuentes.",
- "share_point": "Sincroniza archivos de sitios de SharePoint y OneDrive en Fuentes.",
- "confluence": "Sincroniza espacios y páginas de Confluence en Fuentes.",
- "s3": "Sincroniza documentos de un bucket de S3 en Fuentes.",
- "reddit": "Sincroniza en Fuentes las publicaciones de Reddit que coinciden con tus búsquedas.",
+ "google_drive": "Sincroniza Docs, Hojas de cálculo y PDF en Conocimiento.",
+ "share_point": "Sincroniza archivos de sitios de SharePoint y OneDrive en Conocimiento.",
+ "confluence": "Sincroniza espacios y páginas de Confluence en Conocimiento.",
+ "s3": "Sincroniza documentos de un bucket de S3 en Conocimiento.",
+ "reddit": "Sincroniza publicaciones de Reddit que coinciden con tus búsquedas en Conocimiento.",
"brave": "Busca en la web e imágenes con la API de Brave Search.",
"telegram": "Envía mensajes e imágenes a un chat de Telegram.",
"ntfy": "Envía notificaciones push mediante un servidor ntfy.",
@@ -1168,7 +1168,7 @@
"accounts": "Cuentas",
"connectedAs": "Conectado como {{account}}",
"connectAnother": "Conectar otra cuenta",
- "sources": "Fuentes de esta conexión",
+ "sources": "Conocimiento de esta conexión",
"tools": "Herramientas de esta conexión",
"noAccounts": "Aún no hay ninguna cuenta conectada.",
"failed": "No se pudo cargar esta conexión.",
@@ -1284,17 +1284,22 @@
},
"createFailed": "No se pudo añadir el conector. Inténtalo de nuevo.",
"capabilityFilter": {
- "sync": "Se muestran los conectores que sincronizan contenido en Fuentes.",
+ "sync": "Se muestran los conectores que sincronizan contenido en Conocimiento.",
"tools": "Se muestran los conectores que dan herramientas a los agentes.",
"showAll": "Mostrar todos"
+ },
+ "capabilityPlain": {
+ "sync": "Sincroniza en Conocimiento",
+ "read": "Consulta datos",
+ "write": "Realiza acciones"
}
}
},
"modals": {
"uploadDoc": {
- "label": "Añadir una fuente",
+ "label": "Añadir conocimiento",
"select": "Elige cómo cargar tu documento en DocsGPT",
- "selectSource": "Añadir una fuente",
+ "selectSource": "Añadir conocimiento",
"selectedFiles": "Archivos Seleccionados",
"noFilesSelected": "No hay archivos seleccionados",
"file": "Subir desde el dispositivo",
@@ -1309,7 +1314,7 @@
"filesRejected": "No se añadieron (más de 25 MB o tipo no admitido): {{files}}",
"uploadedFiles": "Archivos Subidos",
"cancel": "Cancelar",
- "train": "Añadir fuente",
+ "train": "Añadir al conocimiento",
"create": "Crear",
"link": "Enlace",
"urlLink": "Enlace URL",
@@ -1659,17 +1664,18 @@
},
"sources": {
"title": "Fuentes",
- "text": "Elegir tus fuentes",
+ "text": "Elegir conocimiento",
"link": "Enlace fuente",
"view_more_one": "Ver {{count}} fuente más",
"view_more_other": "Ver {{count}} fuentes más",
- "noSourcesAvailable": "No hay fuentes disponibles",
+ "noSourcesAvailable": "Aún no hay conocimiento",
"selectedCount": "{{count}} fuentes seleccionadas",
"groupOwn": "Tus fuentes",
"groupTeam": "Compartidas con el equipo",
"connectMore": "Conectar más",
"fromConnector": "De {{name}}",
- "fromConnectorTitle": "De {{name}}: {{title}}"
+ "fromConnectorTitle": "De {{name}}: {{title}}",
+ "knowledge": "Conocimiento"
},
"attachments": {
"attach": "Adjuntar",
@@ -1894,7 +1900,7 @@
"placeholders": {
"agentName": "Nombre del agente",
"describeAgent": "Describe tu agente",
- "selectSources": "Seleccionar fuentes",
+ "selectSources": "Seleccionar conocimiento",
"chunksPerQuery": "Fragmentos por consulta",
"selectType": "Seleccionar tipo",
"selectTools": "Seleccionar herramientas",
@@ -1904,19 +1910,19 @@
"enterRequestLimit": "Ingresar límite de solicitudes"
},
"sourcePopup": {
- "title": "Seleccionar Fuentes",
- "searchPlaceholder": "Buscar fuentes...",
- "noOptionsMessage": "No hay fuentes disponibles",
+ "title": "Seleccionar conocimiento",
+ "searchPlaceholder": "Buscar conocimiento...",
+ "noOptionsMessage": "Aún no hay conocimiento",
"groupOwn": "Tus fuentes",
"groupTeam": "Compartidas con el equipo",
- "noSourceHint": "Opcional. Sin una fuente, el agente responde solo con el modelo y sus herramientas."
+ "noSourceHint": "Opcional. Sin conocimiento, el agente responde solo con el modelo y sus herramientas."
},
"toolsPopup": {
"title": "Seleccionar Herramientas",
"searchPlaceholder": "Buscar herramientas...",
"noOptionsMessage": "No hay herramientas disponibles",
"groupBuiltin": "Integradas",
- "groupDefault": "Predeterminadas",
+ "groupDefault": "Integradas",
"groupCustom": "Personalizadas",
"groupConnection": "{{name}} · {{account}}"
},
@@ -1938,7 +1944,7 @@
"defaultModel": "Modelo Predeterminado",
"name": "Nombre",
"description": "Descripción",
- "sources": "Fuentes",
+ "sources": "Conocimiento",
"avatar": "Avatar"
},
"advanced": {
@@ -2317,7 +2323,7 @@
"outputVariable": "Variable de salida",
"outputVariablePlaceholder": "Nombre de la variable de salida",
"streamToUser": "Transmitir la salida al usuario",
- "sources": "Fuentes",
+ "sources": "Conocimiento",
"documents": "Documentos",
"documentsHint": "Documentos que se pasan a este agente desde cargas o nodos anteriores.",
"filePassing": "Paso de archivos",
diff --git a/frontend/src/locale/jp.json b/frontend/src/locale/jp.json
index e634e8bd..e4fd81f4 100644
--- a/frontend/src/locale/jp.json
+++ b/frontend/src/locale/jp.json
@@ -98,15 +98,15 @@
"sources": {
"title": "ここでは、利用可能なすべてのソースファイルとアップロードしたファイルを管理できます。",
"subtitle": "DocsGPT が検索・引用できるコンテンツ:アップロード、ウェブサイト、Wiki、接続から同期したコンテンツ。",
- "label": "ソース",
+ "label": "ナレッジ",
"name": "ソース名",
"date": "ベクトル日付",
"type": "タイプ",
"tokenUsage": "トークン使用量",
- "noData": "既存のソースがありません",
+ "noData": "ナレッジはまだありません",
"searchPlaceholder": "検索...",
"addNew": "新規追加",
- "addSource": "ソースを追加",
+ "addSource": "ナレッジを追加",
"addChunk": "チャンクを追加",
"preLoaded": "プリロード済み",
"private": "プライベート",
@@ -287,7 +287,7 @@
"chunks": "チャンク",
"noChunks": "チャンクが見つかりません",
"noChunksAlt": "チャンクが見つかりません",
- "goToSources": "ソースへ移動",
+ "goToSources": "ナレッジへ移動",
"uploadNew": "新規アップロード",
"noResults": "結果が見つかりません",
"fileName": "名前",
@@ -1084,9 +1084,9 @@
},
"connectors": {
"label": "コネクタ",
- "subtitle": "DocsGPT をチームで使っているサービスに接続します。接続ごとに、コンテンツをソースへ同期したり、エージェントにツールを提供したりできます。",
+ "subtitle": "DocsGPT をチームで使っているサービスに接続します。接続ごとに、コンテンツをナレッジへ同期したり、エージェントにツールを提供したりできます。",
"search": "コネクタを検索...",
- "addCustom": "カスタムコネクタを追加",
+ "addCustom": "カスタムツールを追加",
"custom": {
"custom_mcp": "MCP サーバー",
"custom_openapi": "OpenAPI / REST"
@@ -1095,8 +1095,8 @@
"categories": {
"all": "すべて",
"connected": "接続済み",
- "files": "ファイルとドキュメント",
- "knowledge": "ナレッジベース",
+ "files": "ファイルとストレージ",
+ "knowledge": "ドキュメントと Wiki",
"dev": "開発者ツール",
"messaging": "メッセージ",
"database": "データベース",
@@ -1130,11 +1130,11 @@
"custom": "カスタム"
},
"descriptions": {
- "google_drive": "ドキュメント、スプレッドシート、PDF をソースに同期します。",
- "share_point": "SharePoint サイトと OneDrive のファイルをソースに同期します。",
- "confluence": "Confluence のスペースとページをソースに同期します。",
- "s3": "S3 バケットのドキュメントをソースに同期します。",
- "reddit": "検索に一致する Reddit の投稿をソースに同期します。",
+ "google_drive": "ドキュメント、スプレッドシート、PDF をナレッジに同期します。",
+ "share_point": "SharePoint サイトと OneDrive のファイルをナレッジに同期します。",
+ "confluence": "Confluence のスペースとページをナレッジに同期します。",
+ "s3": "S3 バケットのドキュメントをナレッジに同期します。",
+ "reddit": "検索条件に一致する Reddit の投稿をナレッジに同期します。",
"brave": "Brave Search API でウェブと画像を検索します。",
"telegram": "Telegram のチャットにメッセージや画像を送信します。",
"ntfy": "ntfy サーバー経由でプッシュ通知を送信します。",
@@ -1159,7 +1159,7 @@
"accounts": "アカウント",
"connectedAs": "{{account}} として接続中",
"connectAnother": "別のアカウントを接続",
- "sources": "この接続のソース",
+ "sources": "この接続からのナレッジ",
"tools": "この接続のツール",
"noAccounts": "まだアカウントが接続されていません。",
"failed": "この接続を読み込めませんでした。",
@@ -1268,17 +1268,22 @@
},
"createFailed": "コネクタを追加できませんでした。もう一度お試しください。",
"capabilityFilter": {
- "sync": "ソースにコンテンツを同期するコネクタを表示しています。",
+ "sync": "ナレッジにコンテンツを同期するコネクタを表示しています。",
"tools": "エージェントにツールを提供するコネクタを表示しています。",
"showAll": "すべて表示"
+ },
+ "capabilityPlain": {
+ "sync": "ナレッジに同期",
+ "read": "情報を調べる",
+ "write": "操作を行う"
}
}
},
"modals": {
"uploadDoc": {
- "label": "ソースを追加",
+ "label": "ナレッジを追加",
"select": "ドキュメントを DocsGPT にアップロードする方法を選択します",
- "selectSource": "ソースを追加",
+ "selectSource": "ナレッジを追加",
"selectedFiles": "選択されたファイル",
"noFilesSelected": "ファイルが選択されていません",
"file": "デバイスからアップロード",
@@ -1293,7 +1298,7 @@
"filesRejected": "追加されませんでした(25 MB を超えているか、未対応の形式です): {{files}}",
"uploadedFiles": "アップロードされたファイル",
"cancel": "キャンセル",
- "train": "ソースを追加",
+ "train": "ナレッジに追加",
"create": "作成",
"link": "リンク",
"urlLink": "URLリンク",
@@ -1642,16 +1647,17 @@
},
"sources": {
"title": "ソース",
- "text": "ソーステキスト",
+ "text": "ナレッジを選択",
"link": "ソースリンク",
"view_more": "さらに{{count}}個のソース",
- "noSourcesAvailable": "利用可能なソースがありません",
+ "noSourcesAvailable": "ナレッジはまだありません",
"selectedCount": "{{count}} 件のソースを選択中",
"groupOwn": "自分のソース",
"groupTeam": "チームと共有",
"connectMore": "さらに接続",
"fromConnector": "{{name}} から",
- "fromConnectorTitle": "{{name}} から: {{title}}"
+ "fromConnectorTitle": "{{name}} から: {{title}}",
+ "knowledge": "ナレッジ"
},
"attachments": {
"attach": "添付",
@@ -1875,7 +1881,7 @@
"placeholders": {
"agentName": "エージェント名",
"describeAgent": "エージェントを説明してください",
- "selectSources": "ソースを選択",
+ "selectSources": "ナレッジを選択",
"chunksPerQuery": "クエリごとのチャンク数",
"selectType": "タイプを選択",
"selectTools": "ツールを選択",
@@ -1885,19 +1891,19 @@
"enterRequestLimit": "リクエスト制限を入力"
},
"sourcePopup": {
- "title": "ソースを選択",
- "searchPlaceholder": "ソースを検索...",
- "noOptionsMessage": "利用可能なソースがありません",
+ "title": "ナレッジを選択",
+ "searchPlaceholder": "ナレッジを検索...",
+ "noOptionsMessage": "ナレッジはまだありません",
"groupOwn": "自分のソース",
"groupTeam": "チームと共有",
- "noSourceHint": "任意。ソースがない場合、エージェントはモデルとツールのみで回答します。"
+ "noSourceHint": "任意です。ナレッジがない場合、エージェントはモデルとツールだけで回答します。"
},
"toolsPopup": {
"title": "ツールを選択",
"searchPlaceholder": "ツールを検索...",
"noOptionsMessage": "利用可能なツールがありません",
"groupBuiltin": "ビルトイン",
- "groupDefault": "デフォルト",
+ "groupDefault": "組み込み",
"groupCustom": "カスタム",
"groupConnection": "{{name}} · {{account}}"
},
@@ -1919,7 +1925,7 @@
"defaultModel": "デフォルトモデル",
"name": "名前",
"description": "説明",
- "sources": "ソース",
+ "sources": "ナレッジ",
"avatar": "アバター"
},
"advanced": {
@@ -2297,7 +2303,7 @@
"outputVariable": "出力変数",
"outputVariablePlaceholder": "出力の変数名",
"streamToUser": "出力をユーザーにストリーミング",
- "sources": "ソース",
+ "sources": "ナレッジ",
"documents": "ドキュメント",
"documentsHint": "アップロードまたは上流ノードからこのエージェントに渡されるドキュメント。",
"filePassing": "ファイルの受け渡し",
diff --git a/frontend/src/locale/ru.json b/frontend/src/locale/ru.json
index 7869d5b9..f50b79cc 100644
--- a/frontend/src/locale/ru.json
+++ b/frontend/src/locale/ru.json
@@ -98,15 +98,15 @@
"sources": {
"title": "Здесь вы можете управлять всеми исходными файлами, которые доступны вам и которые вы загрузили.",
"subtitle": "Контент, по которому DocsGPT может искать и который может цитировать: загрузки, сайты, вики и контент, синхронизированный из ваших подключений.",
- "label": "Источники",
+ "label": "Знания",
"name": "Название источника",
"date": "Дата вектора",
"type": "Тип",
"tokenUsage": "Использование токена",
- "noData": "Нет существующих источников",
+ "noData": "Знаний пока нет",
"searchPlaceholder": "Поиск...",
"addNew": "добавить новый",
- "addSource": "Добавить источник",
+ "addSource": "Добавить знания",
"addChunk": "Добавить фрагмент",
"preLoaded": "Предзагруженный",
"private": "Частный",
@@ -318,7 +318,7 @@
"chunks": "Фрагменты",
"noChunks": "Фрагменты не найдены",
"noChunksAlt": "Фрагменты не найдены",
- "goToSources": "Перейти к источникам",
+ "goToSources": "К знаниям",
"uploadNew": "Загрузить новый",
"noResults": "Результаты не найдены",
"fileName": "Имя",
@@ -1149,9 +1149,9 @@
},
"connectors": {
"label": "Коннекторы",
- "subtitle": "Подключите DocsGPT к сервисам, которыми пользуется ваша команда. Подключение может синхронизировать контент в Источники и давать агентам инструменты.",
+ "subtitle": "Подключите DocsGPT к сервисам, которыми пользуется ваша команда. Подключение может синхронизировать содержимое в знания и давать агентам инструменты.",
"search": "Поиск коннекторов...",
- "addCustom": "Добавить свой коннектор",
+ "addCustom": "Добавить свой инструмент",
"custom": {
"custom_mcp": "MCP-сервер",
"custom_openapi": "OpenAPI / REST"
@@ -1160,8 +1160,8 @@
"categories": {
"all": "Все",
"connected": "Подключённые",
- "files": "Файлы и документы",
- "knowledge": "Базы знаний",
+ "files": "Файлы и хранилища",
+ "knowledge": "Документы и вики",
"dev": "Инструменты разработчика",
"messaging": "Сообщения",
"database": "Базы данных",
@@ -1195,11 +1195,11 @@
"custom": "Свой"
},
"descriptions": {
- "google_drive": "Синхронизирует Документы, Таблицы и PDF в Источники.",
- "share_point": "Синхронизирует файлы с сайтов SharePoint и из OneDrive в Источники.",
- "confluence": "Синхронизирует пространства и страницы Confluence в Источники.",
- "s3": "Синхронизирует документы из бакета S3 в Источники.",
- "reddit": "Синхронизирует в Источники посты Reddit по вашим поисковым запросам.",
+ "google_drive": "Синхронизирует Документы, Таблицы и PDF в знания.",
+ "share_point": "Синхронизирует файлы с сайтов SharePoint и из OneDrive в знания.",
+ "confluence": "Синхронизирует пространства и страницы Confluence в знания.",
+ "s3": "Синхронизирует документы из бакета S3 в знания.",
+ "reddit": "Синхронизирует публикации Reddit по вашим запросам в знания.",
"brave": "Поиск в интернете и по картинкам через Brave Search API.",
"telegram": "Отправляет сообщения и изображения в чат Telegram.",
"ntfy": "Отправляет push-уведомления через сервер ntfy.",
@@ -1224,7 +1224,7 @@
"accounts": "Аккаунты",
"connectedAs": "Подключено как {{account}}",
"connectAnother": "Подключить другой аккаунт",
- "sources": "Источники из этого подключения",
+ "sources": "Знания из этого подключения",
"tools": "Инструменты из этого подключения",
"noAccounts": "Аккаунт ещё не подключён.",
"failed": "Не удалось загрузить это подключение.",
@@ -1354,17 +1354,22 @@
},
"createFailed": "Не удалось добавить коннектор. Попробуйте ещё раз.",
"capabilityFilter": {
- "sync": "Показаны коннекторы, которые синхронизируют содержимое в источники.",
+ "sync": "Показаны коннекторы, которые синхронизируют содержимое в знания.",
"tools": "Показаны коннекторы, которые дают агентам инструменты.",
"showAll": "Показать все"
+ },
+ "capabilityPlain": {
+ "sync": "Синхронизирует в знания",
+ "read": "Ищет информацию",
+ "write": "Выполняет действия"
}
}
},
"modals": {
"uploadDoc": {
- "label": "Добавить источник",
+ "label": "Добавить знания",
"select": "Выберите способ загрузки документа в DocsGPT",
- "selectSource": "Добавить источник",
+ "selectSource": "Добавить знания",
"selectedFiles": "Выбранные файлы",
"noFilesSelected": "Файлы не выбраны",
"file": "Загрузить с устройства",
@@ -1379,7 +1384,7 @@
"filesRejected": "Не добавлены (больше 25 МБ или неподдерживаемый формат): {{files}}",
"uploadedFiles": "Загруженные файлы",
"cancel": "Отмена",
- "train": "Добавить источник",
+ "train": "Добавить в знания",
"create": "Создать",
"link": "Ссылка",
"urlLink": "URL ссылка",
@@ -1731,19 +1736,20 @@
},
"sources": {
"title": "Источники",
- "text": "Выберите ваши источники",
+ "text": "Выберите знания",
"link": "Ссылка на источник",
"view_more_one": "ещё {{count}} источник",
"view_more_few": "ещё {{count}} источника",
"view_more_many": "ещё {{count}} источников",
"view_more_other": "ещё {{count}} источников",
- "noSourcesAvailable": "Нет доступных источников",
+ "noSourcesAvailable": "Знаний пока нет",
"selectedCount": "Выбрано источников: {{count}}",
"groupOwn": "Ваши источники",
"groupTeam": "Общие с командой",
"connectMore": "Подключить ещё",
"fromConnector": "Из {{name}}",
- "fromConnectorTitle": "Из {{name}}: {{title}}"
+ "fromConnectorTitle": "Из {{name}}: {{title}}",
+ "knowledge": "Знания"
},
"attachments": {
"attach": "Прикрепить",
@@ -1970,7 +1976,7 @@
"placeholders": {
"agentName": "Имя агента",
"describeAgent": "Опишите вашего агента",
- "selectSources": "Выберите источники",
+ "selectSources": "Выберите знания",
"chunksPerQuery": "Фрагментов на запрос",
"selectType": "Выберите тип",
"selectTools": "Выберите инструменты",
@@ -1980,19 +1986,19 @@
"enterRequestLimit": "Введите лимит запросов"
},
"sourcePopup": {
- "title": "Выберите Источники",
- "searchPlaceholder": "Поиск источников...",
- "noOptionsMessage": "Нет доступных источников",
+ "title": "Выберите знания",
+ "searchPlaceholder": "Поиск по знаниям...",
+ "noOptionsMessage": "Знаний пока нет",
"groupOwn": "Ваши источники",
"groupTeam": "Общие с командой",
- "noSourceHint": "Необязательно. Без источника агент отвечает только на основе модели и своих инструментов."
+ "noSourceHint": "Необязательно. Без знаний агент отвечает только с помощью модели и своих инструментов."
},
"toolsPopup": {
"title": "Выберите Инструменты",
"searchPlaceholder": "Поиск инструментов...",
"noOptionsMessage": "Нет доступных инструментов",
"groupBuiltin": "Встроенные",
- "groupDefault": "По умолчанию",
+ "groupDefault": "Встроенные",
"groupCustom": "Пользовательские",
"groupConnection": "{{name}} · {{account}}"
},
@@ -2014,7 +2020,7 @@
"defaultModel": "Модель по умолчанию",
"name": "Имя",
"description": "Описание",
- "sources": "Источники",
+ "sources": "Знания",
"avatar": "Аватар"
},
"advanced": {
@@ -2401,7 +2407,7 @@
"outputVariable": "Выходная переменная",
"outputVariablePlaceholder": "Имя переменной для вывода",
"streamToUser": "Передавать вывод пользователю потоком",
- "sources": "Источники",
+ "sources": "Знания",
"documents": "Документы",
"documentsHint": "Документы, передаваемые этому агенту из загрузок или предыдущих узлов.",
"filePassing": "Передача файлов",
diff --git a/frontend/src/locale/zh-TW.json b/frontend/src/locale/zh-TW.json
index abb97e28..23cb4023 100644
--- a/frontend/src/locale/zh-TW.json
+++ b/frontend/src/locale/zh-TW.json
@@ -98,15 +98,15 @@
"sources": {
"title": "在這裡您可以管理所有可用的來源檔案以及您上傳的檔案。",
"subtitle": "DocsGPT 可以搜尋和引用的內容:上傳的檔案、網站、Wiki,以及從連線同步的內容。",
- "label": "來源",
+ "label": "知識庫",
"name": "來源名稱",
"date": "向量日期",
"type": "類型",
"tokenUsage": "Token 使用量",
- "noData": "沒有現有的來源",
+ "noData": "還沒有知識",
"searchPlaceholder": "搜尋...",
"addNew": "新增文件",
- "addSource": "新增來源",
+ "addSource": "新增知識",
"addChunk": "新增區塊",
"preLoaded": "預載入",
"private": "私人",
@@ -287,7 +287,7 @@
"chunks": "文本塊",
"noChunks": "未找到文本塊",
"noChunksAlt": "未找到文本塊",
- "goToSources": "前往來源",
+ "goToSources": "前往知識庫",
"uploadNew": "上傳新文件",
"noResults": "未找到結果",
"fileName": "名稱",
@@ -1084,9 +1084,9 @@
},
"connectors": {
"label": "連接器",
- "subtitle": "將 DocsGPT 連接到團隊使用的服務。一個連線可以把內容同步到來源,也可以為代理提供工具。",
+ "subtitle": "將 DocsGPT 連接到團隊使用的服務。一個連線可以把內容同步到知識庫,也可以為代理提供工具。",
"search": "搜尋連接器...",
- "addCustom": "新增自訂連接器",
+ "addCustom": "新增自訂工具",
"custom": {
"custom_mcp": "MCP 伺服器",
"custom_openapi": "OpenAPI / REST"
@@ -1095,8 +1095,8 @@
"categories": {
"all": "全部",
"connected": "已連線",
- "files": "檔案和文件",
- "knowledge": "知識庫",
+ "files": "檔案與儲存",
+ "knowledge": "文件與 Wiki",
"dev": "開發者工具",
"messaging": "訊息",
"database": "資料庫",
@@ -1130,11 +1130,11 @@
"custom": "自訂"
},
"descriptions": {
- "google_drive": "將文件、試算表和 PDF 同步到來源。",
- "share_point": "將 SharePoint 網站和 OneDrive 中的檔案同步到來源。",
- "confluence": "將 Confluence 空間和頁面同步到來源。",
- "s3": "將 S3 儲存貯體中的文件同步到來源。",
- "reddit": "將符合搜尋條件的 Reddit 貼文同步到來源。",
+ "google_drive": "將文件、試算表和 PDF 同步到知識庫。",
+ "share_point": "將 SharePoint 網站和 OneDrive 中的檔案同步到知識庫。",
+ "confluence": "將 Confluence 空間和頁面同步到知識庫。",
+ "s3": "將 S3 儲存貯體中的文件同步到知識庫。",
+ "reddit": "將符合你搜尋條件的 Reddit 貼文同步到知識庫。",
"brave": "使用 Brave Search API 搜尋網頁和圖片。",
"telegram": "傳送訊息和圖片到 Telegram 聊天。",
"ntfy": "透過 ntfy 伺服器傳送推播通知。",
@@ -1159,7 +1159,7 @@
"accounts": "帳號",
"connectedAs": "已以 {{account}} 連線",
"connectAnother": "連線其他帳號",
- "sources": "來自此連線的來源",
+ "sources": "來自此連線的知識",
"tools": "來自此連線的工具",
"noAccounts": "尚未連線帳號。",
"failed": "無法載入此連線。",
@@ -1268,17 +1268,22 @@
},
"createFailed": "無法新增連接器。請再試一次。",
"capabilityFilter": {
- "sync": "正在顯示將內容同步到來源的連接器。",
+ "sync": "正在顯示將內容同步到知識庫的連接器。",
"tools": "正在顯示為代理提供工具的連接器。",
"showAll": "顯示全部"
+ },
+ "capabilityPlain": {
+ "sync": "同步到知識庫",
+ "read": "查詢資訊",
+ "write": "執行操作"
}
}
},
"modals": {
"uploadDoc": {
- "label": "新增來源",
+ "label": "新增知識",
"select": "選擇如何將文件上傳到 DocsGPT",
- "selectSource": "新增來源",
+ "selectSource": "新增知識",
"selectedFiles": "已選擇的檔案",
"noFilesSelected": "未選擇檔案",
"file": "從檔案",
@@ -1293,7 +1298,7 @@
"filesRejected": "未新增(超過 25 MB 或不支援的類型):{{files}}",
"uploadedFiles": "已上傳檔案",
"cancel": "取消",
- "train": "新增來源",
+ "train": "新增到知識庫",
"create": "建立",
"link": "連結",
"urlLink": "URL 連結",
@@ -1642,16 +1647,17 @@
},
"sources": {
"title": "來源",
- "text": "來源文字",
+ "text": "選擇知識",
"link": "來源連結",
"view_more": "查看更多 {{count}} 個來源",
- "noSourcesAvailable": "沒有可用的來源",
+ "noSourcesAvailable": "還沒有知識",
"selectedCount": "已選擇 {{count}} 個來源",
"groupOwn": "我的來源",
"groupTeam": "團隊共享",
"connectMore": "連線更多",
"fromConnector": "來自 {{name}}",
- "fromConnectorTitle": "來自 {{name}}:{{title}}"
+ "fromConnectorTitle": "來自 {{name}}:{{title}}",
+ "knowledge": "知識庫"
},
"attachments": {
"attach": "附件",
@@ -1875,7 +1881,7 @@
"placeholders": {
"agentName": "代理名稱",
"describeAgent": "描述您的代理",
- "selectSources": "選擇來源",
+ "selectSources": "選擇知識",
"chunksPerQuery": "每次查詢的區塊數",
"selectType": "選擇類型",
"selectTools": "選擇工具",
@@ -1885,19 +1891,19 @@
"enterRequestLimit": "輸入請求限制"
},
"sourcePopup": {
- "title": "選擇來源",
- "searchPlaceholder": "搜尋來源...",
- "noOptionsMessage": "沒有可用的來源",
+ "title": "選擇知識",
+ "searchPlaceholder": "搜尋知識...",
+ "noOptionsMessage": "還沒有知識",
"groupOwn": "我的來源",
"groupTeam": "團隊共享",
- "noSourceHint": "可選。未選擇來源時,代理僅根據模型和工具作答。"
+ "noSourceHint": "選填。沒有知識時,代理只用模型和它的工具回答。"
},
"toolsPopup": {
"title": "選擇工具",
"searchPlaceholder": "搜尋工具...",
"noOptionsMessage": "沒有可用的工具",
"groupBuiltin": "內建",
- "groupDefault": "預設",
+ "groupDefault": "內建",
"groupCustom": "自訂",
"groupConnection": "{{name}} · {{account}}"
},
@@ -1919,7 +1925,7 @@
"defaultModel": "預設模型",
"name": "名稱",
"description": "描述",
- "sources": "來源",
+ "sources": "知識庫",
"avatar": "頭像"
},
"advanced": {
@@ -2297,7 +2303,7 @@
"outputVariable": "輸出變數",
"outputVariablePlaceholder": "輸出的變數名稱",
"streamToUser": "將輸出串流給使用者",
- "sources": "來源",
+ "sources": "知識庫",
"documents": "文件",
"documentsHint": "從上傳或上游節點傳給此代理的文件。",
"filePassing": "檔案傳遞",
diff --git a/frontend/src/locale/zh.json b/frontend/src/locale/zh.json
index b6865ab8..a6c82d8b 100644
--- a/frontend/src/locale/zh.json
+++ b/frontend/src/locale/zh.json
@@ -98,15 +98,15 @@
"sources": {
"title": "在这里您可以管理所有可用的源文件以及您上传的文件。",
"subtitle": "DocsGPT 可以搜索和引用的内容:上传的文件、网站、Wiki,以及从连接同步的内容。",
- "label": "来源",
+ "label": "知识库",
"name": "来源名称",
"date": "向量日期",
"type": "类型",
"tokenUsage": "令牌使用",
- "noData": "没有现有的来源",
+ "noData": "还没有知识",
"searchPlaceholder": "搜索...",
"addNew": "添加新文档",
- "addSource": "添加来源",
+ "addSource": "添加知识",
"addChunk": "添加块",
"preLoaded": "预加载",
"private": "私有",
@@ -287,7 +287,7 @@
"chunks": "文本块",
"noChunks": "未找到文本块",
"noChunksAlt": "未找到文本块",
- "goToSources": "前往来源",
+ "goToSources": "前往知识库",
"uploadNew": "上传新文档",
"noResults": "未找到结果",
"fileName": "名称",
@@ -1084,9 +1084,9 @@
},
"connectors": {
"label": "连接器",
- "subtitle": "将 DocsGPT 连接到团队使用的服务。一个连接可以把内容同步到来源,也可以为智能体提供工具。",
+ "subtitle": "将 DocsGPT 连接到团队使用的服务。一个连接可以把内容同步到知识库,也可以为智能体提供工具。",
"search": "搜索连接器...",
- "addCustom": "添加自定义连接器",
+ "addCustom": "添加自定义工具",
"custom": {
"custom_mcp": "MCP 服务器",
"custom_openapi": "OpenAPI / REST"
@@ -1095,8 +1095,8 @@
"categories": {
"all": "全部",
"connected": "已连接",
- "files": "文件和文档",
- "knowledge": "知识库",
+ "files": "文件与存储",
+ "knowledge": "文档与 Wiki",
"dev": "开发者工具",
"messaging": "消息",
"database": "数据库",
@@ -1130,11 +1130,11 @@
"custom": "自定义"
},
"descriptions": {
- "google_drive": "将文档、表格和 PDF 同步到来源。",
- "share_point": "将 SharePoint 站点和 OneDrive 中的文件同步到来源。",
- "confluence": "将 Confluence 空间和页面同步到来源。",
- "s3": "将 S3 存储桶中的文档同步到来源。",
- "reddit": "将符合搜索条件的 Reddit 帖子同步到来源。",
+ "google_drive": "将文档、表格和 PDF 同步到知识库。",
+ "share_point": "将 SharePoint 站点和 OneDrive 中的文件同步到知识库。",
+ "confluence": "将 Confluence 空间和页面同步到知识库。",
+ "s3": "将 S3 存储桶中的文档同步到知识库。",
+ "reddit": "将符合你搜索条件的 Reddit 帖子同步到知识库。",
"brave": "使用 Brave Search API 搜索网页和图片。",
"telegram": "向 Telegram 聊天发送消息和图片。",
"ntfy": "通过 ntfy 服务器发送推送通知。",
@@ -1159,7 +1159,7 @@
"accounts": "账号",
"connectedAs": "已作为 {{account}} 连接",
"connectAnother": "连接其他账号",
- "sources": "来自此连接的来源",
+ "sources": "来自此连接的知识",
"tools": "来自此连接的工具",
"noAccounts": "尚未连接账号。",
"failed": "无法加载此连接。",
@@ -1268,17 +1268,22 @@
},
"createFailed": "无法添加连接器。请重试。",
"capabilityFilter": {
- "sync": "正在显示将内容同步到来源的连接器。",
+ "sync": "正在显示将内容同步到知识库的连接器。",
"tools": "正在显示为智能体提供工具的连接器。",
"showAll": "显示全部"
+ },
+ "capabilityPlain": {
+ "sync": "同步到知识库",
+ "read": "查找信息",
+ "write": "执行操作"
}
}
},
"modals": {
"uploadDoc": {
- "label": "添加来源",
+ "label": "添加知识",
"select": "选择如何将文档上传到 DocsGPT",
- "selectSource": "添加来源",
+ "selectSource": "添加知识",
"selectedFiles": "已选择的文件",
"noFilesSelected": "未选择文件",
"file": "从设备上传",
@@ -1293,7 +1298,7 @@
"filesRejected": "未添加(超过 25 MB 或不支持的类型):{{files}}",
"uploadedFiles": "已上传文件",
"cancel": "取消",
- "train": "添加来源",
+ "train": "添加到知识库",
"create": "创建",
"link": "链接",
"urlLink": "URL 链接",
@@ -1642,16 +1647,17 @@
},
"sources": {
"title": "来源",
- "text": "来源文本",
+ "text": "选择知识",
"link": "来源链接",
"view_more": "还有{{count}}个来源",
- "noSourcesAvailable": "没有可用的来源",
+ "noSourcesAvailable": "还没有知识",
"selectedCount": "已选择 {{count}} 个来源",
"groupOwn": "我的来源",
"groupTeam": "团队共享",
"connectMore": "连接更多",
"fromConnector": "来自 {{name}}",
- "fromConnectorTitle": "来自 {{name}}:{{title}}"
+ "fromConnectorTitle": "来自 {{name}}:{{title}}",
+ "knowledge": "知识库"
},
"attachments": {
"attach": "附件",
@@ -1875,7 +1881,7 @@
"placeholders": {
"agentName": "代理名称",
"describeAgent": "描述您的代理",
- "selectSources": "选择来源",
+ "selectSources": "选择知识",
"chunksPerQuery": "每次查询的块数",
"selectType": "选择类型",
"selectTools": "选择工具",
@@ -1885,19 +1891,19 @@
"enterRequestLimit": "输入请求限制"
},
"sourcePopup": {
- "title": "选择来源",
- "searchPlaceholder": "搜索来源...",
- "noOptionsMessage": "没有可用的来源",
+ "title": "选择知识",
+ "searchPlaceholder": "搜索知识...",
+ "noOptionsMessage": "还没有知识",
"groupOwn": "我的来源",
"groupTeam": "团队共享",
- "noSourceHint": "可选。未选择来源时,智能体仅根据模型和工具作答。"
+ "noSourceHint": "可选。没有知识时,智能体只用模型和它的工具回答。"
},
"toolsPopup": {
"title": "选择工具",
"searchPlaceholder": "搜索工具...",
"noOptionsMessage": "没有可用的工具",
"groupBuiltin": "内置",
- "groupDefault": "默认",
+ "groupDefault": "内置",
"groupCustom": "自定义",
"groupConnection": "{{name}} · {{account}}"
},
@@ -1919,7 +1925,7 @@
"defaultModel": "默认模型",
"name": "名称",
"description": "描述",
- "sources": "来源",
+ "sources": "知识库",
"avatar": "头像"
},
"advanced": {
@@ -2297,7 +2303,7 @@
"outputVariable": "输出变量",
"outputVariablePlaceholder": "输出的变量名",
"streamToUser": "将输出流式传输给用户",
- "sources": "来源",
+ "sources": "知识库",
"documents": "文档",
"documentsHint": "从上传或上游节点传给此智能体的文档。",
"filePassing": "文件传递",
diff --git a/frontend/src/navigation/sections.ts b/frontend/src/navigation/sections.ts
index b2eb6e66..06a54b90 100644
--- a/frontend/src/navigation/sections.ts
+++ b/frontend/src/navigation/sections.ts
@@ -114,7 +114,7 @@ export const SETTINGS_SECTION: Section = {
items: [
{
key: 'sources',
- path: '/settings/sources',
+ path: '/settings/knowledge',
labelKey: 'settings.sources.label',
icon: Database,
},
diff --git a/frontend/src/settings/Connectors.test.tsx b/frontend/src/settings/Connectors.test.tsx
index b301be8a..c83e4369 100644
--- a/frontend/src/settings/Connectors.test.tsx
+++ b/frontend/src/settings/Connectors.test.tsx
@@ -168,8 +168,9 @@ describe('Connectors page', () => {
'settings.connectors.status.disabledByAdmin',
);
expect(card('brave')!.disabled).toBe(true);
- expect(card('custom_mcp')!.textContent).toContain(
- 'settings.connectors.publisher.custom',
+ // No publisher jargon ("Preset", "Built in") on cards.
+ expect(card('custom_mcp')!.textContent).not.toContain(
+ 'settings.connectors.publisher',
);
});
@@ -186,10 +187,10 @@ describe('Connectors page', () => {
it('shows capability chips', async () => {
await render();
expect(card('google_drive')!.textContent).toContain(
- 'settings.connectors.capability.sync',
+ 'settings.connectors.capabilityPlain.sync',
);
expect(card('telegram')!.textContent).toContain(
- 'settings.connectors.capability.write',
+ 'settings.connectors.capabilityPlain.write',
);
});
@@ -246,6 +247,75 @@ describe('Connectors page', () => {
expect(pills).not.toContain('settings.connectors.categories.messaging');
});
+ const ATLASSIAN = definition({
+ key: 'mcp:atlassian',
+ name: 'Jira & Confluence',
+ description: 'Search and update Jira issues.',
+ category: 'dev',
+ auth_kind: 'mcp_oauth',
+ capabilities: ['read', 'write'],
+ publisher: 'preset',
+ part_of: 'confluence',
+ });
+
+ it('shows one Confluence card that also does what its MCP part does', async () => {
+ service.getCatalog.mockResolvedValue({
+ success: true,
+ connectors: [...CATALOG, ATLASSIAN],
+ });
+ await render();
+ expect(card('mcp:atlassian')).toBeNull();
+ const confluence = card('confluence')!;
+ expect(confluence.textContent).toContain(
+ 'settings.connectors.capabilityPlain.sync',
+ );
+ expect(confluence.textContent).toContain(
+ 'settings.connectors.capabilityPlain.write',
+ );
+ });
+
+ it("finds the merged card by its part's name", async () => {
+ service.getCatalog.mockResolvedValue({
+ success: true,
+ connectors: [...CATALOG, ATLASSIAN],
+ });
+ await render();
+ const input = container.querySelector(
+ '#connector-search-input',
+ )!;
+ const setter = Object.getOwnPropertyDescriptor(
+ HTMLInputElement.prototype,
+ 'value',
+ )!.set!;
+ await act(async () => {
+ setter.call(input, 'jira');
+ input.dispatchEvent(new Event('input', { bubbles: true }));
+ });
+ expect(card('confluence')).not.toBeNull();
+ });
+
+ it('shows the part on its own when its parent is not listed', async () => {
+ service.getCatalog.mockResolvedValue({
+ success: true,
+ connectors: [...CATALOG.filter((c) => c.key !== 'confluence'), ATLASSIAN],
+ });
+ await render();
+ expect(card('mcp:atlassian')).not.toBeNull();
+ });
+
+ it("opens the merged card's page with a section for its part", async () => {
+ service.getCatalog.mockResolvedValue({
+ success: true,
+ connectors: [...CATALOG, ATLASSIAN],
+ });
+ await render();
+ await act(async () => card('confluence')!.click());
+ expect(document.body.textContent).toContain('Jira & Confluence');
+ expect(document.body.textContent).toContain(
+ 'settings.connectors.descriptions.mcp_atlassian',
+ );
+ });
+
it('shows a retry when the catalog fails to load', async () => {
service.getCatalog.mockResolvedValue({ success: false });
await render();
diff --git a/frontend/src/settings/Connectors.tsx b/frontend/src/settings/Connectors.tsx
index 1c402780..1a776fb3 100644
--- a/frontend/src/settings/Connectors.tsx
+++ b/frontend/src/settings/Connectors.tsx
@@ -90,6 +90,30 @@ export default function Connectors() {
const custom = catalog.filter((c) => c.publisher === 'custom');
const openConnector = catalog.find((c) => c.key === openKey) ?? null;
+ // One service offered two ways (Confluence sync and the Jira & Confluence
+ // MCP actions) is one card. A part is shown on its own only when its
+ // parent is not listed (not set up, or turned off).
+ const partsOf = (key: string) => catalog.filter((c) => c.part_of === key);
+ const isShownUnderParent = (connector: ConnectorDefinition) =>
+ !!connector.part_of && catalog.some((c) => c.key === connector.part_of);
+ const merged = (connector: ConnectorDefinition): ConnectorDefinition => {
+ const parts = partsOf(connector.key);
+ if (parts.length === 0) return connector;
+ const all = [connector, ...parts];
+ const state = all.some((c) => c.state === 'reconnect')
+ ? 'reconnect'
+ : all.some((c) => c.state === 'connected')
+ ? 'connected'
+ : connector.state;
+ return {
+ ...connector,
+ capabilities: Array.from(new Set(all.flatMap((c) => c.capabilities))),
+ connection_count: all.reduce((n, c) => n + c.connection_count, 0),
+ connected_count: all.reduce((n, c) => n + c.connected_count, 0),
+ state,
+ };
+ };
+
// "Connect more" in the composer opens the connectors that can do what the
// picker is for: sync content, or give tools.
const capability = searchParams.get('capability');
@@ -101,7 +125,10 @@ export default function Connectors() {
// Only categories that have something in them once the composer's
// capability filter applies (hidden connectors can empty one too), so no
// pill leads to an empty page.
- const withCapability = catalog.filter((connector) =>
+ const cards = catalog
+ .filter((connector) => !isShownUnderParent(connector))
+ .map(merged);
+ const withCapability = cards.filter((connector) =>
capability === 'sync'
? connector.capabilities.includes('sync')
: capability === 'tools'
@@ -128,14 +155,21 @@ export default function Connectors() {
.filter(
(connector) =>
!query ||
- connectorName(t, connector).toLowerCase().includes(query) ||
- connectorDescription(t, connector).toLowerCase().includes(query),
+ [connector, ...partsOf(connector.key)].some(
+ (c) =>
+ connectorName(t, c).toLowerCase().includes(query) ||
+ connectorDescription(t, c).toLowerCase().includes(query),
+ ),
)
.sort((a, b) => STATE_ORDER[a.state] - STATE_ORDER[b.state]);
}, [withCapability, filter, search, t]);
const open = (connector: ConnectorDefinition) => {
- if (connector.state === 'available' || connector.state === 'custom') {
+ const hasParts = partsOf(connector.key).length > 0;
+ if (
+ !hasParts &&
+ (connector.state === 'available' || connector.state === 'custom')
+ ) {
launch(connector);
return;
}
@@ -283,6 +317,7 @@ export default function Connectors() {
{
closeDrawer();
diff --git a/frontend/src/settings/index.tsx b/frontend/src/settings/index.tsx
index 589280ac..340547ed 100644
--- a/frontend/src/settings/index.tsx
+++ b/frontend/src/settings/index.tsx
@@ -76,8 +76,10 @@ export default function Settings() {
} />
} />
+ {/* Sources are called Knowledge now; old links keep working. */}
+ } />
);
}
+
+/** `/settings/sources` from before the rename, query string kept. */
+function SourcesRedirect() {
+ const { search, hash } = useLocation();
+ return (
+
+ );
+}
diff --git a/tests/connectors/test_catalog.py b/tests/connectors/test_catalog.py
index 37e3b86e..78d73e6f 100644
--- a/tests/connectors/test_catalog.py
+++ b/tests/connectors/test_catalog.py
@@ -114,3 +114,13 @@ class TestPresets:
def test_base_url(self):
assert catalog.base_url("https://a.example.com:8443/x/y") == "https://a.example.com:8443"
assert catalog.base_url("not a url") == ""
+
+
+def test_atlassian_preset_is_part_of_confluence():
+ """One Confluence card: syncing pages and the Jira/Confluence agent actions."""
+ from docsgpt.connectors import catalog
+
+ atlassian = catalog.get_definition("mcp:atlassian")
+ assert atlassian.part_of == "confluence"
+ assert atlassian.to_dict()["part_of"] == "confluence"
+ assert catalog.get_definition("confluence").to_dict()["part_of"] is None