@red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +607 -0
- package/README.md +400 -0
- package/app-config.yaml +25 -0
- package/config.d.ts +142 -0
- package/dist/database/migration.cjs.js +19 -0
- package/dist/database/migration.cjs.js.map +1 -0
- package/dist/index.cjs.js +12 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/plugin.cjs.js +95 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/service/constant.cjs.js +107 -0
- package/dist/service/constant.cjs.js.map +1 -0
- package/dist/service/mcp-server-store.cjs.js +107 -0
- package/dist/service/mcp-server-store.cjs.js.map +1 -0
- package/dist/service/mcp-server-validator.cjs.js +215 -0
- package/dist/service/mcp-server-validator.cjs.js.map +1 -0
- package/dist/service/middleware/createPermissionMiddleware.cjs.js +24 -0
- package/dist/service/middleware/createPermissionMiddleware.cjs.js.map +1 -0
- package/dist/service/middleware/createRateLimitMiddleware.cjs.js +52 -0
- package/dist/service/middleware/createRateLimitMiddleware.cjs.js.map +1 -0
- package/dist/service/middleware/getIdentity.cjs.js +39 -0
- package/dist/service/middleware/getIdentity.cjs.js.map +1 -0
- package/dist/service/notebooks/VectorStoresOperator.cjs.js +347 -0
- package/dist/service/notebooks/VectorStoresOperator.cjs.js.map +1 -0
- package/dist/service/notebooks/documents/documentHelpers.cjs.js +36 -0
- package/dist/service/notebooks/documents/documentHelpers.cjs.js.map +1 -0
- package/dist/service/notebooks/documents/documentService.cjs.js +189 -0
- package/dist/service/notebooks/documents/documentService.cjs.js.map +1 -0
- package/dist/service/notebooks/documents/fileParser.cjs.js +139 -0
- package/dist/service/notebooks/documents/fileParser.cjs.js.map +1 -0
- package/dist/service/notebooks/notebooksRouters.cjs.js +477 -0
- package/dist/service/notebooks/notebooksRouters.cjs.js.map +1 -0
- package/dist/service/notebooks/sessions/sessionService.cjs.js +226 -0
- package/dist/service/notebooks/sessions/sessionService.cjs.js.map +1 -0
- package/dist/service/notebooks/types/notebooksTypes.cjs.js +40 -0
- package/dist/service/notebooks/types/notebooksTypes.cjs.js.map +1 -0
- package/dist/service/notebooks/utils.cjs.js +70 -0
- package/dist/service/notebooks/utils.cjs.js.map +1 -0
- package/dist/service/permission.cjs.js +26 -0
- package/dist/service/permission.cjs.js.map +1 -0
- package/dist/service/router.cjs.js +638 -0
- package/dist/service/router.cjs.js.map +1 -0
- package/dist/service/token-encryption.cjs.js +101 -0
- package/dist/service/token-encryption.cjs.js.map +1 -0
- package/dist/service/utils.cjs.js +40 -0
- package/dist/service/utils.cjs.js.map +1 -0
- package/dist/service/validation.cjs.js +45 -0
- package/dist/service/validation.cjs.js.map +1 -0
- package/migrations/20260302120000_add_mcp_servers.js +41 -0
- package/package.json +109 -0
package/README.md
ADDED
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# Intelligent Assistant Backend
|
|
2
|
+
|
|
3
|
+
This is the intelligent-assistant backend plugin that enables you to interact with any LLM server running a model with OpenAI's API compatibility.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
### Installing the plugin
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
yarn add --cwd packages/backend @red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Configuring the Backend
|
|
14
|
+
|
|
15
|
+
Add the following to your `packages/backend/src/index.ts` file:
|
|
16
|
+
|
|
17
|
+
```ts title="packages/backend/src/index.ts"
|
|
18
|
+
const backend = createBackend();
|
|
19
|
+
|
|
20
|
+
// Add the following line
|
|
21
|
+
backend.add(
|
|
22
|
+
import('@red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend'),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
backend.start();
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Migration from `lightspeed` to `intelligent-assistant`
|
|
29
|
+
|
|
30
|
+
If you are upgrading from a previous version, follow the steps below.
|
|
31
|
+
|
|
32
|
+
#### 1. npm packages
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Remove old packages
|
|
36
|
+
yarn remove @red-hat-developer-hub/backstage-plugin-lightspeed
|
|
37
|
+
yarn remove @red-hat-developer-hub/backstage-plugin-lightspeed-backend
|
|
38
|
+
yarn remove @red-hat-developer-hub/backstage-plugin-lightspeed-common
|
|
39
|
+
|
|
40
|
+
# Install new packages
|
|
41
|
+
yarn add @red-hat-developer-hub/backstage-plugin-intelligent-assistant
|
|
42
|
+
yarn add @red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend
|
|
43
|
+
yarn add @red-hat-developer-hub/backstage-plugin-intelligent-assistant-common
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### 2. Backend plugin import
|
|
47
|
+
|
|
48
|
+
Update `packages/backend/src/index.ts`:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// Before
|
|
52
|
+
backend.add(
|
|
53
|
+
import('@red-hat-developer-hub/backstage-plugin-lightspeed-backend'),
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// After
|
|
57
|
+
backend.add(
|
|
58
|
+
import('@red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend'),
|
|
59
|
+
);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### 3. `app-config.yaml` namespace
|
|
63
|
+
|
|
64
|
+
Rename the top-level configuration key:
|
|
65
|
+
|
|
66
|
+
```yaml
|
|
67
|
+
# Before
|
|
68
|
+
lightspeed:
|
|
69
|
+
notebooks:
|
|
70
|
+
enabled: true
|
|
71
|
+
|
|
72
|
+
# After
|
|
73
|
+
intelligent-assistant:
|
|
74
|
+
notebooks:
|
|
75
|
+
enabled: true
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
All nested keys (`servicePort`, `systemPrompt`, `prompts`, `mcpServers`, `notebooks`, etc.) remain the same.
|
|
79
|
+
|
|
80
|
+
#### 4. RBAC policy names
|
|
81
|
+
|
|
82
|
+
Update permission names in your `rbac-policy.csv`:
|
|
83
|
+
|
|
84
|
+
| Before | After |
|
|
85
|
+
| -------------------------- | ------------------------------------- |
|
|
86
|
+
| `lightspeed.chat.read` | `intelligent-assistant.chat.read` |
|
|
87
|
+
| `lightspeed.chat.create` | `intelligent-assistant.chat.create` |
|
|
88
|
+
| `lightspeed.chat.delete` | `intelligent-assistant.chat.delete` |
|
|
89
|
+
| `lightspeed.chat.update` | `intelligent-assistant.chat.update` |
|
|
90
|
+
| `lightspeed.notebooks.use` | `intelligent-assistant.notebooks.use` |
|
|
91
|
+
| `lightspeed.mcp.read` | `intelligent-assistant.mcp.read` |
|
|
92
|
+
| `lightspeed.mcp.manage` | `intelligent-assistant.mcp.manage` |
|
|
93
|
+
|
|
94
|
+
#### 5. OFS dynamic plugin configuration
|
|
95
|
+
|
|
96
|
+
The top-level plugin key, route path, and drawer `config.id` change. `importName` values are **unchanged**:
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
# Before
|
|
100
|
+
dynamicPlugins:
|
|
101
|
+
frontend:
|
|
102
|
+
red-hat-developer-hub.backstage-plugin-lightspeed:
|
|
103
|
+
dynamicRoutes:
|
|
104
|
+
- path: /lightspeed
|
|
105
|
+
importName: LightspeedPage
|
|
106
|
+
module: Legacy
|
|
107
|
+
mountPoints:
|
|
108
|
+
- mountPoint: application/internal/drawer-content
|
|
109
|
+
importName: LightspeedChatContainer
|
|
110
|
+
module: Legacy
|
|
111
|
+
config:
|
|
112
|
+
id: lightspeed
|
|
113
|
+
|
|
114
|
+
# After
|
|
115
|
+
dynamicPlugins:
|
|
116
|
+
frontend:
|
|
117
|
+
red-hat-developer-hub.backstage-plugin-intelligent-assistant:
|
|
118
|
+
dynamicRoutes:
|
|
119
|
+
- path: /intelligent-assistant
|
|
120
|
+
importName: LightspeedPage # unchanged
|
|
121
|
+
module: Legacy
|
|
122
|
+
mountPoints:
|
|
123
|
+
- mountPoint: application/internal/drawer-content
|
|
124
|
+
importName: LightspeedChatContainer # unchanged
|
|
125
|
+
module: Legacy
|
|
126
|
+
config:
|
|
127
|
+
id: intelligent-assistant
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### 6. NFS extension configuration
|
|
131
|
+
|
|
132
|
+
Update extension names in `app-config.yaml`:
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
# Before
|
|
136
|
+
app:
|
|
137
|
+
extensions:
|
|
138
|
+
- app-root-wrapper:app/lightspeed-fab
|
|
139
|
+
- app-drawer-content:lightspeed/lightspeed
|
|
140
|
+
- translation:app/lightspeed-translations
|
|
141
|
+
|
|
142
|
+
# After
|
|
143
|
+
app:
|
|
144
|
+
extensions:
|
|
145
|
+
- app-root-wrapper:app/intelligent-assistant-fab
|
|
146
|
+
- app-drawer-content:intelligent-assistant/intelligent-assistant
|
|
147
|
+
- translation:app/intelligent-assistant-translations
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### 7. NFS module imports
|
|
151
|
+
|
|
152
|
+
For non-dynamic-plugin NFS consumers, update module imports:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// Before
|
|
156
|
+
|
|
157
|
+
// After
|
|
158
|
+
import {
|
|
159
|
+
intelligentAssistantFABModule,
|
|
160
|
+
intelligentAssistantRedirectModule,
|
|
161
|
+
intelligentAssistantTranslationsModule,
|
|
162
|
+
} from '@red-hat-developer-hub/backstage-plugin-intelligent-assistant';
|
|
163
|
+
import {
|
|
164
|
+
lightspeedFABModule,
|
|
165
|
+
lightspeedRedirectModule,
|
|
166
|
+
lightspeedTranslationsModule,
|
|
167
|
+
} from '@red-hat-developer-hub/backstage-plugin-lightspeed';
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### 8. Scalprum `exposedModules` keys
|
|
171
|
+
|
|
172
|
+
For OFS deployments referencing NFS modules:
|
|
173
|
+
|
|
174
|
+
```yaml
|
|
175
|
+
# Before
|
|
176
|
+
module: LightspeedFABModule
|
|
177
|
+
module: LightspeedTranslationsModule
|
|
178
|
+
|
|
179
|
+
# After
|
|
180
|
+
module: IntelligentAssistantFABModule
|
|
181
|
+
module: IntelligentAssistantTranslationsModule
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
> **Warning**: The old `lightspeed:` config key and `lightspeed.*` permission names are no longer recognized. Existing deployments that do not update will silently lose functionality.
|
|
185
|
+
|
|
186
|
+
### Plugin Configurations
|
|
187
|
+
|
|
188
|
+
Add the following intelligent-assistant configurations into your `app-config.yaml` file:
|
|
189
|
+
|
|
190
|
+
```yaml
|
|
191
|
+
intelligent-assistant:
|
|
192
|
+
servicePort: <portNumber> # Optional - Change the LS service port number. Defaults to 8080.
|
|
193
|
+
systemPrompt: <system prompt> # Optional - Override the default system prompt.
|
|
194
|
+
prompts: # Optional - Custom prompts displayed to users in the chat UI
|
|
195
|
+
- title: <prompt_title>
|
|
196
|
+
message: <prompt_message>
|
|
197
|
+
mcpServers: # Optional - one or more MCP servers
|
|
198
|
+
- name: <mcp server name> # must match the name configured in LCS
|
|
199
|
+
token: ${MCP_TOKEN}
|
|
200
|
+
rateLimit: # Optional - per-user request rate limits (defaults apply if omitted)
|
|
201
|
+
expensive:
|
|
202
|
+
max: 25 # Max requests per minute per user for expensive endpoints (default: 25). Set to 0 to disable.
|
|
203
|
+
general:
|
|
204
|
+
max: 200 # Max requests per minute per user for other authenticated endpoints (default: 200). Set to 0 to disable.
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Rate limiting
|
|
208
|
+
|
|
209
|
+
The backend applies per-user rate limits to authenticated endpoints as an abuse
|
|
210
|
+
prevention measure. Limits are keyed by the authenticated user's entity ref and
|
|
211
|
+
use a fixed 1-minute window.
|
|
212
|
+
|
|
213
|
+
**Tiers**:
|
|
214
|
+
|
|
215
|
+
- **Expensive** (default: 25 requests/minute per user): `POST /v1/query`, and
|
|
216
|
+
(when Notebooks is enabled) notebook document uploads and RAG queries.
|
|
217
|
+
- **General** (default: 200 requests/minute per user): all other authenticated
|
|
218
|
+
endpoints, including conversation listing, MCP server management, feedback,
|
|
219
|
+
and notebook session CRUD.
|
|
220
|
+
- **Excluded**: `/health` and `/notebooks/health` are not rate limited.
|
|
221
|
+
|
|
222
|
+
When a limit is exceeded, the API returns `429 Too Many Requests` with a
|
|
223
|
+
`Retry-After` header and a JSON error body (`RateLimitExceeded`).
|
|
224
|
+
|
|
225
|
+
Set `max: 0` on a tier to disable rate limiting for that tier. If the entire
|
|
226
|
+
`rateLimit` block is omitted, the defaults above apply.
|
|
227
|
+
|
|
228
|
+
**Example** — tighter limits for a small deployment:
|
|
229
|
+
|
|
230
|
+
```yaml
|
|
231
|
+
intelligent-assistant:
|
|
232
|
+
rateLimit:
|
|
233
|
+
expensive:
|
|
234
|
+
max: 10
|
|
235
|
+
general:
|
|
236
|
+
max: 100
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
#### MCP servers settings endpoints
|
|
240
|
+
|
|
241
|
+
The backend exposes MCP server management endpoints used by the Intelligent Assistant UI
|
|
242
|
+
settings panel:
|
|
243
|
+
|
|
244
|
+
- `GET /api/intelligent-assistant/mcp-servers` lists configured servers and user-scoped
|
|
245
|
+
state.
|
|
246
|
+
- `PATCH /api/intelligent-assistant/mcp-servers/:name` updates user settings such as
|
|
247
|
+
enabled state and token.
|
|
248
|
+
|
|
249
|
+
- `POST /api/intelligent-assistant/mcp-servers/validate` validates a raw `{ url, token }`
|
|
250
|
+
pair and returns whether credentials are valid.
|
|
251
|
+
- `POST /api/intelligent-assistant/mcp-servers/:name/validate` validates a configured server
|
|
252
|
+
by name using the effective token (user token override or configured token).
|
|
253
|
+
|
|
254
|
+
These endpoints power server selection and token configuration, including inline
|
|
255
|
+
success/error feedback while users enter tokens.
|
|
256
|
+
|
|
257
|
+
#### Permission Framework Support
|
|
258
|
+
|
|
259
|
+
The Intelligent Assistant Backend plugin has support for the permission framework.
|
|
260
|
+
|
|
261
|
+
- When [RBAC permission](https://github.com/backstage/community-plugins/tree/main/workspaces/rbac/plugins/rbac-backend#installation) framework is enabled, for non-admin users to access intelligent-assistant backend API, the role associated with your user should have the following permission policies associated with it. Add the following in your permission policies configuration file named `rbac-policy.csv`:
|
|
262
|
+
|
|
263
|
+
```CSV
|
|
264
|
+
p, role:default/team_a, intelligent-assistant.chat.read, read, allow
|
|
265
|
+
p, role:default/team_a, intelligent-assistant.chat.create, create, allow
|
|
266
|
+
p, role:default/team_a, intelligent-assistant.chat.delete, delete, allow
|
|
267
|
+
p, role:default/team_a, intelligent-assistant.chat.update, update, allow
|
|
268
|
+
|
|
269
|
+
# Required for Notebooks feature (if enabled)
|
|
270
|
+
p, role:default/team_a, intelligent-assistant.notebooks.use, update, allow
|
|
271
|
+
|
|
272
|
+
# Required for MCP server management (if configured)
|
|
273
|
+
p, role:default/team_a, intelligent-assistant.mcp.read, read, allow
|
|
274
|
+
p, role:default/team_a, intelligent-assistant.mcp.manage, update, allow
|
|
275
|
+
|
|
276
|
+
g, user:default/<your-user-name>, role:default/team_a
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
You can specify the path to this configuration file in your application configuration:
|
|
281
|
+
|
|
282
|
+
```yaml
|
|
283
|
+
permission:
|
|
284
|
+
enabled: true
|
|
285
|
+
rbac:
|
|
286
|
+
policies-csv-file: /some/path/rbac-policy.csv
|
|
287
|
+
policyFileReload: true
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Notebooks (Developer Preview)
|
|
291
|
+
|
|
292
|
+
Notebooks is an experimental feature that enables document-based conversations with Retrieval-Augmented Generation (RAG).
|
|
293
|
+
|
|
294
|
+
For user-facing feature documentation, see the [Intelligent Assistant Frontend README](../intelligent-assistant/README.md#notebooks-developer-preview).
|
|
295
|
+
|
|
296
|
+
#### Prerequisites
|
|
297
|
+
|
|
298
|
+
Notebooks requires:
|
|
299
|
+
|
|
300
|
+
- **Lightspeed Core service** to be running (provides the backend API proxy)
|
|
301
|
+
- **Llama Stack service** to be accessible from Lightspeed Core (provides vector database, embeddings, and RAG capabilities)
|
|
302
|
+
|
|
303
|
+
For Llama Stack setup and configuration, refer to the [Llama Stack documentation](https://github.com/llamastack/llama-stack).
|
|
304
|
+
|
|
305
|
+
#### Configuration
|
|
306
|
+
|
|
307
|
+
To enable Notebooks, add the following configuration to your `app-config.yaml`:
|
|
308
|
+
|
|
309
|
+
```yaml
|
|
310
|
+
intelligent-assistant:
|
|
311
|
+
servicePort: 8080 # Optional: Lightspeed Core service port (default: 8080)
|
|
312
|
+
|
|
313
|
+
notebooks:
|
|
314
|
+
enabled: false # Enable Notebooks feature (default: false)
|
|
315
|
+
|
|
316
|
+
# Required: Query defaults for RAG queries
|
|
317
|
+
# Both model and provider_id must be configured together
|
|
318
|
+
queryDefaults:
|
|
319
|
+
model: ${NOTEBOOKS_QUERY_MODEL} # Model to use for answering queries. Must map to a model available through the provider set in $NOTEBOOKS_QUERY_PROVIDER_ID
|
|
320
|
+
provider_id: ${NOTEBOOKS_QUERY_PROVIDER_ID} # AI provider for the query model. Must map to a provider enabled in your Lightspeed config.yaml
|
|
321
|
+
|
|
322
|
+
# Optional: Chunking strategy for document processing
|
|
323
|
+
chunkingStrategy:
|
|
324
|
+
type: auto # 'auto' or 'static' (default: auto)
|
|
325
|
+
# For 'static' chunking:
|
|
326
|
+
maxChunkSizeTokens: 512 # Maximum tokens per chunk (default: 512)
|
|
327
|
+
chunkOverlapTokens: 50 # Overlap between chunks (default: 50)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Configuration Options**:
|
|
331
|
+
|
|
332
|
+
**Core Settings**:
|
|
333
|
+
|
|
334
|
+
- **`intelligent-assistant.servicePort`** _(optional)_: Port where Lightspeed Core service is running (default: `8080`). The backend connects to Lightspeed Core at `http://{DEFAULT_LIGHTSPEED_SERVICE_HOST}:{servicePort}` to proxy vector store operations. The host is defined by the `DEFAULT_LIGHTSPEED_SERVICE_HOST` constant in the source.
|
|
335
|
+
|
|
336
|
+
**Notebooks Settings**:
|
|
337
|
+
|
|
338
|
+
- **`notebooks.enabled`** _(optional)_: Enable or disable the Notebooks feature (default: `false`)
|
|
339
|
+
|
|
340
|
+
**Query Defaults** _(required when enabled)_:
|
|
341
|
+
|
|
342
|
+
- **`queryDefaults.model`** _(required)_: The LLM model to use for answering RAG queries. Must be available in the configured provider.
|
|
343
|
+
- **`queryDefaults.provider_id`** _(required)_: The AI provider identifier for the query model (e.g., `ollama`, `vllm`). Both `model` and `provider_id` must be configured together.
|
|
344
|
+
|
|
345
|
+
> **Important**: The `model` and `provider_id` values must map to a provider and model that are actually enabled in your Lightspeed config.yaml configuration. If the provider or model is not available in Lightspeed, queries will fail. For example, if `openai` enabled in Lightspeed via ENABLE_OPENAI, then model must be available, e.g (model=gpt-4o-mini).
|
|
346
|
+
|
|
347
|
+
**Chunking Strategy** _(optional)_:
|
|
348
|
+
|
|
349
|
+
- **`chunkingStrategy.type`** _(optional)_: Document chunking strategy - `auto` (automatic, default) or `static` (fixed size)
|
|
350
|
+
- **`chunkingStrategy.maxChunkSizeTokens`** _(optional)_: Maximum chunk size in tokens for static chunking (default: `512`)
|
|
351
|
+
- **`chunkingStrategy.chunkOverlapTokens`** _(optional)_: Token overlap between chunks for static chunking (default: `50`)
|
|
352
|
+
|
|
353
|
+
**Where to Find These Values**:
|
|
354
|
+
|
|
355
|
+
- **Provider IDs**: Check your Llama Stack configuration file for configured providers (both for models and vector stores)
|
|
356
|
+
- **Model names**: Available models are listed in your Llama Stack provider configuration
|
|
357
|
+
- **Embedding dimensions**: Refer to the embedding model's documentation (e.g., `all-mpnet-base-v2` outputs 768 dimensions)
|
|
358
|
+
- **Lightspeed Core port**: Check your Lightspeed Core service deployment configuration
|
|
359
|
+
|
|
360
|
+
#### API Endpoints
|
|
361
|
+
|
|
362
|
+
When enabled, Notebooks exposes the following REST API endpoints:
|
|
363
|
+
|
|
364
|
+
- **Health Check**:
|
|
365
|
+
- `GET /intelligent-assistant/notebooks/health` - Health check endpoint
|
|
366
|
+
|
|
367
|
+
- **Sessions**:
|
|
368
|
+
- `POST /intelligent-assistant/notebooks/v1/sessions` - Create a new session
|
|
369
|
+
- `GET /intelligent-assistant/notebooks/v1/sessions` - List all sessions for the current user
|
|
370
|
+
- `GET /intelligent-assistant/notebooks/v1/sessions/:sessionId` - Get a specific session given the sessionID
|
|
371
|
+
- `PUT /intelligent-assistant/notebooks/v1/sessions/:sessionId` - Update session details
|
|
372
|
+
- `DELETE /intelligent-assistant/notebooks/v1/sessions/:sessionId` - Delete session
|
|
373
|
+
|
|
374
|
+
- **Documents**:
|
|
375
|
+
- `PUT /intelligent-assistant/notebooks/v1/sessions/:sessionId/documents` - Upload or update a document (multipart/form-data)
|
|
376
|
+
- `GET /intelligent-assistant/notebooks/v1/sessions/:sessionId/documents` - List all documents in a session
|
|
377
|
+
- `GET /intelligent-assistant/notebooks/v1/sessions/:sessionId/documents/:documentId/status` - Get document processing status
|
|
378
|
+
- `DELETE /intelligent-assistant/notebooks/v1/sessions/:sessionId/documents/:documentId` - Delete a document
|
|
379
|
+
|
|
380
|
+
- **Queries**:
|
|
381
|
+
- `POST /intelligent-assistant/notebooks/v1/sessions/:sessionId/query` - Query documents with RAG
|
|
382
|
+
|
|
383
|
+
**Notes**:
|
|
384
|
+
|
|
385
|
+
- All endpoints require authentication (user context is automatically provided by Backstage)
|
|
386
|
+
- All `/v1/*` endpoints require the `intelligent-assistant.notebooks.use` permission
|
|
387
|
+
- Document endpoints verify session ownership before allowing operations
|
|
388
|
+
- `documentId` in paths is the document title (URL-encoded for special characters)
|
|
389
|
+
|
|
390
|
+
#### Permission Framework Support for Notebooks
|
|
391
|
+
|
|
392
|
+
When RBAC is enabled, users need the following permission to use Notebooks:
|
|
393
|
+
|
|
394
|
+
```CSV
|
|
395
|
+
p, role:default/team_a, intelligent-assistant.notebooks.use, update, allow
|
|
396
|
+
|
|
397
|
+
g, user:default/<your-user-name>, role:default/team_a
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Add this to your `rbac-policy.csv` file along with the existing intelligent-assistant permissions.
|
package/app-config.yaml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# OPTIONAL: Backend-only configurations
|
|
2
|
+
# intelligent-assistant:
|
|
3
|
+
# servicePort: 8080 # OPTIONAL: Port for lightspeed-core service (default: 8080)
|
|
4
|
+
# systemPrompt: <custom_system_prompt> # OPTIONAL: Override default RHDH system prompt
|
|
5
|
+
# # Optional: Per-user request rate limits (defaults apply if omitted)
|
|
6
|
+
# rateLimit:
|
|
7
|
+
# expensive:
|
|
8
|
+
# max: 10
|
|
9
|
+
# general:
|
|
10
|
+
# max: 100
|
|
11
|
+
# # AI Notebooks (Developer Preview) - Disabled by default
|
|
12
|
+
# notebooks:
|
|
13
|
+
# enabled: false # Set to true to enable AI Notebooks feature
|
|
14
|
+
|
|
15
|
+
# # REQUIRED when enabled: Query defaults for RAG queries
|
|
16
|
+
# # Both model and provider_id must be configured together
|
|
17
|
+
# queryDefaults:
|
|
18
|
+
# provider_id: ollama # AI provider for query model (e.g., ollama, vllm)
|
|
19
|
+
# model: llama3.1-8b-instruct # Model to use for answering queries
|
|
20
|
+
|
|
21
|
+
# # OPTIONAL: Chunking strategy for document processing
|
|
22
|
+
# chunkingStrategy:
|
|
23
|
+
# type: auto # 'auto' (default) or 'static'
|
|
24
|
+
# maxChunkSizeTokens: 512 # Max tokens per chunk for 'static' mode (default: 512)
|
|
25
|
+
# chunkOverlapTokens: 50 # Overlap between chunks for 'static' mode (default: 50)
|
package/config.d.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Red Hat, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export interface Config {
|
|
18
|
+
/**
|
|
19
|
+
* Configuration required for using intelligent-assistant
|
|
20
|
+
* @visibility frontend
|
|
21
|
+
*/
|
|
22
|
+
'intelligent-assistant'?: {
|
|
23
|
+
/**
|
|
24
|
+
* configure the port number for the lightspeed service.
|
|
25
|
+
* @visibility backend
|
|
26
|
+
*/
|
|
27
|
+
servicePort?: number;
|
|
28
|
+
/**
|
|
29
|
+
* customize system prompt for the lightspeed service.
|
|
30
|
+
* @visibility backend
|
|
31
|
+
*/
|
|
32
|
+
systemPrompt?: string;
|
|
33
|
+
/**
|
|
34
|
+
* configure the MCP server for the lightspeed service.
|
|
35
|
+
* @visibility backend
|
|
36
|
+
*/
|
|
37
|
+
mcpServers?: Array<{
|
|
38
|
+
/**
|
|
39
|
+
* The name of the MCP server. Must match the name registered in LCS config.
|
|
40
|
+
* The URL is fetched from LCS (GET /v1/mcp-servers) at startup.
|
|
41
|
+
* @visibility backend
|
|
42
|
+
*/
|
|
43
|
+
name: string;
|
|
44
|
+
/**
|
|
45
|
+
* The default access token for authenticating with this MCP server.
|
|
46
|
+
* Optional — if omitted, users must provide their own token via the UI.
|
|
47
|
+
* Users can also override this with a personal token via PATCH /mcp-servers/:name.
|
|
48
|
+
* @visibility secret
|
|
49
|
+
*/
|
|
50
|
+
token?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Authentication mode for this MCP server.
|
|
53
|
+
* Set to 'dcr' for Dynamic Client Registration (user-bound tokens minted per-request).
|
|
54
|
+
* When omitted, falls back to static-token mode.
|
|
55
|
+
* @visibility frontend
|
|
56
|
+
*/
|
|
57
|
+
auth?: 'dcr';
|
|
58
|
+
}>;
|
|
59
|
+
/**
|
|
60
|
+
* Per-user rate limiting for Lightspeed API endpoints.
|
|
61
|
+
* @visibility backend
|
|
62
|
+
*/
|
|
63
|
+
rateLimit?: {
|
|
64
|
+
/**
|
|
65
|
+
* Limits for expensive endpoints (LLM queries, document uploads).
|
|
66
|
+
* @visibility backend
|
|
67
|
+
*/
|
|
68
|
+
expensive?: {
|
|
69
|
+
/**
|
|
70
|
+
* Maximum requests per minute per user.
|
|
71
|
+
* Set to 0 to disable rate limiting for this tier.
|
|
72
|
+
* @default 25
|
|
73
|
+
* @visibility backend
|
|
74
|
+
*/
|
|
75
|
+
max?: number;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Limits for all other authenticated endpoints.
|
|
79
|
+
* @visibility backend
|
|
80
|
+
*/
|
|
81
|
+
general?: {
|
|
82
|
+
/**
|
|
83
|
+
* Maximum requests per minute per user.
|
|
84
|
+
* Set to 0 to disable rate limiting for this tier.
|
|
85
|
+
* @default 200
|
|
86
|
+
* @visibility backend
|
|
87
|
+
*/
|
|
88
|
+
max?: number;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Configuration for AI Notebooks (Developer Preview)
|
|
93
|
+
*/
|
|
94
|
+
notebooks?: {
|
|
95
|
+
/**
|
|
96
|
+
* Enable/disable AI Notebooks feature
|
|
97
|
+
* When enabled, exposes AI Notebooks REST API endpoints for document-based conversations with RAG.
|
|
98
|
+
* Requires Lightspeed service to be running (host and port default to 127.0.0.1 and 8080).
|
|
99
|
+
* @default false
|
|
100
|
+
* @visibility frontend
|
|
101
|
+
*/
|
|
102
|
+
enabled: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Lightspeed configuration
|
|
105
|
+
* @visibility backend
|
|
106
|
+
*/
|
|
107
|
+
queryDefaults: {
|
|
108
|
+
/**
|
|
109
|
+
* Model to use for answering queries. Must map to a model available through the provider set in provider_id.
|
|
110
|
+
* @visibility backend
|
|
111
|
+
*/
|
|
112
|
+
model: string;
|
|
113
|
+
/**
|
|
114
|
+
* AI provider for the query model. Must map to a provider enabled in your Lightspeed config.
|
|
115
|
+
* @visibility backend
|
|
116
|
+
*/
|
|
117
|
+
provider_id: string;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Chunking strategy for document processing
|
|
121
|
+
* @visibility backend
|
|
122
|
+
*/
|
|
123
|
+
chunkingStrategy?: {
|
|
124
|
+
/**
|
|
125
|
+
* Document chunking strategy - 'auto' (automatic, default) or 'static' (fixed size)
|
|
126
|
+
* @visibility backend
|
|
127
|
+
*/
|
|
128
|
+
type?: 'auto' | 'static';
|
|
129
|
+
/**
|
|
130
|
+
* Maximum chunk size in tokens for static chunking (default: 512)
|
|
131
|
+
* @visibility backend
|
|
132
|
+
*/
|
|
133
|
+
maxChunkSizeTokens?: number;
|
|
134
|
+
/**
|
|
135
|
+
* Token overlap between chunks for static chunking (default: 50)
|
|
136
|
+
* @visibility backend
|
|
137
|
+
*/
|
|
138
|
+
chunkOverlapTokens?: number;
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
|
|
5
|
+
const migrationsDir = backendPluginApi.resolvePackagePath(
|
|
6
|
+
"@red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend",
|
|
7
|
+
"migrations"
|
|
8
|
+
);
|
|
9
|
+
async function migrate(databaseManager) {
|
|
10
|
+
const knex = await databaseManager.getClient();
|
|
11
|
+
if (!databaseManager.migrations?.skip) {
|
|
12
|
+
await knex.migrate.latest({
|
|
13
|
+
directory: migrationsDir
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
exports.migrate = migrate;
|
|
19
|
+
//# sourceMappingURL=migration.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.cjs.js","sources":["../../src/database/migration.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n DatabaseService,\n resolvePackagePath,\n} from '@backstage/backend-plugin-api';\n\nconst migrationsDir = resolvePackagePath(\n '@red-hat-developer-hub/backstage-plugin-intelligent-assistant-backend',\n 'migrations',\n);\n\nexport async function migrate(databaseManager: DatabaseService) {\n const knex = await databaseManager.getClient();\n\n if (!databaseManager.migrations?.skip) {\n await knex.migrate.latest({\n directory: migrationsDir,\n });\n }\n}\n"],"names":["resolvePackagePath"],"mappings":";;;;AAqBA,MAAM,aAAA,GAAgBA,mCAAA;AAAA,EACpB,uEAAA;AAAA,EACA;AACF,CAAA;AAEA,eAAsB,QAAQ,eAAA,EAAkC;AAC9D,EAAA,MAAM,IAAA,GAAO,MAAM,eAAA,CAAgB,SAAA,EAAU;AAE7C,EAAA,IAAI,CAAC,eAAA,CAAgB,UAAA,EAAY,IAAA,EAAM;AACrC,IAAA,MAAM,IAAA,CAAK,QAAQ,MAAA,CAAO;AAAA,MACxB,SAAA,EAAW;AAAA,KACZ,CAAA;AAAA,EACH;AACF;;;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var plugin = require('./plugin.cjs.js');
|
|
6
|
+
var router = require('./service/router.cjs.js');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
exports.default = plugin.intelligentAssistantPlugin;
|
|
11
|
+
exports.createRouter = router.createRouter;
|
|
12
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
2
|
+
import { LoggerService, DatabaseService, HttpAuthService, UserInfoService, PermissionsService, AuthService } from '@backstage/backend-plugin-api';
|
|
3
|
+
import express from 'express';
|
|
4
|
+
import { Config } from '@backstage/config';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
* The lightspeed backend plugin.
|
|
9
|
+
*/
|
|
10
|
+
declare const intelligentAssistantPlugin: _backstage_backend_plugin_api.BackendFeature;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @public
|
|
14
|
+
* The lightspeed backend router options
|
|
15
|
+
*/
|
|
16
|
+
type RouterOptions = {
|
|
17
|
+
logger: LoggerService;
|
|
18
|
+
config: Config;
|
|
19
|
+
database: DatabaseService;
|
|
20
|
+
httpAuth: HttpAuthService;
|
|
21
|
+
userInfo: UserInfoService;
|
|
22
|
+
permissions: PermissionsService;
|
|
23
|
+
auth: AuthService;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @public
|
|
28
|
+
* The lightspeed backend router
|
|
29
|
+
*/
|
|
30
|
+
declare function createRouter(options: RouterOptions): Promise<express.Router>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
type McpServerStatus = 'connected' | 'error' | 'unknown';
|
|
36
|
+
/**
|
|
37
|
+
* Authentication mode for MCP servers.
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
type McpServerAuth = 'dcr';
|
|
41
|
+
/**
|
|
42
|
+
* Public-facing response for an MCP server with user settings merged.
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
interface McpServerResponse {
|
|
46
|
+
name: string;
|
|
47
|
+
url?: string;
|
|
48
|
+
enabled: boolean;
|
|
49
|
+
status: McpServerStatus;
|
|
50
|
+
toolCount: number;
|
|
51
|
+
hasToken: boolean;
|
|
52
|
+
hasUserToken: boolean;
|
|
53
|
+
/** Authentication mode — `'dcr'` means tokens are minted automatically. */
|
|
54
|
+
auth?: McpServerAuth;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
interface McpToolInfo {
|
|
60
|
+
name: string;
|
|
61
|
+
description: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
interface McpValidationResult {
|
|
67
|
+
valid: boolean;
|
|
68
|
+
toolCount: number;
|
|
69
|
+
tools: McpToolInfo[];
|
|
70
|
+
error?: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { type McpServerAuth, type McpServerResponse, type McpServerStatus, type McpToolInfo, type McpValidationResult, type RouterOptions, createRouter, intelligentAssistantPlugin as default };
|