Docs revamp
No files matched your search
@@ -4,12 +4,18 @@ import Image from 'next/image';
|
||||
|
||||
const iconMap = {
|
||||
'API Tool': '/toolIcons/tool_api_tool.svg',
|
||||
'Brave Search Tool': '/toolIcons/tool_brave.svg',
|
||||
'Cryptoprice Tool': '/toolIcons/tool_cryptoprice.svg',
|
||||
'Ntfy Tool': '/toolIcons/tool_ntfy.svg',
|
||||
'PostgreSQL Tool': '/toolIcons/tool_postgres.svg',
|
||||
'Read Webpage Tool': '/toolIcons/tool_read_webpage.svg',
|
||||
'Telegram Tool': '/toolIcons/tool_telegram.svg'
|
||||
'Brave Search': '/toolIcons/tool_brave.svg',
|
||||
'DuckDuckGo Search': '/toolIcons/tool_duckduckgo.svg',
|
||||
'CryptoPrice': '/toolIcons/tool_cryptoprice.svg',
|
||||
'Ntfy': '/toolIcons/tool_ntfy.svg',
|
||||
'Telegram Bot': '/toolIcons/tool_telegram.svg',
|
||||
'PostgreSQL Database': '/toolIcons/tool_postgres.svg',
|
||||
'Read Webpage (browser)': '/toolIcons/tool_read_webpage.svg',
|
||||
'Remote Device': '/toolIcons/tool_remote_device.svg',
|
||||
'MCP Tool': '/toolIcons/tool_mcp_tool.svg',
|
||||
'Memory': '/toolIcons/tool_memory.svg',
|
||||
'Notepad': '/toolIcons/tool_notes.svg',
|
||||
'Todo List': '/toolIcons/tool_todo_list.svg'
|
||||
};
|
||||
|
||||
|
||||
@@ -19,7 +25,7 @@ export function ToolCards({ items }) {
|
||||
<div className="tool-cards">
|
||||
{items.map(({ title, link, description }) => {
|
||||
const isExternal = link.startsWith('https://');
|
||||
const iconSrc = iconMap[title] || '/default-icon.png'; // Default icon if not found
|
||||
const iconSrc = iconMap[title]; // No icon rendered when the tool has none
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -15,6 +15,10 @@ export default {
|
||||
"title": "🪝 Agent Webhooks",
|
||||
"href": "/Agents/webhooks"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "📡 Realtime Events",
|
||||
"href": "/Agents/notifications"
|
||||
},
|
||||
"nodes": {
|
||||
"title": "🧩 Workflow Nodes",
|
||||
"href": "/Agents/nodes"
|
||||
|
||||
@@ -345,3 +345,51 @@ curl -X POST http://localhost:7091/stream \
|
||||
- If the selected model/provider does not support a file type natively, DocsGPT falls back to parsed text content.
|
||||
- For providers that support images but not native PDF file attachments, DocsGPT can convert PDF pages to images (synthetic PDF support).
|
||||
- Attachments are user-scoped. Upload and query must be done under the same user context (same API key owner or same JWT user).
|
||||
|
||||
## Agent Portability (Export & Import)
|
||||
|
||||
Agents can be exported to a portable YAML file and imported into another DocsGPT instance (or back into the same one). This is how you move an agent between environments or share a reproducible definition.
|
||||
|
||||
| Method | Path | Description |
|
||||
| --- | --- | --- |
|
||||
| `GET` | `/api/export_agent?id=<agent_id>` | Download the agent as a `*.agent.yaml` file. |
|
||||
| `POST` | `/api/import_agent/plan` | Dry-run an import: parse a YAML file and return a resolution plan without creating anything. |
|
||||
| `POST` | `/api/import_agent` | Import a YAML file, creating the agent as a **draft**. |
|
||||
|
||||
```bash
|
||||
# Export
|
||||
curl -L "https://your-docsgpt/api/export_agent?id=<agent_id>" \
|
||||
-H "Authorization: Bearer <token>" -o my-agent.agent.yaml
|
||||
|
||||
# Preview what an import would do
|
||||
curl -X POST https://your-docsgpt/api/import_agent/plan \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
--data-binary @my-agent.agent.yaml
|
||||
|
||||
# Import (creates a draft agent)
|
||||
curl -X POST https://your-docsgpt/api/import_agent \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
--data-binary @my-agent.agent.yaml
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- **Secrets are stripped on export** — API keys and tool credentials are never written into the YAML, so you re-enter them after import.
|
||||
- The **plan** endpoint resolves references (sources, tools, prompts) and reports what will be created or matched, so you can review before committing.
|
||||
- Imported tool URLs are validated against SSRF protections, the same as when creating tools normally.
|
||||
- **Workflow agents cannot be exported yet** — exporting one returns `400`.
|
||||
|
||||
## Searching Conversations
|
||||
|
||||
Search across your conversations by name and message content:
|
||||
|
||||
```text
|
||||
GET /api/search_conversations?q=<query>&limit=30
|
||||
```
|
||||
|
||||
| Parameter | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `q` | — (required) | Case-insensitive substring to search for. |
|
||||
| `limit` | `30` | Max results (max `100`). |
|
||||
|
||||
Each result includes a `match_field` (`name`, `prompt`, or `response`) and a `match_snippet` showing the matched text in context, in addition to the fields returned by `/api/get_conversations`.
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
title: Realtime Events & Notifications (SSE)
|
||||
description: Subscribe to DocsGPT's server-sent events channel for live notifications — ingestion progress, tool approvals, MCP OAuth completion — and reconnect to an in-flight chat answer.
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
# Realtime Events & Notifications
|
||||
|
||||
DocsGPT pushes realtime updates to the browser over **Server-Sent Events (SSE)**. This is what powers the upload toasts, tool-approval prompts, and other live notifications in the UI. There are two channels:
|
||||
|
||||
- **User events** — `GET /api/events`: a per-user notification stream (ingestion progress, tool approvals, MCP OAuth completion, …).
|
||||
- **Chat reconnect** — `GET /api/messages/<message_id>/events`: resume an answer stream that was interrupted mid-generation.
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
Both channels require Redis (already a DocsGPT dependency). The publisher can be turned off instance-wide with `ENABLE_SSE_PUSH=false`.
|
||||
</Callout>
|
||||
|
||||
## User events channel
|
||||
|
||||
Open an SSE connection to receive notifications for the authenticated user:
|
||||
|
||||
```text
|
||||
GET /api/events
|
||||
Accept: text/event-stream
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
Each event is a JSON object with a `type` field, for example:
|
||||
|
||||
```text
|
||||
id: 1718900000000-0
|
||||
data: {"type":"source.ingest.queued","scope":{"id":"<source_id>"}, ...}
|
||||
```
|
||||
|
||||
Common event types:
|
||||
|
||||
| Type | Meaning |
|
||||
| --- | --- |
|
||||
| `source.ingest.queued` | A source ingestion task was enqueued (drives the upload toast). |
|
||||
| `mcp.oauth.completed` | An MCP server's OAuth handshake finished. |
|
||||
| tool-approval events | An agent is requesting approval to run a tool. |
|
||||
| `backlog.truncated` | The client's cursor slid off the retained backlog window — clear your cursor and refetch state. |
|
||||
|
||||
### Reconnecting and backlog replay
|
||||
|
||||
Events are journaled per user in a Redis Stream so a client that reconnects can catch up on what it missed. Send the last id you processed and DocsGPT replays everything after it:
|
||||
|
||||
```text
|
||||
GET /api/events
|
||||
Last-Event-ID: 1718900000000-0
|
||||
```
|
||||
|
||||
(You may also pass it as a `last_event_id` query parameter.) Each delivered event carries its own `id:`, so your cursor advances as you read. If you fall a long way behind, the snapshot is delivered across several reconnects rather than all at once.
|
||||
|
||||
A few bounded behaviors to be aware of:
|
||||
|
||||
- The backlog is capped at `EVENTS_STREAM_MAXLEN` entries (default 1000). If your `Last-Event-ID` is older than the oldest retained entry, you receive a `backlog.truncated` event — reset your cursor and refetch current state.
|
||||
- Each snapshot is capped at `EVENTS_REPLAY_MAX_PER_REQUEST` entries per request (default 200); reconnect to continue.
|
||||
- There is a per-user cap on simultaneous connections (`SSE_MAX_CONCURRENT_PER_USER`, default 8) and a windowed replay budget. Exceeding either returns **HTTP 429** — back off and retry.
|
||||
|
||||
## Chat answer reconnect
|
||||
|
||||
When an answer is streaming and the connection drops, resume it without losing the in-progress generation:
|
||||
|
||||
```text
|
||||
GET /api/messages/<message_id>/events
|
||||
```
|
||||
|
||||
This replays the message's events past your last-seen sequence number and tails the rest live. It is backed by the Postgres `message_events` journal (retained for `MESSAGE_EVENTS_RETENTION_DAYS`, default 14).
|
||||
|
||||
<Callout type="warning" emoji="⚠️">
|
||||
The chat reconnect endpoint is a native-async route served by the ASGI entrypoint. Under a plain `flask run` dev server it returns `404`; run the backend via the ASGI app (`uvicorn application.asgi:asgi_app`) or the production gunicorn uvicorn worker to use it. See the [Development Environment](/Deploying/Development-Environment) guide.
|
||||
</Callout>
|
||||
|
||||
## Settings
|
||||
|
||||
| Setting | Default | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `ENABLE_SSE_PUSH` | `true` | Master switch for the publisher and channel. |
|
||||
| `EVENTS_STREAM_MAXLEN` | `1000` | Per-user backlog cap (approximate). |
|
||||
| `SSE_KEEPALIVE_SECONDS` | `15` | Keepalive comment-frame cadence (keep below your proxy's idle timeout). |
|
||||
| `SSE_MAX_CONCURRENT_PER_USER` | `8` | Max simultaneous SSE connections per user (`0` disables the cap). |
|
||||
| `EVENTS_REPLAY_MAX_PER_REQUEST` | `200` | Max backlog entries per replay request. |
|
||||
| `EVENTS_REPLAY_BUDGET_REQUESTS_PER_WINDOW` | `30` | Per-user replay requests per window (`0` disables). |
|
||||
| `EVENTS_REPLAY_BUDGET_WINDOW_SECONDS` | `60` | Replay budget window length. |
|
||||
| `MESSAGE_EVENTS_RETENTION_DAYS` | `14` | Retention for the chat-stream `message_events` journal. |
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
Operators debugging delivery issues ("the toast never appeared", "the answer didn't reconnect") can follow the SSE notifications runbook in the repository at `docs/runbooks/sse-notifications.md`.
|
||||
</Callout>
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: OpenAI-Compatible API
|
||||
description: Connect any OpenAI-compatible client to DocsGPT Agents via /v1/chat/completions.
|
||||
description: Connect any OpenAI-compatible client to DocsGPT Agents via /v1/chat/completions — streaming, structured output, multimodal, tool calling, reasoning, and idempotent retries.
|
||||
---
|
||||
|
||||
import { Callout, Tabs } from 'nextra/components';
|
||||
@@ -58,7 +58,7 @@ Authenticate with `Authorization: Bearer <agent_api_key>`.
|
||||
|
||||
## Streaming
|
||||
|
||||
Set `"stream": true`. You'll receive SSE chunks with `choices[0].delta.content`. DocsGPT-specific events (sources, tool calls) arrive as extra frames with a `docsgpt` key — standard clients ignore them.
|
||||
Set `"stream": true`. You'll receive SSE chunks with `choices[0].delta.content`. DocsGPT-specific events (sources, tool calls) arrive as extra frames that carry a top-level `docsgpt` key on an otherwise-empty chunk — standard clients ignore them.
|
||||
|
||||
```python
|
||||
stream = client.chat.completions.create(
|
||||
@@ -70,6 +70,135 @@ for chunk in stream:
|
||||
print(chunk.choices[0].delta.content or "", end="", flush=True)
|
||||
```
|
||||
|
||||
## Sampling Parameters
|
||||
|
||||
Standard OpenAI sampling parameters are forwarded to the model. When omitted, the agent's configured defaults apply. Supported: `temperature`, `max_tokens` (or `max_completion_tokens`), `top_p`, `frequency_penalty`, `presence_penalty`, `stop`, `seed`.
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "docsgpt-agent",
|
||||
"messages": [{"role": "user", "content": "Write a haiku about search"}],
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 256,
|
||||
"seed": 42
|
||||
}
|
||||
```
|
||||
|
||||
## Structured Output
|
||||
|
||||
You can force the model to return JSON matching a schema, using either the OpenAI `response_format` field or the `response_schema` convenience field.
|
||||
|
||||
<Tabs items={['response_format', 'response_schema']}>
|
||||
<Tabs.Tab>
|
||||
```json
|
||||
{
|
||||
"model": "docsgpt-agent",
|
||||
"messages": [{"role": "user", "content": "Extract the order id and total"}],
|
||||
"response_format": {
|
||||
"type": "json_schema",
|
||||
"json_schema": {
|
||||
"name": "order",
|
||||
"strict": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"order_id": {"type": "string"},
|
||||
"total": {"type": "number"}
|
||||
},
|
||||
"required": ["order_id", "total"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```json
|
||||
{
|
||||
"model": "docsgpt-agent",
|
||||
"messages": [{"role": "user", "content": "Extract the order id and total"}],
|
||||
"response_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"order_id": {"type": "string"},
|
||||
"total": {"type": "number"}
|
||||
},
|
||||
"required": ["order_id", "total"]
|
||||
}
|
||||
}
|
||||
```
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
|
||||
- `response_format` follows OpenAI Structured Outputs. `strict` defaults to `true`; set `strict: false` to relax enforcement.
|
||||
- `response_format: {"type": "json_object"}` requests JSON without a fixed schema (the model is steered by the prompt).
|
||||
- `response_schema` is a DocsGPT convenience: pass a raw JSON Schema object (or a `{"schema": {...}}` wrapper) directly.
|
||||
|
||||
## Multimodal Input (text + images)
|
||||
|
||||
User messages may use OpenAI typed-content arrays with `image_url` parts. Images are forwarded to vision-capable models.
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "docsgpt-agent",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "What's in this screenshot?"},
|
||||
{"type": "image_url", "image_url": {"url": "https://example.com/shot.png"}}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Tool Calling (client-side, stateless)
|
||||
|
||||
You can register your own tools and execute them on the client. The flow is stateless — OpenAI clients that don't carry a `conversation_id` re-send the full message history each turn, and DocsGPT rebuilds the agent from it.
|
||||
|
||||
1. Send a request with a `tools` array.
|
||||
2. If the agent decides to call a tool, the response comes back with `finish_reason: "tool_calls"` and a `tool_calls` array (and `content: null`).
|
||||
3. Execute the tool(s) on your side, then **re-POST the full message history** with the assistant's `tool_calls` message followed by `role: "tool"` result messages.
|
||||
4. DocsGPT continues the run and returns the final answer.
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "docsgpt-agent",
|
||||
"messages": [
|
||||
{"role": "user", "content": "What's the weather in Paris?"},
|
||||
{"role": "assistant", "tool_calls": [
|
||||
{"id": "call_1", "type": "function",
|
||||
"function": {"name": "get_weather", "arguments": "{\"city\":\"Paris\"}"}}
|
||||
]},
|
||||
{"role": "tool", "tool_call_id": "call_1", "content": "18°C, clear"}
|
||||
],
|
||||
"tools": [ { "type": "function", "function": { "name": "get_weather", "...": "..." } } ]
|
||||
}
|
||||
```
|
||||
|
||||
## Reasoning
|
||||
|
||||
For models that emit reasoning ("thinking") tokens, the response surfaces them in a non-standard `reasoning_content` field (a `reasoning_content` delta when streaming). Standard clients ignore it; clients that understand it can display the model's thinking separately from the answer.
|
||||
|
||||
## Idempotent Retries
|
||||
|
||||
Add an `Idempotency-Key` header so a retried request returns the *stored first response* instead of re-running the agent (which would duplicate the answer and double-bill tokens).
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:7091/v1/chat/completions \
|
||||
-H "Authorization: Bearer your_agent_api_key" \
|
||||
-H "Idempotency-Key: 8f1c...unique-per-request" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"docsgpt-agent","messages":[{"role":"user","content":"hi"}]}'
|
||||
```
|
||||
|
||||
- **Opt-in** — no header means today's behavior (every request runs).
|
||||
- **Non-streaming only** — streaming replay is not supported.
|
||||
- A completed key **replays the cached body** (and status) for **24 hours**.
|
||||
- A request with a key whose first attempt is **still in flight** returns **HTTP 409**.
|
||||
- Keys are scoped per agent and capped at **256 characters** (oversized keys are rejected).
|
||||
|
||||
## System Prompt Override
|
||||
|
||||
System messages are **dropped by default** — the agent's configured prompt is used. To allow callers to override it, enable **Allow prompt override** in the agent's Advanced settings.
|
||||
@@ -80,13 +209,30 @@ When an override is active, the agent's prompt template is replaced wholesale
|
||||
|
||||
## Conversation Persistence
|
||||
|
||||
Conversations are **always persisted** server-side, and the response includes
|
||||
`docsgpt.conversation_id`. They never appear in the agent owner's sidebar —
|
||||
`/v1` traffic is stored hidden, so external clients can't clutter the owner's
|
||||
conversation list.
|
||||
Conversations are **always persisted** server-side, and the response includes `docsgpt.conversation_id`. They never appear in the agent owner's sidebar — `/v1` traffic is stored hidden, so external clients can't clutter the owner's conversation list.
|
||||
|
||||
The legacy `{ "docsgpt": { "save_conversation": true } }` opt-in from older
|
||||
releases (when `/v1` was stateless by default) is deprecated and ignored.
|
||||
Stateless tool continuations (no `conversation_id`, e.g. opencode) skip persistence by default to avoid writing orphan rows; set `docsgpt.persist` to override. The legacy `docsgpt.save_conversation` flag from older releases is deprecated and ignored.
|
||||
|
||||
## DocsGPT Extension Fields
|
||||
|
||||
DocsGPT adds an optional `docsgpt` object to both requests and responses for features outside the OpenAI schema.
|
||||
|
||||
**Request** (`docsgpt.*`):
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `attachments` | List of attachment IDs to include as context for this turn. |
|
||||
| `persist` | Force-enable/disable conversation persistence (mainly for stateless tool continuations). |
|
||||
|
||||
**Response** (`docsgpt.*`):
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `conversation_id` | Server-side conversation ID for this exchange. |
|
||||
| `sources` | RAG sources used to answer. |
|
||||
| `tool_calls` | Completed tool-call results from the run. |
|
||||
|
||||
When streaming, these arrive on otherwise-empty chunks that carry a top-level `docsgpt` key, so strict OpenAI clients still validate each frame.
|
||||
|
||||
## When to Use Native Endpoints Instead
|
||||
|
||||
|
||||
@@ -88,6 +88,28 @@ Send an HTTP `POST` request to the agent's unique webhook URL with the required
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
|
||||
### Triggering with GET (query parameters)
|
||||
|
||||
The webhook listener also accepts `GET` requests, mapping the query string to the payload. This is handy for systems that can only issue a simple `GET` (for example a "ping this URL" integration):
|
||||
|
||||
```bash
|
||||
curl "http://localhost:7091/api/webhooks/agents/your_webhook_token?question=Your+message+to+agent"
|
||||
```
|
||||
|
||||
As with `POST`, the response is a JSON object containing the `task_id`.
|
||||
|
||||
### Preventing duplicate triggers (Idempotency-Key)
|
||||
|
||||
To make a trigger safe to retry, send an optional `Idempotency-Key` header. If the same key is seen again within 24 hours, DocsGPT does not enqueue a second task — it returns the **original** `task_id` instead. This prevents a retried or double-fired webhook from running the agent twice.
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
http://localhost:7091/api/webhooks/agents/your_webhook_token \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Idempotency-Key: order-4567-created" \
|
||||
-d '{"question": "Your message to agent"}'
|
||||
```
|
||||
|
||||
### Step 2: Poll for the Result
|
||||
|
||||
Once you have the `task_id`, periodically send a `GET` request to the `/api/task_status` endpoint until the task `status` is `SUCCESS` or `FAILURE`.
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
title: Access Control, Roles & Teams
|
||||
description: How DocsGPT models permissions — global admin/user roles (RBAC), the admin dashboard, teams with per-team roles, and sharing agents, sources, prompts, and tools.
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
# Access Control, Roles & Teams
|
||||
|
||||
DocsGPT has two independent permission planes:
|
||||
|
||||
- **Global RBAC** — every user holds the `admin` or `user` role for the whole instance. Admins can manage other users and see instance-wide usage and audit data.
|
||||
- **Team roles** — within a team a user is a `team_admin` or `team_member`, and resources can be shared to teams or individual members.
|
||||
|
||||
The two planes never mix: a global `admin` is a superuser over *all* teams, but a `team_admin` is **not** a global admin.
|
||||
|
||||
<Callout type="info" emoji="🔒">
|
||||
Roles are resolved **server-side on every request** and are never trusted from the JWT. The frontend route guards are cosmetic — the server-side decorators are the real boundary. Persisted roles apply under `AUTH_TYPE=oidc`; token-only modes (`simple_jwt`, `session_jwt`) can never hold the admin role.
|
||||
</Callout>
|
||||
|
||||
## Global roles (RBAC)
|
||||
|
||||
| Role | Capabilities |
|
||||
| --- | --- |
|
||||
| `user` | The default. Owns their own conversations, sources, agents, prompts, and tools. |
|
||||
| `admin` | Everything a user can do, plus the [admin dashboard](#admin-dashboard): user management, force-logout, role management, and instance-wide usage/audit. |
|
||||
|
||||
To see the roles the current request resolves to, call:
|
||||
|
||||
```text
|
||||
GET /api/user/me → { "user_id": "...", "roles": ["user"], "email": "...", "name": "...", "picture": "..." }
|
||||
```
|
||||
|
||||
This is the canonical way to check a caller's effective roles (distinct from `/api/config`, which only reports the instance `auth_type`).
|
||||
|
||||
## Granting admin
|
||||
|
||||
There are four ways an account becomes an admin:
|
||||
|
||||
1. **The `grant_admin` script** — run `python scripts/grant_admin.py <user_id>` on the server to grant (or `--revoke` / `--list`) the admin role directly. This is the canonical bootstrap for the first admin.
|
||||
2. **OIDC group mapping** — `OIDC_ADMIN_GROUPS` auto-grants admin to members of the listed IdP groups. See [below](#admin-via-oidc-groups).
|
||||
3. **Local no-auth mode** — `LOCAL_MODE_ADMIN=true` grants admin when `AUTH_TYPE=None` (self-host, no authentication).
|
||||
4. **Grant by an existing admin** — through the admin API/dashboard.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `OIDC_ADMIN_GROUPS` | — | Comma-separated IdP groups whose members are granted the global `admin` role. Re-checked at every login and silent renewal. Unset = no OIDC admin mapping. |
|
||||
| `LOCAL_MODE_ADMIN` | `false` | Grants admin in no-auth mode only (`AUTH_TYPE=None`). |
|
||||
|
||||
<Callout type="warning" emoji="⚠️">
|
||||
**Never set `LOCAL_MODE_ADMIN=true` on a networked deployment.** It only makes sense for a single-user local install with `AUTH_TYPE=None`, where there is no identity to check.
|
||||
</Callout>
|
||||
|
||||
### Bootstrapping the first admin
|
||||
|
||||
Granting admin through the dashboard itself requires *already being* an admin, which creates a chicken-and-egg problem on a fresh deployment. Break it one of these ways:
|
||||
|
||||
- **Run the script** on the server: `python scripts/grant_admin.py <user_id>` (the `user_id` is the OIDC `sub`). The grant is written to `user_roles` with `source='manual'` and takes effect on the user's next request. Use `--list` to see current admins and `--revoke` to remove a manual grant.
|
||||
- Set `OIDC_ADMIN_GROUPS` to a group you belong to, and sign in — you become an admin automatically.
|
||||
- For a no-auth local install, use `LOCAL_MODE_ADMIN=true`.
|
||||
|
||||
### Admin via OIDC groups
|
||||
|
||||
When `OIDC_ADMIN_GROUPS` is set, group membership is mapped to the admin role at every sign-in *and* every [silent renewal](/Deploying/OIDC-SSO#silent-session-renewal) — so removing a user from the admin group revokes their admin at the next renewal, just like the [sign-in allowlist](/Deploying/OIDC-SSO#restricting-sign-in-by-group). It is independent of `OIDC_ALLOWED_GROUPS` (which controls *whether* a user may sign in at all). Leaving `OIDC_ADMIN_GROUPS` unset never mass-revokes admin.
|
||||
|
||||
```env
|
||||
OIDC_ADMIN_GROUPS=platform-admins
|
||||
# OIDC_GROUPS_CLAIM=groups # only if your IdP uses a different claim name
|
||||
```
|
||||
|
||||
If your IdP only exposes groups via the userinfo endpoint, DocsGPT backfills them from there during reconciliation, the same as the allowlist.
|
||||
|
||||
## Admin dashboard
|
||||
|
||||
Admins get a dashboard backed by a REST surface under `/api/admin` (every endpoint requires the admin role). All mutating actions are written to the `auth_events` audit log with the acting admin recorded in the metadata.
|
||||
|
||||
| Method | Path | Description |
|
||||
| --- | --- | --- |
|
||||
| `GET` | `/api/admin/overview` | Instance overview counts. |
|
||||
| `GET` | `/api/admin/users` | List users (paginated; supports a `user_id` filter). |
|
||||
| `GET` | `/api/admin/users/<id>` | Drill into a single user. |
|
||||
| `PATCH` | `/api/admin/users/<id>` | Activate / deactivate a user (deactivation revokes their sessions). |
|
||||
| `POST` | `/api/admin/users/<id>/role` | Grant the admin role (guards against removing the last admin). |
|
||||
| `DELETE` | `/api/admin/users/<id>/role` | Revoke the admin role. |
|
||||
| `POST` | `/api/admin/users/<id>/revoke-sessions` | Force-logout a user. |
|
||||
| `GET` | `/api/admin/admins` | List current admins. |
|
||||
| `GET` | `/api/admin/usage` | Token-usage series and top users. |
|
||||
| `GET` | `/api/admin/audit` | Authentication/admin audit feed. |
|
||||
| `GET` | `/api/admin/devices/audit` | Remote-device audit feed. |
|
||||
| `GET` | `/api/admin/teams` | Instance-wide oversight of all teams. |
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
Deactivating a user via the dashboard works for any auth type, while OIDC deployments can also offboard through [SCIM](/Deploying/OIDC-SSO#scim-user-provisioning). Both revoke live sessions immediately.
|
||||
</Callout>
|
||||
|
||||
## Teams
|
||||
|
||||
Teams let a group of users collaborate and share resources. Teams are self-serve — any user can create one and manage its membership.
|
||||
|
||||
### Team roles
|
||||
|
||||
| Role | Capabilities |
|
||||
| --- | --- |
|
||||
| `team_member` | Belongs to the team; can use resources shared with the team. |
|
||||
| `team_admin` | Manages membership and team settings. Implies `team_member`. |
|
||||
|
||||
The team **owner** is a distinct concept from `team_admin`: ownership can be transferred, and a global `admin` is treated as a superuser over every team.
|
||||
|
||||
### Managing a team
|
||||
|
||||
| Method | Path | Description |
|
||||
| --- | --- | --- |
|
||||
| `GET` / `POST` | `/api/teams` | List your teams / create a team. |
|
||||
| `GET` / `PATCH` / `DELETE` | `/api/teams/<id>` | Read, update, or delete a team. |
|
||||
| `GET` / `POST` | `/api/teams/<id>/members` | List members / add a member. |
|
||||
| `PATCH` / `DELETE` | `/api/teams/<id>/members/<member_id>` | Change a member's role / remove (or leave). |
|
||||
| `POST` | `/api/teams/<id>/transfer_owner` | Transfer ownership. |
|
||||
|
||||
Membership and removal are guarded so a team can never be left without an admin (the last-admin guard).
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
Members are added by email (or subject id). The invitee **must have signed in at least once** so DocsGPT can resolve them to a user account.
|
||||
</Callout>
|
||||
|
||||
## Sharing resources with a team
|
||||
|
||||
Four resource types can be shared: **agents**, **sources**, **prompts**, and **tools**. Sharing is **additive** — it grants access to others without changing ownership.
|
||||
|
||||
| Method | Path | Description |
|
||||
| --- | --- | --- |
|
||||
| `GET` / `POST` / `DELETE` | `/api/teams/<id>/grants` | List, create, or revoke a share within a team. |
|
||||
| `GET` | `/api/resource_shares` | List shares visible to the caller. |
|
||||
|
||||
Sharing rules:
|
||||
|
||||
- Only the **owner** of a resource can share it.
|
||||
- A share targets either the **whole team** or a **single member**.
|
||||
- Each share carries an access level: **`viewer`** (read-only) or **`editor`** (read and modify).
|
||||
- `editor` is not the same as owner — an editor can change a resource but cannot delete it or re-share it.
|
||||
- Shared tools run server-side with the **owner's** credentials; a grantee never sees the owner's secrets.
|
||||
|
||||
## Audit log
|
||||
|
||||
Access-control actions are appended to the `auth_events` table alongside the [authentication events](/Deploying/OIDC-SSO#login-auditing). This includes admin actions — `admin_user_activated` / `admin_user_deactivated`, `admin_sessions_revoked`, `role_granted` / `role_revoked` (with `metadata.source` = `manual` or `oidc_group`) — and team events (`team.create`, `team.member_add`, `team.member_role`, `team.member_remove`, `team.share`, `team.unshare`, `team.transfer_owner`, `team.delete`). The acting admin is recorded in the event metadata.
|
||||
|
||||
## Related
|
||||
|
||||
- [SSO with OIDC](/Deploying/OIDC-SSO) — sign-in, group allowlists, and the `auth_events` table.
|
||||
- [App Configuration](/Deploying/DocsGPT-Settings) — the full settings reference.
|
||||
@@ -388,6 +388,54 @@ gated by CI/CD).
|
||||
migration path.
|
||||
</Callout>
|
||||
|
||||
## Retrieval & RAG Settings
|
||||
|
||||
These control how sources are retrieved and whether the advanced RAG features are available. See [Per-Source Configuration](/Sources/Per-source-configuration) and [GraphRAG](/Sources/GraphRAG) for details.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `RETRIEVERS_ENABLED` | `["classic", "default"]` | Allow-list of retrievers usable instance-wide. Valid keys: `classic`, `default`, `hybrid`, `graphrag`. A per-source `retriever` must be within this list. |
|
||||
| `PER_SOURCE_RETRIEVAL_ENABLED` | `true` | Master switch for per-source retrieval config. When `false`, all sources fall back to the classic retriever regardless of their stored config. |
|
||||
| `GRAPHRAG_ENABLED` | `false` | Enable [GraphRAG](/Sources/GraphRAG). Requires `VECTOR_STORE=pgvector`. |
|
||||
| `GRAPHRAG_EXTRACTION_MODEL` | unset | Model used for ingest-time graph extraction. Unset reuses the instance default model. |
|
||||
| `GRAPHRAG_MAX_CHUNKS_FOR_EXTRACTION` | `2000` | Hard cap on chunks extracted per source (cost control). |
|
||||
|
||||
## Embeddings Settings
|
||||
|
||||
See [Embeddings](/Models/embeddings) for full guidance.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `EMBEDDINGS_NAME` | `huggingface_sentence-transformers/all-mpnet-base-v2` | The embedding model. |
|
||||
| `EMBEDDINGS_BASE_URL` | unset | Base URL of a remote OpenAI-compatible embeddings server. Setting it routes all embedding calls there. |
|
||||
| `EMBEDDINGS_KEY` | unset | Optional bearer token for the remote embeddings server. |
|
||||
| `EMBEDDINGS_MAX_INPUT_TOKENS` | unset | Truncate each remote embedding input to N tokens (guards servers that reject oversized inputs). |
|
||||
|
||||
## Tools Settings
|
||||
|
||||
| Setting | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `DEFAULT_CHAT_TOOLS` | `["memory", "read_webpage", "scheduler"]` | Tools enabled automatically in regular (agentless) chats. See [Tools Basics](/Tools/basics#default-chat-tools). |
|
||||
|
||||
## Admin & Access Settings
|
||||
|
||||
See [Access Control, Roles & Teams](/Deploying/Access-Control) for the full model.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `OIDC_ADMIN_GROUPS` | unset | Comma-separated IdP groups granted the global `admin` role (OIDC only). |
|
||||
| `LOCAL_MODE_ADMIN` | `false` | Grants admin in no-auth mode (`AUTH_TYPE=None`) only. **Never enable on a networked deployment.** |
|
||||
|
||||
## LLM Provider Settings
|
||||
|
||||
| Setting | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `OPENAI_RESPONSES_STORE` | `false` | When `true`, allows OpenAI to persist [Responses API](/Models/cloud-providers#openai-responses-api-and-reasoning) state server-side. |
|
||||
|
||||
## Realtime Events Settings
|
||||
|
||||
The realtime notifications channel has its own settings — see [Realtime Events & Notifications](/Agents/notifications) (`ENABLE_SSE_PUSH`, `EVENTS_STREAM_MAXLEN`, `SSE_MAX_CONCURRENT_PER_USER`, and related).
|
||||
|
||||
## Exploring More Settings
|
||||
|
||||
These are just the basic settings to get you started. The `settings.py` file contains many more advanced options that you can explore to further customize DocsGPT, such as:
|
||||
|
||||
@@ -43,6 +43,7 @@ Sessions last `OIDC_SESSION_LIFETIME_SECONDS` (8 hours by default) and renew wit
|
||||
| `OIDC_SESSION_LIFETIME_SECONDS` | no | `28800` (8h) | Lifetime of the DocsGPT session JWT. Sessions renew before expiry — see [Silent session renewal](#silent-session-renewal). |
|
||||
| `OIDC_PROVIDER_NAME` | no | — | Display name on the sign-in button: `Acme SSO` renders "Sign in with Acme SSO". Unset, the button shows a generic "SSO". |
|
||||
| `OIDC_ALLOWED_GROUPS` | no | — | Comma-separated group allowlist. Unset, any authenticated IdP user may sign in — see [Restricting sign-in by group](#restricting-sign-in-by-group). |
|
||||
| `OIDC_ADMIN_GROUPS` | no | — | Comma-separated groups whose members are granted the global `admin` role. Re-checked at every login and renewal — see [Granting admin via groups](#granting-admin-via-groups). |
|
||||
| `OIDC_GROUPS_CLAIM` | no | `groups` | ID-token/userinfo claim carrying the user's group membership. |
|
||||
| `JWT_SECRET_KEY` | recommended | auto-generated | Signs DocsGPT session tokens. Set it explicitly in production — required when running multiple API replicas. |
|
||||
|
||||
@@ -108,6 +109,16 @@ Getting groups into the token:
|
||||
- **Authentik** includes group names in the `groups` claim through its default `profile` scope — no extra configuration needed.
|
||||
- **Keycloak** does not emit groups by default. On the client, open **Client scopes → the client's dedicated scope → Add mapper → By configuration → Group Membership**, set the claim name to `groups`, and turn **Full group path** off so the claim carries plain names (`devs`) rather than paths (`/devs`).
|
||||
|
||||
## Granting admin via groups
|
||||
|
||||
Separately from *who may sign in*, you can map an IdP group to the global **admin** role with `OIDC_ADMIN_GROUPS`:
|
||||
|
||||
```env
|
||||
OIDC_ADMIN_GROUPS=platform-admins
|
||||
```
|
||||
|
||||
Members of the listed groups are granted admin; the mapping is re-evaluated at every login **and** every [silent renewal](#silent-session-renewal), so removing a user from the admin group revokes their admin at the next renewal (exactly like the sign-in allowlist). It is independent of `OIDC_ALLOWED_GROUPS`, and leaving it unset never mass-revokes admin. On a fresh deployment this is the only way to create the first admin. For the full roles, teams, and admin-dashboard model see [Access Control, Roles & Teams](/Deploying/Access-Control).
|
||||
|
||||
## Silent session renewal
|
||||
|
||||
The DocsGPT session JWT lives for `OIDC_SESSION_LIFETIME_SECONDS` (default 8 hours). Sessions renew without user-visible interruptions, in one of two ways:
|
||||
@@ -183,6 +194,12 @@ Authentication activity is recorded in `auth_events`, an append-only Postgres ta
|
||||
| `oidc_refresh` | A session is silently renewed. |
|
||||
| `backchannel_logout` | The IdP revokes sessions via back-channel logout. |
|
||||
| `scim_created` / `scim_deactivated` / `scim_reactivated` | SCIM lifecycle changes. |
|
||||
| `role_granted` / `role_revoked` | The admin role is granted/revoked (`metadata.source` is `manual` or `oidc_group`). |
|
||||
| `admin_user_activated` / `admin_user_deactivated` | An admin activates/deactivates a user. |
|
||||
| `admin_sessions_revoked` | An admin force-logs-out a user. |
|
||||
| `team.*` | Team management — `team.create`, `team.member_add`, `team.member_role`, `team.member_remove`, `team.share`, `team.unshare`, `team.transfer_owner`, `team.delete`. |
|
||||
|
||||
The acting admin is recorded in the event metadata. See [Access Control, Roles & Teams](/Deploying/Access-Control) for the admin and team features that emit these events.
|
||||
|
||||
There is no UI for these events yet — query the table directly:
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@ export default {
|
||||
"title": "🔐 SSO with OIDC",
|
||||
"href": "/Deploying/OIDC-SSO"
|
||||
},
|
||||
"Access-Control": {
|
||||
"title": "👥 Access Control & Teams",
|
||||
"href": "/Deploying/Access-Control"
|
||||
},
|
||||
"Docker-Deploying": {
|
||||
"title": "🛳️ Docker Setup",
|
||||
"href": "/Deploying/Docker-Deploying"
|
||||
|
||||
@@ -68,6 +68,16 @@ flowchart LR
|
||||
* Provides storage and indexing of high-dimensional vector embeddings.
|
||||
* Enables editing and updating of vector indexes including specific chunks.
|
||||
|
||||
### 4a. Retrieval Layer (Part of backend)
|
||||
|
||||
* **Responsibility:** Sits between the API and the vector stores and decides *how* context is fetched for each question. Rather than a single similarity search, a **retriever dispatcher** groups the question's sources by their configured retriever and runs each under a shared token budget, then applies post-retrieval stages before answering.
|
||||
* **Key Features:**
|
||||
* Multiple retrievers: `classic` (vector similarity), `hybrid` (vector + full-text keyword fusion), and `graphrag` (knowledge-graph / Personalized PageRank).
|
||||
* Optional query rephrasing before retrieval.
|
||||
* Optional post-retrieval stages such as LLM pre-screening (map-reduce relevance filtering).
|
||||
* Per-source behavior via the [per-source configuration](/Sources/Per-source-configuration) contract, so different sources can be chunked and retrieved differently.
|
||||
* See [GraphRAG](/Sources/GraphRAG) for the knowledge-graph retrieval path.
|
||||
|
||||
### 5. Parser Integration Layer (Part of backend)
|
||||
|
||||
* **Technology:** Supports multiple formats for file processing and remote source uploading.
|
||||
@@ -101,14 +111,17 @@ sequenceDiagram
|
||||
participant User
|
||||
participant Frontend
|
||||
participant BackendAPI
|
||||
participant RetrievalLayer
|
||||
participant LLMIntegrationLayer
|
||||
participant VectorStores
|
||||
participant InferenceEngine
|
||||
|
||||
User->>Frontend: User asks a question
|
||||
Frontend->>BackendAPI: API Request (Question)
|
||||
BackendAPI->>VectorStores: Fetch relevant document chunks (Similarity Search)
|
||||
VectorStores-->>BackendAPI: Return document chunks
|
||||
BackendAPI->>RetrievalLayer: Dispatch retrieval (per-source: classic / hybrid / graphrag)
|
||||
RetrievalLayer->>VectorStores: Fetch candidates (vector / keyword / graph)
|
||||
VectorStores-->>RetrievalLayer: Return candidates
|
||||
RetrievalLayer-->>BackendAPI: Ranked, optionally pre-screened chunks
|
||||
BackendAPI->>LLMIntegrationLayer: Send question and document chunks
|
||||
LLMIntegrationLayer->>InferenceEngine: LLM API Request (Prompt + Context)
|
||||
InferenceEngine-->>LLMIntegrationLayer: LLM API Response (Answer)
|
||||
|
||||
@@ -25,13 +25,17 @@ DocsGPT offers direct, streamlined support for the following cloud LLM providers
|
||||
| :--------------------------- | :------------- | :-------------------------- |
|
||||
| DocsGPT Public API | `docsgpt` | `None` |
|
||||
| OpenAI | `openai` | `gpt-5.1` |
|
||||
| OpenAI-compatible (BYOM) | `openai_compatible` | (any; with per-model `base_url`/`api_key`) |
|
||||
| Google (Vertex AI, Gemini) | `google` | `gemini-3.5-flash` |
|
||||
| Anthropic (Claude) | `anthropic` | `claude-3-5-sonnet-20241022`|
|
||||
| Groq | `groq` | `llama-3.3-70b-versatile` |
|
||||
| OpenRouter | `openrouter` | (See OpenRouter docs) |
|
||||
| Novita AI | `novita` | (See Novita docs) |
|
||||
| HuggingFace Inference API | `huggingface` | `meta-llama/Llama-3.1-8B-Instruct` |
|
||||
| Prem AI | `premai` | (See Prem AI docs) |
|
||||
| AWS SageMaker | `sagemaker` | (See SageMaker docs) |
|
||||
| Novita AI | `novita` | (See Novita docs) |
|
||||
|
||||
DocsGPT also ships a **model catalog** (`application/core/models/*.yaml`) that the in-app model picker reads, so common models from these providers — including DeepSeek — appear ready to select once the matching API key is set.
|
||||
|
||||
## Connecting to OpenAI-Compatible Cloud APIs
|
||||
|
||||
@@ -52,6 +56,21 @@ OPENAI_BASE_URL=https://api.deepseek.com/v1 # DeepSeek's OpenAI API URL
|
||||
|
||||
Remember to consult the documentation of your chosen OpenAI-compatible cloud provider for their specific API endpoint, required model names, and authentication methods.
|
||||
|
||||
### Dedicated `openai_compatible` provider (bring-your-own-model)
|
||||
|
||||
Beyond the global `OPENAI_BASE_URL`, DocsGPT has a first-class `openai_compatible` provider. It lets a model carry its **own** `base_url` and `api_key`, which is how per-user "bring your own model" (BYOM) endpoints work — each model can point at a different OpenAI-compatible server without changing instance-wide settings. Outbound requests use an SSRF-pinned HTTP client for safety.
|
||||
|
||||
This is the mechanism behind catalog entries like DeepSeek, which declare their own `base_url` and API key environment variable rather than relying on `OPENAI_BASE_URL`.
|
||||
|
||||
## OpenAI Responses API and reasoning
|
||||
|
||||
For OpenAI models that support it, DocsGPT can call the newer **Responses API** (`/v1/responses`) instead of Chat Completions. This is selected per model in the catalog via an `api_flavor: responses` capability and enables features like server-side reasoning. Related settings:
|
||||
|
||||
- `reasoning_effort` — per-model reasoning effort hint (for example `medium`) declared in the model catalog.
|
||||
- `OPENAI_RESPONSES_STORE` (default `false`) — when `true`, lets OpenAI persist Responses API state server-side.
|
||||
|
||||
See [App Configuration](/Deploying/DocsGPT-Settings) for the full settings reference.
|
||||
|
||||
## Adding Support for Other Cloud Providers
|
||||
|
||||
If you wish to connect to a cloud provider that is not explicitly listed above or doesn't offer OpenAI API compatibility, you can extend DocsGPT to support it. Within the DocsGPT repository, navigate to the `application/llm` directory. Here, you will find Python files defining the existing LLM integrations. You can use these files as examples to create a new module for your desired cloud provider. After creating your new LLM module, you will need to register it within the `llm_creator.py` file. This process involves some coding, but it allows for virtually unlimited extensibility to connect to any cloud-based LLM service with an accessible API.
|
||||
@@ -22,10 +22,12 @@ In essence, embedding models are the bridge that allows DocsGPT to understand th
|
||||
|
||||
## Out-of-the-Box Embedding Model Support in DocsGPT
|
||||
|
||||
DocsGPT is designed to be flexible and supports a wide range of embedding models right out of the box. Currently, DocsGPT provides native support for models from two major sources:
|
||||
DocsGPT is designed to be flexible and supports a wide range of embedding models right out of the box:
|
||||
|
||||
* **Sentence Transformers:** DocsGPT supports all models available through the [Sentence Transformers library](https://www.sbert.net/). This library offers a vast selection of pre-trained embedding models, known for their quality and efficiency in various semantic tasks.
|
||||
* **OpenAI Embeddings:** DocsGPT also supports using embedding models from OpenAI, specifically the `text-embedding-ada-002` model, which is a powerful and widely used embedding model from OpenAI's API.
|
||||
* **Sentence Transformers:** DocsGPT supports all models available through the [Sentence Transformers library](https://www.sbert.net/). This library offers a vast selection of pre-trained embedding models, known for their quality and efficiency in various semantic tasks. This is the default (`EMBEDDINGS_NAME=huggingface_sentence-transformers/all-mpnet-base-v2`).
|
||||
* **OpenAI Embeddings:** DocsGPT supports OpenAI embedding models (for example `text-embedding-ada-002`, `text-embedding-3-small`, `text-embedding-3-large`) via the OpenAI API.
|
||||
* **Azure OpenAI Embeddings:** Set `AZURE_EMBEDDINGS_DEPLOYMENT_NAME` alongside your Azure OpenAI configuration.
|
||||
* **Remote OpenAI-compatible Embeddings:** Any server that exposes an OpenAI-compatible `/v1/embeddings` endpoint (for example llama.cpp, vLLM, TEI, or a hosted provider) by setting `EMBEDDINGS_BASE_URL`. See [Remote Embeddings](#remote-openai-compatible-embeddings) below.
|
||||
|
||||
## Configuring Sentence Transformer Models
|
||||
|
||||
@@ -65,6 +67,36 @@ API_KEY=YOUR_OPENAI_API_KEY # Your OpenAI API Key
|
||||
EMBEDDINGS_NAME=openai_text-embedding-ada-002
|
||||
```
|
||||
|
||||
## Remote (OpenAI-compatible) Embeddings
|
||||
|
||||
If you run your own embedding server, or use a provider that exposes an OpenAI-style embeddings API, point DocsGPT at it with `EMBEDDINGS_BASE_URL`. When this is set, all embedding calls (ingestion and querying) are sent to `{EMBEDDINGS_BASE_URL}/v1/embeddings` in OpenAI format instead of running a local model.
|
||||
|
||||
```env
|
||||
EMBEDDINGS_BASE_URL=http://localhost:8080 # your OpenAI-compatible embeddings server
|
||||
EMBEDDINGS_NAME=your-model-name # sent as the "model" field in the request
|
||||
EMBEDDINGS_KEY=YOUR_API_KEY # optional; sent as a Bearer token
|
||||
```
|
||||
|
||||
- `EMBEDDINGS_BASE_URL` — base URL of the remote server. Setting it switches DocsGPT into remote-embeddings mode.
|
||||
- `EMBEDDINGS_NAME` — forwarded as the `model` field in each request.
|
||||
- `EMBEDDINGS_KEY` — optional bearer token. If you are using OpenAI directly you can copy `API_KEY` here.
|
||||
|
||||
### Guarding against oversized inputs
|
||||
|
||||
Some remote servers (notably llama.cpp) reject any single input larger than their physical batch size with a `500` error. Set `EMBEDDINGS_MAX_INPUT_TOKENS` to clip each input to a fixed number of tokens before it is sent:
|
||||
|
||||
```env
|
||||
EMBEDDINGS_MAX_INPUT_TOKENS=512
|
||||
```
|
||||
|
||||
When set, each input string is truncated to that many tokens and the overflow is dropped (lossy by design). Token counts use DocsGPT's shared tiktoken encoding, which differs from your server's tokenizer, so choose a limit with some headroom below the server's true limit to absorb tokenizer skew. Leave the setting unset (or `0`) to disable truncation.
|
||||
|
||||
## Important: Embedding Dimensions Must Stay Consistent
|
||||
|
||||
Each embedding model produces vectors of a fixed dimension, and your vector store is created with that dimension. **Changing `EMBEDDINGS_NAME` to a model with a different dimension is not compatible with an existing index** — FAISS and LanceDB will raise a dimension-mismatch error, and pgvector/Qdrant tables are sized to the original dimension.
|
||||
|
||||
If you need to switch embedding models, you must re-ingest your sources so the index is rebuilt with the new dimension. This also applies to the [GraphRAG](/Sources/GraphRAG) graph tables, which are sized to the embedding dimension at creation time.
|
||||
|
||||
## Adding Support for Other Embedding Models
|
||||
|
||||
If you wish to use an embedding model that is not supported out-of-the-box, a good starting point for adding custom embedding model support is to examine the `base.py` file located in the `application/vectorstore` directory.
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
---
|
||||
title: GraphRAG — Knowledge-Graph Retrieval
|
||||
description: Build a knowledge graph from a source at ingest time and retrieve over it with Personalized PageRank. Covers requirements, enabling, configuration, and the graph view.
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
import Image from 'next/image'
|
||||
|
||||
# GraphRAG
|
||||
|
||||
GraphRAG augments classic vector retrieval with a **knowledge graph**. During ingestion DocsGPT uses an LLM to extract entities and the relationships between them from a source's chunks, and stores them as a graph alongside the vectors. At query time, a graph retriever uses Personalized PageRank (PPR) to walk that graph from the entities mentioned in your question, surfacing connected context that pure similarity search can miss — useful for multi-hop questions and queries that span related concepts.
|
||||
|
||||
<Callout type="warning" emoji="⚠️">
|
||||
GraphRAG is **flag-gated** and currently **pgvector-only**. It is available only when both `GRAPHRAG_ENABLED=true` **and** `VECTOR_STORE=pgvector`. On any other vector store the enable action is rejected.
|
||||
</Callout>
|
||||
|
||||
## Requirements
|
||||
|
||||
- A PostgreSQL database with the `pgvector` extension (`VECTOR_STORE=pgvector`). See [PostgreSQL for User Data](/Deploying/Postgres-Migration).
|
||||
- `GRAPHRAG_ENABLED=true` in your environment.
|
||||
- An LLM configured for extraction (GraphRAG reuses your instance default model unless you override it).
|
||||
|
||||
```env
|
||||
GRAPHRAG_ENABLED=true
|
||||
VECTOR_STORE=pgvector
|
||||
```
|
||||
|
||||
The graph tables live in the same pgvector database as your embeddings and are sized to the embedding dimension. If you change embedding models you must re-ingest and re-extract (see [Embeddings](/Models/embeddings#important-embedding-dimensions-must-stay-consistent)).
|
||||
|
||||
## How it works
|
||||
|
||||
1. **Choose GraphRAG** for the source — either at upload time, or by enabling it on an existing source (see below). This sets the source's config to `graphrag` mode.
|
||||
2. **Extraction** runs over the source's chunks. For each chunk, the LLM extracts entities and relations, which are written into per-source graph tables. Extraction is durable and resumable via a checkpoint, so it survives restarts and re-runs from scratch each time you re-enable it.
|
||||
3. **Query.** Questions against the source are routed to the graph retriever, which runs Personalized PageRank from the query's entities to gather related context.
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
If a source has no graph yet (extraction still running or failed), the graph retriever **falls back to classic vector retrieval** for that source — answers keep working, they just don't use the graph until it is ready.
|
||||
</Callout>
|
||||
|
||||
## Enabling GraphRAG
|
||||
|
||||
### At upload time (recommended)
|
||||
|
||||
When you upload a new document, open **Advanced settings** and set **Retriever** to **GraphRAG** (the same dropdown also offers **Hybrid**). The source is created in `graphrag` mode and extraction is enqueued as part of ingestion — no extra step.
|
||||
|
||||
<Image
|
||||
src="/graph-rag-settings-before-upload.png"
|
||||
alt="Upload dialog advanced settings showing the Retriever dropdown with Classic, Hybrid, and GraphRAG options"
|
||||
width={661}
|
||||
height={945}
|
||||
/>
|
||||
|
||||
These are the same [per-source retrieval settings](/Sources/Per-source-configuration) you can change later — choosing the retriever up front just avoids a re-ingest.
|
||||
|
||||
### On an existing source
|
||||
|
||||
To turn an already-ingested source into a GraphRAG source, use the **Enable GraphRAG** action on the source (it shows a status badge while extraction runs), or call the API:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-docsgpt/api/sources/<source_id>/graphrag/enable \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
The response returns a `task_id` for the extraction job:
|
||||
|
||||
```json
|
||||
{ "success": true, "task_id": "..." }
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Requires write access to the source (owner or team `editor`).
|
||||
- Returns `400` if GraphRAG isn't available on the workspace (wrong vector store or flag off).
|
||||
- Re-running the action rebuilds the graph from scratch rather than no-opping against an existing one.
|
||||
- You cannot switch a source to `graphrag` through the [config PATCH endpoint](/Sources/Per-source-configuration#editing-the-config-via-api) — use the upload-time selector or this dedicated endpoint.
|
||||
|
||||
## Configuration
|
||||
|
||||
Instance-wide settings (see [App Configuration](/Deploying/DocsGPT-Settings)):
|
||||
|
||||
| Setting | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `GRAPHRAG_ENABLED` | `false` | Master switch for the feature. |
|
||||
| `GRAPHRAG_EXTRACTION_MODEL` | `null` | Model used for extraction. `null` reuses the instance default model. |
|
||||
| `GRAPHRAG_MAX_CHUNKS_FOR_EXTRACTION` | `2000` | Hard cap on how many chunks are extracted per source (cost control). |
|
||||
|
||||
Per-source extraction knobs live under the source config's `graph` object and override the instance defaults:
|
||||
|
||||
| Field | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `extraction_model` | `null` | Override the extraction model for this source. |
|
||||
| `max_chunks` | `null` | Override the chunk cap; `null` falls back to `GRAPHRAG_MAX_CHUNKS_FOR_EXTRACTION`. |
|
||||
| `gleanings` | `0` | Extra extraction passes per chunk to catch entities missed on the first pass. Off by default (each pass costs additional LLM calls). |
|
||||
|
||||
<Callout type="warning" emoji="⚠️">
|
||||
Graph extraction makes an LLM call per chunk (more if `gleanings > 0`), so it has a real token cost. The cost is attributed to token usage under a `graph_extraction` tag, and the `max_chunks` cap bounds it.
|
||||
</Callout>
|
||||
|
||||
## Visualizing the graph
|
||||
|
||||
GraphRAG sources expose a **graph view** in the UI — an interactive network of the extracted entities and relationships. It is backed by two read endpoints:
|
||||
|
||||
```text
|
||||
GET /api/sources/<source_id>/graph # bounded {nodes, edges} overview
|
||||
GET /api/sources/<source_id>/graph/node/<node_id> # one node and its neighbors
|
||||
```
|
||||
|
||||
The overview is bounded to a default node limit to keep large graphs responsive.
|
||||
|
||||
## Related
|
||||
|
||||
- [Per-Source Configuration](/Sources/Per-source-configuration) — the config object GraphRAG plugs into.
|
||||
- [PostgreSQL for User Data](/Deploying/Postgres-Migration) — required pgvector setup.
|
||||
- [Embeddings](/Models/embeddings) — embedding-dimension constraints that also apply to the graph tables.
|
||||
@@ -0,0 +1,177 @@
|
||||
---
|
||||
title: Per-Source Configuration (Chunking & Retrieval)
|
||||
description: Tune how each knowledge source is chunked at ingest time and retrieved at query time — chunking strategy, retriever, exposure, top-k, pre-screening and more.
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
import Image from 'next/image'
|
||||
|
||||
# Per-Source Configuration
|
||||
|
||||
Every source in DocsGPT carries its own **behavior contract** — a small config object that controls how that source is *chunked* when it is ingested and how it is *retrieved* when you ask a question. This lets you tune each source independently: a large reference manual can use a different chunking strategy and retriever than a short FAQ.
|
||||
|
||||
You edit this config from a source's settings in the UI (shown below), or through the API. The same options are also available in **Advanced settings** when you first upload a document.
|
||||
|
||||
<Image
|
||||
src="/sources-settings-screen.png"
|
||||
alt="Source settings panel showing Retrieval options (retriever, top-k, score threshold, rephrase, exposure, prescreen) and Chunking options (strategy, max/min tokens, duplicate headers)"
|
||||
width={633}
|
||||
height={862}
|
||||
/>
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
Per-source retrieval is enabled by default. Operators can turn it off instance-wide with `PER_SOURCE_RETRIEVAL_ENABLED=false`, in which case all sources fall back to the classic retriever regardless of their stored config.
|
||||
</Callout>
|
||||
|
||||
## Two kinds of settings: live vs. bake-time
|
||||
|
||||
The config has two groups of settings that differ in *when* they take effect:
|
||||
|
||||
| Group | When it applies | Re-ingest needed? |
|
||||
| --- | --- | --- |
|
||||
| **Retrieval** (`retrieval.*`) | Query time — applied live on the next question | No |
|
||||
| **Chunking** (`chunking.*`) | Ingest time — baked into the stored chunks | **Yes** |
|
||||
|
||||
Changing a retrieval setting takes effect immediately. Changing a chunking setting only affects documents ingested *after* the change, so you must re-ingest the source to apply it to existing content. The API response includes a `requires_reingest` flag to make this explicit.
|
||||
|
||||
## Chunking configuration
|
||||
|
||||
Chunking decides how a document is split into the pieces that get embedded and stored.
|
||||
|
||||
```json
|
||||
{
|
||||
"chunking": {
|
||||
"strategy": "classic_chunk",
|
||||
"max_tokens": 1250,
|
||||
"min_tokens": 150,
|
||||
"duplicate_headers": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `strategy` | `classic_chunk` | Which chunking algorithm to use (see below). |
|
||||
| `max_tokens` | `1250` | Upper bound on chunk size in tokens. |
|
||||
| `min_tokens` | `150` | Lower bound; small fragments are merged up to this size. |
|
||||
| `duplicate_headers` | `false` | Repeat section headers into each child chunk for context. |
|
||||
|
||||
### Available chunking strategies
|
||||
|
||||
| Strategy | Behavior |
|
||||
| --- | --- |
|
||||
| `classic_chunk` | The default token-window splitter. An empty config reproduces DocsGPT's historical chunking byte-for-byte. |
|
||||
| `recursive` | Recursive character/token splitter that tries to break on natural boundaries (paragraphs, sentences). |
|
||||
| `markdown` | Splits along Markdown structure (headings, sections) — good for docs and wikis. |
|
||||
| `parent_child` | Embeds small **child** chunks for precise matching but carries a larger **parent** window in metadata, so the model still sees surrounding context. |
|
||||
| `semantic` | Embeds sentences and splits where meaning shifts (at the 95th-percentile cosine-distance gap between adjacent sentences), falling back to `recursive` on failure. Produces topically coherent chunks at the cost of extra embedding calls during ingest. |
|
||||
|
||||
<Callout type="warning" emoji="⚠️">
|
||||
Chunking is bake-time. After changing `strategy`, `max_tokens`, `min_tokens`, or `duplicate_headers`, re-ingest the source so existing chunks are rebuilt.
|
||||
</Callout>
|
||||
|
||||
## Retrieval configuration
|
||||
|
||||
Retrieval decides which chunks are pulled in to answer a question. These settings apply live.
|
||||
|
||||
```json
|
||||
{
|
||||
"retrieval": {
|
||||
"retriever": "classic",
|
||||
"exposure": "prefetch",
|
||||
"chunks": 2,
|
||||
"score_threshold": null,
|
||||
"rephrase_query": true,
|
||||
"prescreen": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `retriever` | `classic` | Retrieval strategy: `classic`, `hybrid`, or `graphrag`. |
|
||||
| `exposure` | `prefetch` | How retrieved context reaches the model: `prefetch` or `agentic_tool` (see below). |
|
||||
| `chunks` | `2` | Final number of chunks (top-k) returned to the answer. Range 1–500. |
|
||||
| `score_threshold` | `null` | Minimum similarity score. Honored by pgvector and MongoDB Atlas; other stores ignore it. |
|
||||
| `rephrase_query` | `true` | Whether to run a query-rephrasing side-call before retrieval. |
|
||||
| `prescreen` | `null` | Optional LLM relevance filter (see below). `null` = off. |
|
||||
|
||||
### Retrievers
|
||||
|
||||
- **`classic`** — Vector similarity search. The default and a safe choice for any vector store.
|
||||
- **`hybrid`** — Fuses vector search with full-text keyword search using Reciprocal Rank Fusion, which improves recall for exact terms, codes, and names that pure vector search can miss.
|
||||
- **`graphrag`** — Knowledge-graph retrieval. Set indirectly when you enable GraphRAG on a source. See [GraphRAG](/Sources/GraphRAG).
|
||||
|
||||
<Callout type="warning" emoji="⚠️">
|
||||
Keyword search for the **hybrid** retriever is currently implemented only for the **pgvector** vector store. On other stores (FAISS, Qdrant, Milvus, etc.) the keyword half returns nothing, so `hybrid` quietly behaves like `classic` (vector-only).
|
||||
</Callout>
|
||||
|
||||
Operators can restrict which retrievers are usable instance-wide with the `RETRIEVERS_ENABLED` setting; a per-source `retriever` value must be within that allow-list.
|
||||
|
||||
### Exposure: prefetch vs. agentic tool
|
||||
|
||||
`exposure` controls *how* a source's content is delivered to the model:
|
||||
|
||||
- **`prefetch`** (default) — DocsGPT retrieves the top chunks up front and injects them into the prompt before the model answers. Best for focused Q&A over a source.
|
||||
- **`agentic_tool`** — The source is exposed to the model as a search tool it can call on demand, deciding when and what to look up (browse-as-you-go) rather than receiving a bulk prefetch. This is the default exposure for [Wiki sources](/Sources/Wiki-sources).
|
||||
|
||||
### Pre-screening (LLM relevance filter)
|
||||
|
||||
Pre-screening adds an optional map-reduce step between retrieval and answering: a base retriever fetches a wider set of candidates, an LLM screens them in batches, and only the most relevant survivors are passed to the answer. It improves precision on noisy sources at the cost of extra query-time LLM calls, so it is **off by default**.
|
||||
|
||||
```json
|
||||
{
|
||||
"retrieval": {
|
||||
"chunks": 8,
|
||||
"prescreen": {
|
||||
"candidate_k": 40,
|
||||
"batch_size": 10,
|
||||
"max_keep": 8,
|
||||
"model": null
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `candidate_k` | `40` | Candidates fetched before screening. Must be `>= chunks`. |
|
||||
| `batch_size` | `10` | Candidates screened per LLM call. |
|
||||
| `max_keep` | `8` | Survivors kept after screening. Must be `<= candidate_k`. |
|
||||
| `model` | `null` | Model used for screening. `null` reuses the request's resolved model. |
|
||||
|
||||
## Editing the config via API
|
||||
|
||||
The config is edited with a `PATCH` to the source's config endpoint:
|
||||
|
||||
```bash
|
||||
curl -X PATCH https://your-docsgpt/api/sources/<source_id>/config \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"retrieval": { "retriever": "hybrid", "chunks": 4 },
|
||||
"chunking": { "strategy": "semantic" }
|
||||
}'
|
||||
```
|
||||
|
||||
The response echoes the stored config and a `requires_reingest` flag:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"config": { "...": "..." },
|
||||
"requires_reingest": true
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Invalid values are rejected with `400` (strict validation on write).
|
||||
- The `kind` field (classic / wiki / graphrag) cannot be changed through this endpoint — converting a source to a [Wiki](/Sources/Wiki-sources) or enabling [GraphRAG](/Sources/GraphRAG) uses dedicated endpoints.
|
||||
- Editing requires ownership of the source or a team `editor` grant; viewers receive `403`.
|
||||
|
||||
## Related
|
||||
|
||||
- [GraphRAG](/Sources/GraphRAG) — knowledge-graph retrieval for a source.
|
||||
- [Wiki Sources](/Sources/Wiki-sources) — LLM-editable living documentation.
|
||||
- [Embeddings](/Models/embeddings) — the embedding model used during ingest and retrieval.
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
title: Wiki Sources — Living, LLM-Editable Documentation
|
||||
description: Create a knowledge source that the agent can read and write — a living wiki it keeps up to date, with human edits, provenance stamps, and version safety.
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
# Wiki Sources
|
||||
|
||||
A **wiki source** is a knowledge source that the agent can both read *and* write. Instead of being a fixed set of ingested files, a wiki is a small set of Markdown pages that the LLM edits over time — recording what it learns, correcting stale information, and building living documentation. Humans can edit the same pages directly, and every change is stamped with who made it.
|
||||
|
||||
Unlike a classic source, a wiki is **team-scoped, not per-user**: it is shared and edited at the source level, so a whole team works against the same living document.
|
||||
|
||||
## How a wiki differs from a classic source
|
||||
|
||||
| | Classic source | Wiki source |
|
||||
| --- | --- | --- |
|
||||
| Content | Ingested files, read-only | Markdown pages, read **and** write |
|
||||
| Who edits | You (re-upload to change) | The agent and humans |
|
||||
| Default exposure | `prefetch` (chunks injected up front) | `agentic_tool` (the agent browses pages on demand) |
|
||||
| Searchability | Embedded at ingest | Re-embedded automatically on every edit |
|
||||
| Scope | Per owner | Team-shareable, edited at source scope |
|
||||
|
||||
Because a wiki defaults to the `agentic_tool` [exposure](/Sources/Per-source-configuration#exposure-prefetch-vs-agentic-tool), the agent navigates it as a tool — opening, searching, and editing pages as needed — rather than receiving a bulk prefetch.
|
||||
|
||||
## How the agent edits a wiki
|
||||
|
||||
The agent edits a wiki through an internal **Wiki tool** that is automatically scoped to one wiki source. It supports a small, edit-safe action surface:
|
||||
|
||||
- **view** a page,
|
||||
- **create** or overwrite a page,
|
||||
- **str_replace** an exact, unique string,
|
||||
- **insert** at a line,
|
||||
- **delete** a page,
|
||||
- **rename** a page.
|
||||
|
||||
Two safety properties matter:
|
||||
|
||||
- **Provenance stamps.** Every page records whether its last change came from a human or the agent, so edits are traceable.
|
||||
- **Optimistic versioning.** Edits carry an expected version; if a page changed underneath, the edit is rejected rather than silently clobbering a concurrent change. String replacements must match exactly and uniquely.
|
||||
|
||||
After any edit, the affected page is **re-embedded asynchronously** so the wiki stays searchable and the new content is immediately retrievable.
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
Each wiki page is capped at 1 MB (1,000,000 bytes). Pages are addressed by path (the home page is `/index.md`).
|
||||
</Callout>
|
||||
|
||||
## Creating a wiki
|
||||
|
||||
In the UI, choose **New wiki source** when adding a source. From the API:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-docsgpt/api/sources/wiki \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{ "name": "Team Handbook", "initial_content": "# Team Handbook\n\nWelcome." }'
|
||||
```
|
||||
|
||||
- `name` (required) — the wiki source name.
|
||||
- `initial_content` (optional) — Markdown that seeds the home page `/index.md` and triggers its first re-embed.
|
||||
|
||||
No ingestion task runs for a wiki; pages are authored directly. The response returns the new `source_id`.
|
||||
|
||||
## Converting an existing source into a wiki
|
||||
|
||||
You can turn an already-ingested source into a wiki so the agent can start maintaining it:
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-docsgpt/api/sources/<source_id>/wiki/convert \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
- A **blank** source is enabled inline (no task) and immediately becomes a wiki.
|
||||
- A source **with files** runs a conversion task that reassembles its existing chunks into wiki pages; poll the returned task for a per-file summary.
|
||||
- Conversion is rejected with `409` if the source is still ingesting — wait for it to finish first.
|
||||
|
||||
<Callout type="warning" emoji="⚠️">
|
||||
Switching a source to (or from) wiki mode goes only through `POST /api/sources/<id>/wiki/convert`. It cannot be done through the [config PATCH endpoint](/Sources/Per-source-configuration#editing-the-config-via-api).
|
||||
</Callout>
|
||||
|
||||
## Reading and editing pages directly
|
||||
|
||||
Humans can read and edit wiki pages through the API (and the wiki viewer in the UI):
|
||||
|
||||
```text
|
||||
GET /api/sources/<source_id>/wiki/pages # list pages
|
||||
GET /api/sources/<source_id>/wiki/page?path=... # fetch one page fresh
|
||||
PUT /api/sources/<source_id>/wiki/page # create or overwrite a page (human edit)
|
||||
```
|
||||
|
||||
Human edits are stamped with `human` provenance and trigger the same re-embed as agent edits. Read access follows source sharing (owner or anyone the source is shared with); writing requires owner or team `editor` access.
|
||||
|
||||
## Related
|
||||
|
||||
- [Per-Source Configuration](/Sources/Per-source-configuration) — exposure and retrieval settings a wiki uses.
|
||||
- [Access Control & Teams](/Deploying/Access-Control) — sharing a wiki with a team.
|
||||
@@ -0,0 +1,14 @@
|
||||
export default {
|
||||
"Per-source-configuration": {
|
||||
"title": "🎛️ Per-Source Configuration",
|
||||
"href": "/Sources/Per-source-configuration"
|
||||
},
|
||||
"GraphRAG": {
|
||||
"title": "🕸️ GraphRAG",
|
||||
"href": "/Sources/GraphRAG"
|
||||
},
|
||||
"Wiki-sources": {
|
||||
"title": "📖 Wiki Sources",
|
||||
"href": "/Sources/Wiki-sources"
|
||||
}
|
||||
}
|
||||
@@ -37,38 +37,82 @@ DocsGPT includes a suite of pre-built tools designed to expand its capabilities
|
||||
description: 'A highly flexible tool that allows DocsGPT to interact with virtually any API without needing to write custom Python code.'
|
||||
},
|
||||
{
|
||||
title: 'Brave Search Tool',
|
||||
title: 'Brave Search',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/brave.py',
|
||||
description: 'Enables DocsGPT to perform real-time web and image searches using the Brave Search API for up-to-date information.'
|
||||
description: 'Enables DocsGPT to perform real-time web and image searches using the Brave Search API. Requires an API key.'
|
||||
},
|
||||
{
|
||||
title: 'Cryptoprice Tool',
|
||||
title: 'DuckDuckGo Search',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/duckduckgo.py',
|
||||
description: 'Performs web and image searches using DuckDuckGo. No API key required.'
|
||||
},
|
||||
{
|
||||
title: 'CryptoPrice',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/cryptoprice.py',
|
||||
description: 'Fetches the current price of specified cryptocurrencies.'
|
||||
description: 'Fetches the current price of specified cryptocurrencies using the CryptoCompare public API.'
|
||||
},
|
||||
{
|
||||
title: 'Ntfy Tool',
|
||||
title: 'Ntfy',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/ntfy.py',
|
||||
description: 'Allows DocsGPT to send push notifications to Ntfy.sh channels, ideal for alerts and updates.'
|
||||
description: 'Allows DocsGPT to send push notifications to ntfy topics on a specified server, ideal for alerts and updates.'
|
||||
},
|
||||
{
|
||||
title: 'PostgreSQL Tool',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/postgres.py',
|
||||
description: 'Provides capabilities to connect to a PostgreSQL database, execute SQL queries, and retrieve schema information.'
|
||||
},
|
||||
{
|
||||
title: 'Read Webpage Tool', // Renamed from Scraper Tool
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/read_webpage.py',
|
||||
description: 'Enables DocsGPT to fetch and extract (scrape) textual content from specified web page URLs.'
|
||||
},
|
||||
{
|
||||
title: 'Telegram Tool',
|
||||
title: 'Telegram Bot',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/telegram.py',
|
||||
description: 'Allows DocsGPT to send messages or images to Telegram chats via a Telegram Bot.'
|
||||
description: 'Allows DocsGPT to send messages or images to Telegram chats via a Telegram Bot. Requires a bot token and chat ID.'
|
||||
},
|
||||
{
|
||||
title: 'PostgreSQL Database',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/postgres.py',
|
||||
description: 'Connects to a PostgreSQL database to execute SQL queries and retrieve schema information.'
|
||||
},
|
||||
{
|
||||
title: 'Read Webpage (browser)',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/read_webpage.py',
|
||||
description: 'Fetches the HTML content of a URL and converts it to Markdown for the agent to read.'
|
||||
},
|
||||
{
|
||||
title: 'Remote Device',
|
||||
link: '/Tools/remote-device',
|
||||
description: 'Runs shell commands on a paired remote machine through the docsgpt-cli host. See the Remote Device guide.'
|
||||
},
|
||||
{
|
||||
title: 'MCP Tool',
|
||||
link: '/Guides/Integrations/mcp-tool-integration',
|
||||
description: 'Connects to remote Model Context Protocol (MCP) servers to access their dynamic tools and resources.'
|
||||
},
|
||||
{
|
||||
title: 'Memory',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/memory.py',
|
||||
description: 'Stores and retrieves information across conversations through a per-user memory file directory.'
|
||||
},
|
||||
{
|
||||
title: 'Notepad',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/notes.py',
|
||||
description: 'A single editable note. Supports viewing, overwriting, and string replacement.'
|
||||
},
|
||||
{
|
||||
title: 'Todo List',
|
||||
link: 'https://github.com/arc53/DocsGPT/blob/main/application/agents/tools/todo_list.py',
|
||||
description: 'Manages todo items — creating, viewing, updating, and deleting todos.'
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
## Default Chat Tools
|
||||
|
||||
In a regular chat (no custom agent), DocsGPT can enable a small set of tools automatically so the assistant is useful out of the box. These are the **default chat tools**, controlled by the `DEFAULT_CHAT_TOOLS` setting:
|
||||
|
||||
```env
|
||||
DEFAULT_CHAT_TOOLS=memory,read_webpage,scheduler
|
||||
```
|
||||
|
||||
- Default tools are config-free and run with synthetic, deterministic tool IDs (no manual setup needed).
|
||||
- Each user can opt out of individual default tools from their settings; the disabled list is stored per user.
|
||||
- Some default tools are excluded from **headless runs** (scheduled tasks and webhook triggers). For example, `scheduler` is skipped in those runs to prevent a scheduled task from chaining new schedules on every fire.
|
||||
|
||||
To change the defaults for the whole instance, set `DEFAULT_CHAT_TOOLS` to a comma-separated list of tool names. See [App Configuration](/Deploying/DocsGPT-Settings) for the full settings reference.
|
||||
|
||||
## Using Tools in DocsGPT (User Perspective)
|
||||
|
||||
Interacting with tools in DocsGPT is designed to be intuitive:
|
||||
|
||||
@@ -4,6 +4,7 @@ export default {
|
||||
"upgrading": "Upgrading",
|
||||
"Deploying": "Deploying",
|
||||
"Models": "Models",
|
||||
"Sources": "Sources",
|
||||
"Tools": "Tools",
|
||||
"Agents": "Agents",
|
||||
"Extensions": "Extensions",
|
||||
|
||||
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 94 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 122.88 122.88"><defs><style>.a{fill:#d53;}.b{fill:#fff;}.c{fill:#ddd;}.d{fill:#fc0;}.e{fill:#6b5;}.f{fill:#4a4;}.g{fill:#148;}</style></defs><title>duckduckgo</title><path class="a" d="M122.88,61.44a61.44,61.44,0,1,0-61.44,61.44,61.44,61.44,0,0,0,61.44-61.44Z"/><path class="b" d="M114.37,61.44a52.92,52.92,0,1,0-15.5,37.43,52.76,52.76,0,0,0,15.5-37.43Zm-13.12-39.8A56.29,56.29,0,1,1,61.44,5.15a56.12,56.12,0,0,1,39.81,16.49Z"/><path class="c" d="M43.24,30.15C26.17,34.13,32.43,58,32.43,58l10.81,52.9,4,1.71-4-82.49Zm-4-10.24H34.7L41,22.19s-6.26,0-6.26,4C48.36,25.6,54.61,29,54.61,29l-15.36-9.1Zm0,0Z"/><path class="b" d="M75.66,115.48S62,93.87,62,79.64c0-26.73,17.63-4,17.63-25S62,28.44,62,28.44c-8.53-10.8-25-8.53-25-8.53l4,2.28s-4,1.13-5.12,2.27,10.81-1.7,15.93,2.85C30.72,29,34.13,46.08,34.13,46.08l11.95,68.27,29.58,1.13Zm0,0Z"/><path class="d" d="M75.66,60.87l21.62-5.69C116.62,58,80.78,68.84,78.51,68.27c-17.07-2.85-12,11.37,8.53,6.82s5.12,11.38-13.65,5.12c-26.74-7.39-12.52-20.48,2.27-19.34Z"/><path class="e" d="M70,105.81l1.14-1.7c12.52,4.55,13.09,6.25,12.52-5.12s0-11.38-13.09-1.71c0-2.84-7.39-1.71-8.53,0-11.95-5.12-13.09-6.83-12.52,1.14,1.14,16.5.57,13.65,11.95,8l8.53-.57Zm0,0Z"/><path class="f" d="M60.87,99.56v6.82c.57,1.14,9.67,1.14,9.67-1.14s-4.55,1.71-7.39.57S62,98.42,62,98.42l-1.14,1.14Zm0,0Z"/><path class="g" d="M48.36,43.24c-2.85-3.42-10.24-.57-8.54,4,.57-2.28,4.55-5.69,8.54-4Zm18.2,0c.57-3.42,6.26-4,8-.57a8,8,0,0,0-8,.57Zm-18.77,9.1a1.14,1.14,0,1,1,0,.57v-.57Zm-4.55,2.27a4,4,0,1,0,0-.57v.57Zm29.58-4a1.14,1.14,0,1,1,0,.57v-.57ZM69.4,52.91a3.42,3.42,0,1,0,0-.57v.57Zm0,0Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="64" height="64" fill="none">
|
||||
<path d="M3.49994 11.7501L11.6717 3.57855C12.7762 2.47398 14.5672 2.47398 15.6717 3.57855C16.7762 4.68312 16.7762 6.47398 15.6717 7.57855M15.6717 7.57855L9.49994 13.7501M15.6717 7.57855C16.7762 6.47398 18.5672 6.47398 19.6717 7.57855C20.7762 8.68312 20.7762 10.474 19.6717 11.5785L12.7072 18.543C12.3167 18.9335 12.3167 19.5667 12.7072 19.9572L13.9999 21.2499" stroke="#e3e3e3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M17.4999 9.74921L11.3282 15.921C10.2237 17.0255 8.43272 17.0255 7.32823 15.921C6.22373 14.8164 6.22373 13.0255 7.32823 11.921L13.4999 5.74939" stroke="#e3e3e3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 805 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3">
|
||||
<path d="M240-80q-33 0-56.5-23.5T160-160v-480q0-33 23.5-56.5T240-720h80v-80q0-17 11.5-28.5T360-840q17 0 28.5 11.5T400-800v80h40v-80q0-17 11.5-28.5T480-840q17 0 28.5 11.5T520-800v80h40v-80q0-17 11.5-28.5T600-840q17 0 28.5 11.5T640-800v80h80q33 0 56.5 23.5T800-640v480q0 33-23.5 56.5T720-80H240Zm0-80h480v-480H240v480Zm120-320v-80h240v80H360Zm0 120v-80h240v80H360Zm0 120v-80h160v80H360ZM240-160v-480 480Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 523 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M320-240h320v-80H320v80Zm0-160h320v-80H320v80ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>
|
||||
|
After Width: | Height: | Size: 334 B |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="64" height="64" fill="none">
|
||||
<rect x="2.5" y="4" width="19" height="13" rx="2" stroke="#e3e3e3" stroke-width="1.5"/>
|
||||
<path d="M8 21h8" stroke="#e3e3e3" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M12 17v4" stroke="#e3e3e3" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M6.5 9l2.5 2-2.5 2" stroke="#e3e3e3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11 13h5" stroke="#e3e3e3" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 564 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h480q33 0 56.5 23.5T800-800v640q0 33-23.5 56.5T720-80H240Zm0-80h480v-640H240v640Zm88-104 56-56-56-56-56 56 56 56Zm0-160 56-56-56-56-56 56 56 56Zm0-160 56-56-56-56-56 56 56 56Zm120 280h232v-80H448v80Zm0-160h232v-80H448v80Zm0-160h232v-80H448v80ZM240-160v-640 640Z"/></svg>
|
||||
|
After Width: | Height: | Size: 446 B |