@sweetoburrito/backstage-plugin-ai-assistant-backend 0.10.0 → 0.12.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.
Files changed (32) hide show
  1. package/dist/constants/prompts.cjs.js +12 -6
  2. package/dist/constants/prompts.cjs.js.map +1 -1
  3. package/dist/database/user-settings-store.cjs.js +42 -0
  4. package/dist/database/user-settings-store.cjs.js.map +1 -0
  5. package/dist/plugin.cjs.js +14 -6
  6. package/dist/plugin.cjs.js.map +1 -1
  7. package/dist/services/chat.cjs.js +23 -3
  8. package/dist/services/chat.cjs.js.map +1 -1
  9. package/dist/services/mcp/helpers.cjs.js +31 -0
  10. package/dist/services/mcp/helpers.cjs.js.map +1 -0
  11. package/dist/services/mcp/index.cjs.js +150 -0
  12. package/dist/services/mcp/index.cjs.js.map +1 -0
  13. package/dist/services/router/chat.cjs.js +17 -5
  14. package/dist/services/router/chat.cjs.js.map +1 -1
  15. package/dist/services/router/index.cjs.js +2 -2
  16. package/dist/services/router/index.cjs.js.map +1 -1
  17. package/dist/services/router/settings/index.cjs.js +51 -0
  18. package/dist/services/router/settings/index.cjs.js.map +1 -0
  19. package/dist/services/router/{mcp.cjs.js → settings/mcp.cjs.js} +3 -3
  20. package/dist/services/router/settings/mcp.cjs.js.map +1 -0
  21. package/dist/services/user-settings.cjs.js +34 -0
  22. package/dist/services/user-settings.cjs.js.map +1 -0
  23. package/dist/{services/tools → tools}/searchKnowledge.cjs.js +12 -2
  24. package/dist/tools/searchKnowledge.cjs.js.map +1 -0
  25. package/migrations/20251124_user_settings.js +131 -0
  26. package/package.json +3 -3
  27. package/dist/database/mcp-store.cjs.js +0 -46
  28. package/dist/database/mcp-store.cjs.js.map +0 -1
  29. package/dist/services/mcp.cjs.js +0 -119
  30. package/dist/services/mcp.cjs.js.map +0 -1
  31. package/dist/services/router/mcp.cjs.js.map +0 -1
  32. package/dist/services/tools/searchKnowledge.cjs.js.map +0 -1
@@ -22,21 +22,28 @@ async function createChatRouter(options) {
22
22
  })
23
23
  ),
24
24
  modelId: z__default.default.string(),
25
- conversationId: z__default.default.string().uuid().optional().default(uuid.v4),
26
- stream: z__default.default.boolean().optional()
25
+ conversationId: z__default.default.uuid().optional().default(uuid.v4),
26
+ stream: z__default.default.boolean().optional(),
27
+ tools: z__default.default.array(
28
+ z__default.default.object({
29
+ name: z__default.default.string(),
30
+ provider: z__default.default.string()
31
+ })
32
+ ).optional()
27
33
  });
28
34
  router.post(
29
35
  "/message",
30
36
  validation.validation(messageSchema, "body"),
31
37
  async (req, res) => {
32
- const { messages, conversationId, modelId, stream } = req.body;
38
+ const { messages, conversationId, modelId, stream, tools } = req.body;
33
39
  const userCredentials = await httpAuth.credentials(req);
34
40
  const responseMessages = await chat.prompt({
35
41
  modelId,
36
42
  messages,
37
43
  conversationId,
38
44
  stream,
39
- userCredentials
45
+ userCredentials,
46
+ tools
40
47
  });
41
48
  res.json({
42
49
  messages: responseMessages,
@@ -45,7 +52,7 @@ async function createChatRouter(options) {
45
52
  }
46
53
  );
47
54
  const chatSchema = z__default.default.object({
48
- id: z__default.default.string().uuid()
55
+ id: z__default.default.uuid()
49
56
  });
50
57
  router.get("/conversations", async (req, res) => {
51
58
  const credentials = await httpAuth.credentials(req);
@@ -55,6 +62,11 @@ async function createChatRouter(options) {
55
62
  });
56
63
  res.json({ conversations });
57
64
  });
65
+ router.get("/tools", async (req, res) => {
66
+ const credentials = await httpAuth.credentials(req);
67
+ const tools = await chat.getAvailableTools({ credentials });
68
+ res.json({ tools });
69
+ });
58
70
  router.get("/:id", validation.validation(chatSchema, "params"), async (req, res) => {
59
71
  const { id } = req.params;
60
72
  const credentials = await httpAuth.credentials(req);
@@ -1 +1 @@
1
- {"version":3,"file":"chat.cjs.js","sources":["../../../src/services/router/chat.ts"],"sourcesContent":["import express from 'express';\nimport Router from 'express-promise-router';\nimport { ChatService } from '../chat';\nimport z from 'zod';\nimport { validation } from './middleware/validation';\nimport { v4 as uuid } from 'uuid';\nimport {\n DatabaseService,\n HttpAuthService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\n\nexport type ChatRouterOptions = {\n chat: ChatService;\n database: DatabaseService;\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n};\n\nexport async function createChatRouter(\n options: ChatRouterOptions,\n): Promise<express.Router> {\n const { chat, httpAuth, userInfo } = options;\n\n const router = Router();\n\n const messageSchema = z.object({\n messages: z.array(\n z.object({\n id: z.string().uuid().optional().default(uuid),\n role: z.string(),\n content: z.string(),\n }),\n ),\n modelId: z.string(),\n conversationId: z.string().uuid().optional().default(uuid),\n stream: z.boolean().optional(),\n });\n\n router.post(\n '/message',\n validation(messageSchema, 'body'),\n async (req, res) => {\n const { messages, conversationId, modelId, stream } = req.body;\n\n const userCredentials = await httpAuth.credentials(req);\n\n const responseMessages = await chat.prompt({\n modelId,\n messages,\n conversationId,\n stream,\n userCredentials,\n });\n\n res.json({\n messages: responseMessages,\n conversationId,\n });\n },\n );\n\n const chatSchema = z.object({\n id: z.string().uuid(),\n });\n\n router.get('/conversations', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await userInfo.getUserInfo(credentials);\n\n const conversations = await chat.getConversations({\n userEntityRef,\n });\n\n res.json({ conversations });\n });\n\n router.get('/:id', validation(chatSchema, 'params'), async (req, res) => {\n const { id } = req.params;\n\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await userInfo.getUserInfo(credentials);\n\n const conversation = await chat.getConversation({\n conversationId: id,\n userEntityRef,\n });\n\n res.json({ conversation });\n });\n\n router.post(\n '/message/:messageId/score',\n validation(\n z.object({\n messageId: z.string().uuid(),\n }),\n 'params',\n ),\n validation(\n z.object({\n score: z.number(),\n }),\n 'body',\n ),\n async (req, res) => {\n const { messageId } = req.params;\n const { score } = req.body;\n\n await chat.scoreMessage(messageId, score);\n\n res.status(204).end();\n },\n );\n\n return router;\n}\n"],"names":["Router","z","uuid","validation"],"mappings":"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"}
1
+ {"version":3,"file":"chat.cjs.js","sources":["../../../src/services/router/chat.ts"],"sourcesContent":["import express from 'express';\nimport Router from 'express-promise-router';\nimport { ChatService } from '../chat';\nimport z from 'zod';\nimport { validation } from './middleware/validation';\nimport { v4 as uuid } from 'uuid';\nimport {\n DatabaseService,\n HttpAuthService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\n\nexport type ChatRouterOptions = {\n chat: ChatService;\n database: DatabaseService;\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n};\n\nexport async function createChatRouter(\n options: ChatRouterOptions,\n): Promise<express.Router> {\n const { chat, httpAuth, userInfo } = options;\n\n const router = Router();\n\n const messageSchema = z.object({\n messages: z.array(\n z.object({\n id: z.string().uuid().optional().default(uuid),\n role: z.string(),\n content: z.string(),\n }),\n ),\n modelId: z.string(),\n conversationId: z.uuid().optional().default(uuid),\n stream: z.boolean().optional(),\n tools: z\n .array(\n z.object({\n name: z.string(),\n provider: z.string(),\n }),\n )\n .optional(),\n });\n\n router.post(\n '/message',\n validation(messageSchema, 'body'),\n async (req, res) => {\n const { messages, conversationId, modelId, stream, tools } = req.body;\n\n const userCredentials = await httpAuth.credentials(req);\n\n const responseMessages = await chat.prompt({\n modelId,\n messages,\n conversationId,\n stream,\n userCredentials,\n tools,\n });\n\n res.json({\n messages: responseMessages,\n conversationId,\n });\n },\n );\n\n const chatSchema = z.object({\n id: z.uuid(),\n });\n\n router.get('/conversations', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await userInfo.getUserInfo(credentials);\n\n const conversations = await chat.getConversations({\n userEntityRef,\n });\n\n res.json({ conversations });\n });\n\n router.get('/tools', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n\n const tools = await chat.getAvailableTools({ credentials });\n\n res.json({ tools });\n });\n\n router.get('/:id', validation(chatSchema, 'params'), async (req, res) => {\n const { id } = req.params;\n\n const credentials = await httpAuth.credentials(req);\n const { userEntityRef } = await userInfo.getUserInfo(credentials);\n\n const conversation = await chat.getConversation({\n conversationId: id,\n userEntityRef,\n });\n\n res.json({ conversation });\n });\n\n router.post(\n '/message/:messageId/score',\n validation(\n z.object({\n messageId: z.string().uuid(),\n }),\n 'params',\n ),\n validation(\n z.object({\n score: z.number(),\n }),\n 'body',\n ),\n async (req, res) => {\n const { messageId } = req.params;\n const { score } = req.body;\n\n await chat.scoreMessage(messageId, score);\n\n res.status(204).end();\n },\n );\n\n return router;\n}\n"],"names":["Router","z","uuid","validation"],"mappings":"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"}
@@ -5,8 +5,8 @@ var Router = require('express-promise-router');
5
5
  var chat = require('./chat.cjs.js');
6
6
  var models = require('./models.cjs.js');
7
7
  var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
8
- var mcp = require('./mcp.cjs.js');
9
8
  var summary = require('./summary.cjs.js');
9
+ var index = require('./settings/index.cjs.js');
10
10
 
11
11
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
12
12
 
@@ -18,8 +18,8 @@ async function createRouter(options) {
18
18
  router.use(express__default.default.json());
19
19
  router.use("/chat", await chat.createChatRouter(options));
20
20
  router.use("/models", await models.createModelRouter(options));
21
- router.use("/mcp", await mcp.createMcpRouter(options));
22
21
  router.use("/summary", await summary.createSummaryRouter(options));
22
+ router.use("/settings", await index.createSettingsRouter(options));
23
23
  const middleware = rootHttpRouter.MiddlewareFactory.create(options);
24
24
  router.use(middleware.error());
25
25
  return router;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../../../src/services/router/index.ts"],"sourcesContent":["import express from 'express';\nimport Router from 'express-promise-router';\nimport { createChatRouter, ChatRouterOptions } from './chat';\nimport { createModelRouter } from './models';\nimport {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { createMcpRouter, McpRouterOptions } from './mcp';\nimport { SummaryRouterOptions, createSummaryRouter } from './summary';\n\nexport type RouterOptions = ChatRouterOptions &\n SummaryRouterOptions &\n McpRouterOptions & {\n config: RootConfigService;\n logger: LoggerService;\n };\n\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = Router();\n router.use(express.json());\n\n router.use('/chat', await createChatRouter(options));\n router.use('/models', await createModelRouter(options));\n router.use('/mcp', await createMcpRouter(options));\n router.use('/summary', await createSummaryRouter(options));\n\n const middleware = MiddlewareFactory.create(options);\n\n router.use(middleware.error());\n\n return router;\n}\n"],"names":["Router","express","createChatRouter","createModelRouter","createMcpRouter","createSummaryRouter","MiddlewareFactory"],"mappings":";;;;;;;;;;;;;;;AAmBA,eAAsB,aACpB,OAAA,EACyB;AACzB,EAAA,MAAM,SAASA,uBAAA,EAAO;AACtB,EAAA,MAAA,CAAO,GAAA,CAAIC,wBAAA,CAAQ,IAAA,EAAM,CAAA;AAEzB,EAAA,MAAA,CAAO,GAAA,CAAI,OAAA,EAAS,MAAMC,qBAAA,CAAiB,OAAO,CAAC,CAAA;AACnD,EAAA,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,MAAMC,wBAAA,CAAkB,OAAO,CAAC,CAAA;AACtD,EAAA,MAAA,CAAO,GAAA,CAAI,MAAA,EAAQ,MAAMC,mBAAA,CAAgB,OAAO,CAAC,CAAA;AACjD,EAAA,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,MAAMC,2BAAA,CAAoB,OAAO,CAAC,CAAA;AAEzD,EAAA,MAAM,UAAA,GAAaC,gCAAA,CAAkB,MAAA,CAAO,OAAO,CAAA;AAEnD,EAAA,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,KAAA,EAAO,CAAA;AAE7B,EAAA,OAAO,MAAA;AACT;;;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../src/services/router/index.ts"],"sourcesContent":["import express from 'express';\nimport Router from 'express-promise-router';\nimport { createChatRouter, ChatRouterOptions } from './chat';\nimport { createModelRouter, ModelRouterOptions } from './models';\nimport {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { SummaryRouterOptions, createSummaryRouter } from './summary';\nimport { createSettingsRouter, SettingsRouterOptions } from './settings';\n\nexport type RouterOptions = ChatRouterOptions &\n SummaryRouterOptions &\n ModelRouterOptions &\n SettingsRouterOptions & {\n config: RootConfigService;\n logger: LoggerService;\n };\n\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = Router();\n router.use(express.json());\n\n router.use('/chat', await createChatRouter(options));\n router.use('/models', await createModelRouter(options));\n router.use('/summary', await createSummaryRouter(options));\n router.use('/settings', await createSettingsRouter(options));\n\n const middleware = MiddlewareFactory.create(options);\n\n router.use(middleware.error());\n\n return router;\n}\n"],"names":["Router","express","createChatRouter","createModelRouter","createSummaryRouter","createSettingsRouter","MiddlewareFactory"],"mappings":";;;;;;;;;;;;;;;AAoBA,eAAsB,aACpB,OAAA,EACyB;AACzB,EAAA,MAAM,SAASA,uBAAA,EAAO;AACtB,EAAA,MAAA,CAAO,GAAA,CAAIC,wBAAA,CAAQ,IAAA,EAAM,CAAA;AAEzB,EAAA,MAAA,CAAO,GAAA,CAAI,OAAA,EAAS,MAAMC,qBAAA,CAAiB,OAAO,CAAC,CAAA;AACnD,EAAA,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,MAAMC,wBAAA,CAAkB,OAAO,CAAC,CAAA;AACtD,EAAA,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,MAAMC,2BAAA,CAAoB,OAAO,CAAC,CAAA;AACzD,EAAA,MAAA,CAAO,GAAA,CAAI,WAAA,EAAa,MAAMC,0BAAA,CAAqB,OAAO,CAAC,CAAA;AAE3D,EAAA,MAAM,UAAA,GAAaC,gCAAA,CAAkB,MAAA,CAAO,OAAO,CAAA;AAEnD,EAAA,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,KAAA,EAAO,CAAA;AAE7B,EAAA,OAAO,MAAA;AACT;;;;"}
@@ -0,0 +1,51 @@
1
+ 'use strict';
2
+
3
+ var express = require('express');
4
+ var Router = require('express-promise-router');
5
+ var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
6
+ var mcp = require('./mcp.cjs.js');
7
+ var z = require('zod');
8
+ var validation = require('../middleware/validation.cjs.js');
9
+
10
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
11
+
12
+ var express__default = /*#__PURE__*/_interopDefaultCompat(express);
13
+ var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
14
+ var z__default = /*#__PURE__*/_interopDefaultCompat(z);
15
+
16
+ async function createSettingsRouter(options) {
17
+ const { userSettings, httpAuth } = options;
18
+ const router = Router__default.default();
19
+ router.use(express__default.default.json());
20
+ router.use("/mcp", await mcp.createMcpRouter(options));
21
+ const settingsSchema = z__default.default.object({
22
+ type: z__default.default.string()
23
+ });
24
+ router.get("/", validation.validation(settingsSchema, "query"), async (req, res) => {
25
+ const credentials = await httpAuth.credentials(req);
26
+ const { type } = req.query;
27
+ const settings = await userSettings.getSettingsForType(
28
+ credentials,
29
+ type
30
+ );
31
+ res.json({
32
+ settings
33
+ });
34
+ });
35
+ const setSettingsSchema = z__default.default.object({
36
+ type: z__default.default.string(),
37
+ settings: z__default.default.any()
38
+ });
39
+ router.patch("/", validation.validation(setSettingsSchema, "body"), async (req, res) => {
40
+ const credentials = await httpAuth.credentials(req);
41
+ const { type, settings } = req.body;
42
+ await userSettings.setSettingsForType(credentials, type, settings);
43
+ res.status(204).send();
44
+ });
45
+ const middleware = rootHttpRouter.MiddlewareFactory.create(options);
46
+ router.use(middleware.error());
47
+ return router;
48
+ }
49
+
50
+ exports.createSettingsRouter = createSettingsRouter;
51
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../../src/services/router/settings/index.ts"],"sourcesContent":["import express from 'express';\nimport Router from 'express-promise-router';\nimport {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport { createMcpRouter, McpRouterOptions } from './mcp';\nimport { UserSettingsService } from '../../user-settings';\nimport z from 'zod';\nimport { validation } from '../middleware/validation';\n\nexport type SettingsRouterOptions = McpRouterOptions & {\n config: RootConfigService;\n logger: LoggerService;\n userSettings: UserSettingsService;\n};\n\nexport async function createSettingsRouter(\n options: SettingsRouterOptions,\n): Promise<express.Router> {\n const { userSettings, httpAuth } = options;\n const router = Router();\n router.use(express.json());\n\n router.use('/mcp', await createMcpRouter(options));\n\n const settingsSchema = z.object({\n type: z.string(),\n });\n\n router.get('/', validation(settingsSchema, 'query'), async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n\n const { type } = req.query;\n\n const settings = await userSettings.getSettingsForType(\n credentials,\n type as string,\n );\n\n res.json({\n settings,\n });\n });\n\n const setSettingsSchema = z.object({\n type: z.string(),\n settings: z.any(),\n });\n\n router.patch('/', validation(setSettingsSchema, 'body'), async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n const { type, settings } = req.body;\n\n await userSettings.setSettingsForType(credentials, type, settings);\n res.status(204).send();\n });\n\n const middleware = MiddlewareFactory.create(options);\n\n router.use(middleware.error());\n\n return router;\n}\n"],"names":["Router","express","createMcpRouter","z","validation","MiddlewareFactory"],"mappings":";;;;;;;;;;;;;;;AAkBA,eAAsB,qBACpB,OAAA,EACyB;AACzB,EAAA,MAAM,EAAE,YAAA,EAAc,QAAA,EAAS,GAAI,OAAA;AACnC,EAAA,MAAM,SAASA,uBAAA,EAAO;AACtB,EAAA,MAAA,CAAO,GAAA,CAAIC,wBAAA,CAAQ,IAAA,EAAM,CAAA;AAEzB,EAAA,MAAA,CAAO,GAAA,CAAI,MAAA,EAAQ,MAAMC,mBAAA,CAAgB,OAAO,CAAC,CAAA;AAEjD,EAAA,MAAM,cAAA,GAAiBC,mBAAE,MAAA,CAAO;AAAA,IAC9B,IAAA,EAAMA,mBAAE,MAAA;AAAO,GAChB,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,KAAKC,qBAAA,CAAW,cAAA,EAAgB,OAAO,CAAA,EAAG,OAAO,KAAK,GAAA,KAAQ;AACvE,IAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAElD,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,GAAA,CAAI,KAAA;AAErB,IAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,kBAAA;AAAA,MAClC,WAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,GAAA,CAAI,IAAA,CAAK;AAAA,MACP;AAAA,KACD,CAAA;AAAA,EACH,CAAC,CAAA;AAED,EAAA,MAAM,iBAAA,GAAoBD,mBAAE,MAAA,CAAO;AAAA,IACjC,IAAA,EAAMA,mBAAE,MAAA,EAAO;AAAA,IACf,QAAA,EAAUA,mBAAE,GAAA;AAAI,GACjB,CAAA;AAED,EAAA,MAAA,CAAO,KAAA,CAAM,KAAKC,qBAAA,CAAW,iBAAA,EAAmB,MAAM,CAAA,EAAG,OAAO,KAAK,GAAA,KAAQ;AAC3E,IAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAClD,IAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAS,GAAI,GAAA,CAAI,IAAA;AAE/B,IAAA,MAAM,YAAA,CAAa,kBAAA,CAAmB,WAAA,EAAa,IAAA,EAAM,QAAQ,CAAA;AACjE,IAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,EAAK;AAAA,EACvB,CAAC,CAAA;AAED,EAAA,MAAM,UAAA,GAAaC,gCAAA,CAAkB,MAAA,CAAO,OAAO,CAAA;AAEnD,EAAA,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,KAAA,EAAO,CAAA;AAE7B,EAAA,OAAO,MAAA;AACT;;;;"}
@@ -2,7 +2,7 @@
2
2
 
3
3
  var Router = require('express-promise-router');
4
4
  var z = require('zod');
5
- var validation = require('./middleware/validation.cjs.js');
5
+ var validation = require('../middleware/validation.cjs.js');
6
6
 
7
7
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
8
8
 
@@ -27,7 +27,7 @@ async function createMcpRouter(options) {
27
27
  const credentials = await httpAuth.credentials(req);
28
28
  const { name, options: mcpOptions } = req.body;
29
29
  try {
30
- await mcp.createUserMcpServerConfig(credentials, {
30
+ await mcp.setUserMcpServerConfig(credentials, {
31
31
  name,
32
32
  options: mcpOptions
33
33
  });
@@ -47,7 +47,7 @@ async function createMcpRouter(options) {
47
47
  const credentials = await httpAuth.credentials(req);
48
48
  const { name, options: mcpOptions } = req.body;
49
49
  try {
50
- await mcp.updateUserMcpServerConfig(credentials, {
50
+ await mcp.setUserMcpServerConfig(credentials, {
51
51
  name,
52
52
  options: mcpOptions
53
53
  });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.cjs.js","sources":["../../../../src/services/router/settings/mcp.ts"],"sourcesContent":["import express from 'express';\nimport Router from 'express-promise-router';\nimport { McpService } from '../../mcp';\nimport { HttpAuthService } from '@backstage/backend-plugin-api';\nimport z from 'zod';\nimport { validation } from '../middleware/validation';\n\nexport type McpRouterOptions = {\n mcp: McpService;\n httpAuth: HttpAuthService;\n};\n\nexport async function createMcpRouter(\n options: McpRouterOptions,\n): Promise<express.Router> {\n const { mcp, httpAuth } = options;\n const router = Router();\n\n router.get('/config', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n\n const names = await mcp.getUserMcpServerConfigNames(credentials);\n\n res.json({\n names,\n });\n });\n\n const configSchema = z.object({\n name: z.string(),\n options: z.record(z.string(), z.any()),\n });\n\n router.post('/config', validation(configSchema, 'body'), async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n const { name, options: mcpOptions } = req.body;\n try {\n await mcp.setUserMcpServerConfig(credentials, {\n name,\n options: mcpOptions,\n });\n\n res.status(201).send();\n } catch (error) {\n if (error instanceof Error && error.name === 'McpConfigurationError') {\n res.status(400).json({ error: error.message });\n return;\n }\n throw error;\n }\n });\n\n router.patch(\n '/config',\n validation(configSchema, 'body'),\n async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n const { name, options: mcpOptions } = req.body;\n\n try {\n await mcp.setUserMcpServerConfig(credentials, {\n name,\n options: mcpOptions,\n });\n res.status(204).send();\n } catch (error) {\n if (error instanceof Error && error.name === 'McpConfigurationError') {\n res.status(400).json({ error: error.message });\n return;\n }\n throw error;\n }\n },\n );\n\n const deleteConfigSchema = z.object({\n name: z.string(),\n });\n\n router.delete(\n '/config',\n validation(deleteConfigSchema, 'body'),\n async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n const { name } = req.body;\n\n await mcp.deleteUserMcpServerConfig(credentials, name);\n\n res.status(204).send();\n },\n );\n\n return router;\n}\n"],"names":["Router","z","validation"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ var userSettingsStore = require('../database/user-settings-store.cjs.js');
4
+
5
+ const createUserSettingsService = async ({
6
+ userInfo,
7
+ database
8
+ }) => {
9
+ const userSettingsStore$1 = await userSettingsStore.UserSettingsStore.fromConfig({ database });
10
+ const getSettingsForType = async (credentials, type) => {
11
+ const { userEntityRef } = await userInfo.getUserInfo(credentials);
12
+ const settings = await userSettingsStore$1.getUserSettingsByType(
13
+ userEntityRef,
14
+ type
15
+ );
16
+ return settings ?? {};
17
+ };
18
+ const setSettingsForType = async (credentials, type, settings) => {
19
+ const { userEntityRef } = await userInfo.getUserInfo(credentials);
20
+ await userSettingsStore$1.setUserSettings(userEntityRef, type, settings);
21
+ };
22
+ const deleteSettingsForType = async (credentials, type) => {
23
+ const { userEntityRef } = await userInfo.getUserInfo(credentials);
24
+ await userSettingsStore$1.deleteUserSettings(userEntityRef, type);
25
+ };
26
+ return {
27
+ getSettingsForType,
28
+ setSettingsForType,
29
+ deleteSettingsForType
30
+ };
31
+ };
32
+
33
+ exports.createUserSettingsService = createUserSettingsService;
34
+ //# sourceMappingURL=user-settings.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-settings.cjs.js","sources":["../../src/services/user-settings.ts"],"sourcesContent":["import {\n BackstageCredentials,\n DatabaseService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport { UserSettingsStore } from '../database/user-settings-store';\n\ntype CreateUserSettingsServiceOptions = {\n userInfo: UserInfoService;\n database: DatabaseService;\n};\n\nexport type UserSettingsService = {\n getSettingsForType: (\n credentials: BackstageCredentials,\n type: string,\n ) => Promise<Record<string, unknown>>;\n setSettingsForType: (\n credentials: BackstageCredentials,\n type: string,\n settings: Record<string, unknown>,\n ) => Promise<void>;\n deleteSettingsForType: (\n credentials: BackstageCredentials,\n type: string,\n ) => Promise<void>;\n};\n\nexport const createUserSettingsService = async ({\n userInfo,\n database,\n}: CreateUserSettingsServiceOptions): Promise<UserSettingsService> => {\n const userSettingsStore = await UserSettingsStore.fromConfig({ database });\n\n const getSettingsForType: UserSettingsService['getSettingsForType'] = async (\n credentials,\n type,\n ) => {\n const { userEntityRef } = await userInfo.getUserInfo(credentials);\n const settings = await userSettingsStore.getUserSettingsByType(\n userEntityRef,\n type,\n );\n\n return settings ?? {};\n };\n\n const setSettingsForType: UserSettingsService['setSettingsForType'] = async (\n credentials,\n type,\n settings,\n ) => {\n const { userEntityRef } = await userInfo.getUserInfo(credentials);\n await userSettingsStore.setUserSettings(userEntityRef, type, settings);\n };\n\n const deleteSettingsForType: UserSettingsService['deleteSettingsForType'] =\n async (credentials, type) => {\n const { userEntityRef } = await userInfo.getUserInfo(credentials);\n await userSettingsStore.deleteUserSettings(userEntityRef, type);\n };\n\n return {\n getSettingsForType,\n setSettingsForType,\n deleteSettingsForType,\n };\n};\n"],"names":["userSettingsStore","UserSettingsStore"],"mappings":";;;;AA4BO,MAAM,4BAA4B,OAAO;AAAA,EAC9C,QAAA;AAAA,EACA;AACF,CAAA,KAAsE;AACpE,EAAA,MAAMA,sBAAoB,MAAMC,mCAAA,CAAkB,UAAA,CAAW,EAAE,UAAU,CAAA;AAEzE,EAAA,MAAM,kBAAA,GAAgE,OACpE,WAAA,EACA,IAAA,KACG;AACH,IAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM,QAAA,CAAS,YAAY,WAAW,CAAA;AAChE,IAAA,MAAM,QAAA,GAAW,MAAMD,mBAAA,CAAkB,qBAAA;AAAA,MACvC,aAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,OAAO,YAAY,EAAC;AAAA,EACtB,CAAA;AAEA,EAAA,MAAM,kBAAA,GAAgE,OACpE,WAAA,EACA,IAAA,EACA,QAAA,KACG;AACH,IAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM,QAAA,CAAS,YAAY,WAAW,CAAA;AAChE,IAAA,MAAMA,mBAAA,CAAkB,eAAA,CAAgB,aAAA,EAAe,IAAA,EAAM,QAAQ,CAAA;AAAA,EACvE,CAAA;AAEA,EAAA,MAAM,qBAAA,GACJ,OAAO,WAAA,EAAa,IAAA,KAAS;AAC3B,IAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM,QAAA,CAAS,YAAY,WAAW,CAAA;AAChE,IAAA,MAAMA,mBAAA,CAAkB,kBAAA,CAAmB,aAAA,EAAe,IAAI,CAAA;AAAA,EAChE,CAAA;AAEF,EAAA,OAAO;AAAA,IACL,kBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -19,6 +19,7 @@ Use this tool when users ask about:
19
19
  - General questions about the company or internal information
20
20
 
21
21
  Do NOT use for general knowledge that doesn't require company-specific information.`,
22
+ provider: "core",
22
23
  schema: z__default.default.object({
23
24
  query: z__default.default.string().describe("The query to search for."),
24
25
  filter: z__default.default.object({
@@ -34,9 +35,18 @@ Do NOT use for general knowledge that doesn't require company-specific informati
34
35
  amount
35
36
  );
36
37
  if (results.length === 0) {
37
- return "No relevant information found.";
38
+ return {
39
+ content: "No relevant information found in the knowledge base."
40
+ };
38
41
  }
39
- return results.map((r) => r.content).join("\n---\n");
42
+ const content = results.map((r) => r.content).join("\n---\n");
43
+ const urls = results.map((r) => r.metadata.url);
44
+ return {
45
+ content,
46
+ metadata: {
47
+ urls
48
+ }
49
+ };
40
50
  }
41
51
  }
42
52
  });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchKnowledge.cjs.js","sources":["../../src/tools/searchKnowledge.ts"],"sourcesContent":["import {\n createAssistantTool,\n VectorStore,\n} from '@sweetoburrito/backstage-plugin-ai-assistant-node';\nimport { Tool } from '@sweetoburrito/backstage-plugin-ai-assistant-common';\nimport z from 'zod';\n\ntype CreateSearchKnowledgeToolOptions = {\n vectorStore: VectorStore;\n};\n\nexport const createSearchKnowledgeTool = ({\n vectorStore,\n}: CreateSearchKnowledgeToolOptions): Tool => {\n const knowledgeTool = createAssistantTool({\n tool: {\n name: 'search-knowledge-base',\n description: `Search the internal knowledge base containing company specific information.\n\nUse this tool when users ask about:\n- General questions about the company or internal information\n\nDo NOT use for general knowledge that doesn't require company-specific information.`,\n provider: 'core',\n schema: z.object({\n query: z.string().describe('The query to search for.'),\n filter: z\n .object({\n source: z.string().optional().describe('Source to filter by.'),\n id: z.string().optional().describe('ID to filter by.'),\n })\n .optional()\n .describe('Filters to apply to the search.'),\n amount: z\n .number()\n .min(1)\n .optional()\n .describe('The number of results to return.'),\n }),\n func: async ({ query, filter, amount }) => {\n const results = await vectorStore.similaritySearch(\n query,\n filter,\n amount,\n );\n\n if (results.length === 0) {\n return {\n content: 'No relevant information found in the knowledge base.',\n };\n }\n\n const content = results.map(r => r.content).join('\\n---\\n');\n\n const urls = results.map(r => r.metadata.url);\n\n return {\n content,\n metadata: {\n urls,\n },\n };\n },\n },\n });\n\n return knowledgeTool;\n};\n"],"names":["createAssistantTool","z"],"mappings":";;;;;;;;;AAWO,MAAM,4BAA4B,CAAC;AAAA,EACxC;AACF,CAAA,KAA8C;AAC5C,EAAA,MAAM,gBAAgBA,kDAAA,CAAoB;AAAA,IACxC,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,uBAAA;AAAA,MACN,WAAA,EAAa,CAAA;;AAAA;AAAA;;AAAA,mFAAA,CAAA;AAAA,MAMb,QAAA,EAAU,MAAA;AAAA,MACV,MAAA,EAAQC,mBAAE,MAAA,CAAO;AAAA,QACf,KAAA,EAAOA,kBAAA,CAAE,MAAA,EAAO,CAAE,SAAS,0BAA0B,CAAA;AAAA,QACrD,MAAA,EAAQA,mBACL,MAAA,CAAO;AAAA,UACN,QAAQA,kBAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,sBAAsB,CAAA;AAAA,UAC7D,IAAIA,kBAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,kBAAkB;AAAA,SACtD,CAAA,CACA,QAAA,EAAS,CACT,SAAS,iCAAiC,CAAA;AAAA,QAC7C,MAAA,EAAQA,kBAAA,CACL,MAAA,EAAO,CACP,GAAA,CAAI,CAAC,CAAA,CACL,QAAA,EAAS,CACT,QAAA,CAAS,kCAAkC;AAAA,OAC/C,CAAA;AAAA,MACD,MAAM,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAO,KAAM;AACzC,QAAA,MAAM,OAAA,GAAU,MAAM,WAAA,CAAY,gBAAA;AAAA,UAChC,KAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACF;AAEA,QAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,UAAA,OAAO;AAAA,YACL,OAAA,EAAS;AAAA,WACX;AAAA,QACF;AAEA,QAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,OAAO,CAAA,CAAE,KAAK,SAAS,CAAA;AAE1D,QAAA,MAAM,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,GAAG,CAAA;AAE5C,QAAA,OAAO;AAAA,UACL,OAAA;AAAA,UACA,QAAA,EAAU;AAAA,YACR;AAAA;AACF,SACF;AAAA,MACF;AAAA;AACF,GACD,CAAA;AAED,EAAA,OAAO,aAAA;AACT;;;;"}
@@ -0,0 +1,131 @@
1
+ const mcpConfigTable = 'user_mcp_config';
2
+ const newConfigTable = 'user_ai_assistant_settings';
3
+
4
+ /**
5
+ *
6
+ * @param {import('knex').knex} knex
7
+ */
8
+
9
+ exports.down = async knex => {
10
+ // Recreate old table
11
+ await knex.schema.createTable(mcpConfigTable, table => {
12
+ table
13
+ .uuid('id')
14
+ .primary()
15
+ .notNullable()
16
+ .defaultTo(knex.raw('gen_random_uuid()'));
17
+ table
18
+ .text('userRef')
19
+ .notNullable()
20
+ .comment('Reference to the user who sent the message');
21
+ table
22
+ .text('name')
23
+ .notNullable()
24
+ .comment('Name of the MCP server configuration');
25
+ table
26
+ .text('encryptedOptions')
27
+ .notNullable()
28
+ .comment('Encrypted MCP server configuration');
29
+ table.timestamps(true, true);
30
+ });
31
+
32
+ const mcpSettings = await knex(newConfigTable)
33
+ .where('type', 'mcp_server_config')
34
+ .select('*');
35
+
36
+ for (const setting of mcpSettings) {
37
+ const servers = setting.data;
38
+ const insertRecords = Object.entries(servers).map(
39
+ ([name, encryptedOptions]) => ({
40
+ userRef: setting.userRef,
41
+ name,
42
+ encryptedOptions,
43
+ created_at: setting.created_at,
44
+ updated_at: setting.updated_at,
45
+ }),
46
+ );
47
+
48
+ if (insertRecords.length > 0) {
49
+ await knex.batchInsert(mcpConfigTable, insertRecords);
50
+ }
51
+ }
52
+
53
+ await knex.schema.dropTable(newConfigTable);
54
+ };
55
+
56
+ /**
57
+ *
58
+ * @param {import('knex').knex} knex
59
+ */
60
+
61
+ exports.up = async knex => {
62
+ await knex.schema.createTable(newConfigTable, table => {
63
+ table
64
+ .uuid('id')
65
+ .primary()
66
+ .notNullable()
67
+ .defaultTo(knex.raw('gen_random_uuid()'));
68
+
69
+ table.text('userRef').notNullable().comment('Reference to the user');
70
+
71
+ table
72
+ .text('type')
73
+ .notNullable()
74
+ .comment('AI Assistant setting type. i.e "MCP, tools etc"');
75
+
76
+ table
77
+ .jsonb('data')
78
+ .notNullable()
79
+ .comment('AI assistant settings for the user');
80
+
81
+ table.unique(['userRef', 'type']);
82
+ table.timestamps(true, true);
83
+ });
84
+
85
+ // Check if old table exists
86
+ const hasMcpConfigTable = await knex.schema.hasTable(mcpConfigTable);
87
+
88
+ if (!hasMcpConfigTable) {
89
+ return;
90
+ }
91
+
92
+ const mcpConfigs = await knex(mcpConfigTable).select('*');
93
+
94
+ if (mcpConfigs.length <= 0) {
95
+ await knex.schema.dropTable(mcpConfigTable);
96
+ return;
97
+ }
98
+
99
+ const configsByUser = mcpConfigs.reduce((acc, config) => {
100
+ if (!acc[config.userRef]) {
101
+ acc[config.userRef] = {
102
+ userRef: config.userRef,
103
+ servers: {},
104
+ created_at: config.created_at,
105
+ updated_at: config.updated_at,
106
+ };
107
+ }
108
+ // Use name as key, encryptedOptions as value
109
+ acc[config.userRef].servers[config.name] = config.encryptedOptions;
110
+
111
+ // Keep the most recent timestamps
112
+ if (config.updated_at > acc[config.userRef].updated_at) {
113
+ acc[config.userRef].updated_at = config.updated_at;
114
+ }
115
+
116
+ return acc;
117
+ }, {});
118
+
119
+ await knex.batchInsert(
120
+ newConfigTable,
121
+ Object.values(configsByUser).map(userConfig => ({
122
+ userRef: userConfig.userRef,
123
+ type: 'mcp_server_config',
124
+ data: userConfig.servers,
125
+ created_at: userConfig.created_at,
126
+ updated_at: userConfig.updated_at,
127
+ })),
128
+ );
129
+
130
+ await knex.schema.dropTable(mcpConfigTable);
131
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sweetoburrito/backstage-plugin-ai-assistant-backend",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/index.cjs.js",
6
6
  "types": "dist/index.d.ts",
@@ -43,8 +43,8 @@
43
43
  "@langchain/langgraph": "^0.4.9",
44
44
  "@langchain/mcp-adapters": "^1.0.0",
45
45
  "@langchain/textsplitters": "^0.1.0",
46
- "@sweetoburrito/backstage-plugin-ai-assistant-common": "^0.6.0",
47
- "@sweetoburrito/backstage-plugin-ai-assistant-node": "^0.6.0",
46
+ "@sweetoburrito/backstage-plugin-ai-assistant-common": "^0.7.0",
47
+ "@sweetoburrito/backstage-plugin-ai-assistant-node": "^0.8.0",
48
48
  "express": "^4.17.1",
49
49
  "express-promise-router": "^4.1.0",
50
50
  "knex": "^3.1.0",
@@ -1,46 +0,0 @@
1
- 'use strict';
2
-
3
- const MCP_TABLE_NAME = "user_mcp_config";
4
- class McpStore {
5
- /**
6
- * Creates an instance of ChatStore.
7
- * @param client - The Knex client to interact with the PostgreSQL database.
8
- */
9
- constructor(client) {
10
- this.client = client;
11
- }
12
- static async fromConfig({ database }) {
13
- const client = await database.getClient();
14
- return new McpStore(client);
15
- }
16
- mcpTable() {
17
- return this.client(MCP_TABLE_NAME);
18
- }
19
- async getUserUserMcpConfigNames(userRef) {
20
- const rows = await this.mcpTable().where({ userRef }).select("name");
21
- return rows.map((row) => row.name);
22
- }
23
- async getUserMcpConfigs(userRef) {
24
- const rows = await this.mcpTable().where({ userRef }).select();
25
- return rows.map((row) => ({
26
- name: row.name,
27
- encryptedOptions: row.encryptedOptions
28
- }));
29
- }
30
- async createUserMcpConfig(userRef, name, encryptedOptions) {
31
- await this.mcpTable().insert({
32
- userRef,
33
- name,
34
- encryptedOptions
35
- });
36
- }
37
- async updateUserMcpConfig(userRef, name, encryptedOptions) {
38
- await this.mcpTable().where({ userRef, name }).update({ encryptedOptions });
39
- }
40
- async deleteUserMcpConfig(userRef, name) {
41
- await this.mcpTable().where({ userRef, name }).delete();
42
- }
43
- }
44
-
45
- exports.McpStore = McpStore;
46
- //# sourceMappingURL=mcp-store.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp-store.cjs.js","sources":["../../src/database/mcp-store.ts"],"sourcesContent":["import { DatabaseService } from '@backstage/backend-plugin-api';\n\nimport { Knex } from 'knex';\n\nconst MCP_TABLE_NAME = 'user_mcp_config';\n\nexport type McpStoreOptions = {\n database: DatabaseService;\n};\n\nexport class McpStore {\n /**\n * Creates an instance of ChatStore.\n * @param client - The Knex client to interact with the PostgreSQL database.\n */\n constructor(private readonly client: Knex) {}\n\n static async fromConfig({ database }: McpStoreOptions) {\n const client = await database.getClient();\n return new McpStore(client);\n }\n\n mcpTable() {\n return this.client(MCP_TABLE_NAME);\n }\n\n async getUserUserMcpConfigNames(userRef: string): Promise<string[]> {\n const rows = await this.mcpTable().where({ userRef }).select('name');\n return rows.map(row => row.name);\n }\n\n async getUserMcpConfigs(\n userRef: string,\n ): Promise<Array<{ name: string; encryptedOptions: string }>> {\n const rows = await this.mcpTable().where({ userRef }).select();\n return rows.map(row => ({\n name: row.name,\n encryptedOptions: row.encryptedOptions,\n }));\n }\n\n async createUserMcpConfig(\n userRef: string,\n name: string,\n encryptedOptions: string,\n ): Promise<void> {\n await this.mcpTable().insert({\n userRef,\n name,\n encryptedOptions,\n });\n }\n\n async updateUserMcpConfig(\n userRef: string,\n name: string,\n encryptedOptions: string,\n ): Promise<void> {\n await this.mcpTable().where({ userRef, name }).update({ encryptedOptions });\n }\n\n async deleteUserMcpConfig(userRef: string, name: string): Promise<void> {\n await this.mcpTable().where({ userRef, name }).delete();\n }\n}\n"],"names":[],"mappings":";;AAIA,MAAM,cAAA,GAAiB,iBAAA;AAMhB,MAAM,QAAA,CAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpB,YAA6B,MAAA,EAAc;AAAd,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAAe;AAAA,EAE5C,aAAa,UAAA,CAAW,EAAE,QAAA,EAAS,EAAoB;AACrD,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,SAAA,EAAU;AACxC,IAAA,OAAO,IAAI,SAAS,MAAM,CAAA;AAAA,EAC5B;AAAA,EAEA,QAAA,GAAW;AACT,IAAA,OAAO,IAAA,CAAK,OAAO,cAAc,CAAA;AAAA,EACnC;AAAA,EAEA,MAAM,0BAA0B,OAAA,EAAoC;AAClE,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,QAAA,EAAS,CAAE,KAAA,CAAM,EAAE,OAAA,EAAS,CAAA,CAAE,MAAA,CAAO,MAAM,CAAA;AACnE,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,GAAA,KAAO,GAAA,CAAI,IAAI,CAAA;AAAA,EACjC;AAAA,EAEA,MAAM,kBACJ,OAAA,EAC4D;AAC5D,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,QAAA,EAAS,CAAE,MAAM,EAAE,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO;AAC7D,IAAA,OAAO,IAAA,CAAK,IAAI,CAAA,GAAA,MAAQ;AAAA,MACtB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,kBAAkB,GAAA,CAAI;AAAA,KACxB,CAAE,CAAA;AAAA,EACJ;AAAA,EAEA,MAAM,mBAAA,CACJ,OAAA,EACA,IAAA,EACA,gBAAA,EACe;AACf,IAAA,MAAM,IAAA,CAAK,QAAA,EAAS,CAAE,MAAA,CAAO;AAAA,MAC3B,OAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,mBAAA,CACJ,OAAA,EACA,IAAA,EACA,gBAAA,EACe;AACf,IAAA,MAAM,IAAA,CAAK,QAAA,EAAS,CAAE,KAAA,CAAM,EAAE,OAAA,EAAS,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,EAAE,gBAAA,EAAkB,CAAA;AAAA,EAC5E;AAAA,EAEA,MAAM,mBAAA,CAAoB,OAAA,EAAiB,IAAA,EAA6B;AACtE,IAAA,MAAM,IAAA,CAAK,UAAS,CAAE,KAAA,CAAM,EAAE,OAAA,EAAS,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO;AAAA,EACxD;AACF;;;;"}
@@ -1,119 +0,0 @@
1
- 'use strict';
2
-
3
- var mcpAdapters = require('@langchain/mcp-adapters');
4
- var backstagePluginAiAssistantNode = require('@sweetoburrito/backstage-plugin-ai-assistant-node');
5
- var mcpStore = require('../database/mcp-store.cjs.js');
6
-
7
- const createMcpService = async ({
8
- config,
9
- userInfo,
10
- database
11
- }) => {
12
- const serversConfig = config.getOptionalConfigArray(
13
- "aiAssistant.mcp.servers"
14
- );
15
- const encryptionKey = config.getString("aiAssistant.mcp.encryptionKey");
16
- const preConfiguredMcpServers = serversConfig ? serversConfig.reduce((acc, server) => {
17
- const serverName = server.getString("name");
18
- const options = server.get("options");
19
- acc[serverName] = options;
20
- return acc;
21
- }, {}) : null;
22
- const preConfiguredMcpClient = preConfiguredMcpServers ? new mcpAdapters.MultiServerMCPClient({
23
- prefixToolNameWithServerName: true,
24
- useStandardContentBlocks: true,
25
- mcpServers: preConfiguredMcpServers
26
- }) : null;
27
- const mcpStore$1 = await mcpStore.McpStore.fromConfig({ database });
28
- const getUserMcpServerConfigNames = async (credentials) => {
29
- const { userEntityRef } = await userInfo.getUserInfo(credentials);
30
- return mcpStore$1.getUserUserMcpConfigNames(userEntityRef);
31
- };
32
- const getUserMcpServerConfig = async (credentials) => {
33
- const { userEntityRef } = await userInfo.getUserInfo(credentials);
34
- const encryptedMcpConfig = await mcpStore$1.getUserMcpConfigs(userEntityRef);
35
- const mcpConfig = encryptedMcpConfig.map((c) => ({
36
- name: c.name,
37
- options: JSON.parse(backstagePluginAiAssistantNode.decrypt(c.encryptedOptions, encryptionKey))
38
- }));
39
- return mcpConfig;
40
- };
41
- const getTools = async (credentials) => {
42
- const userMcpConfig = await getUserMcpServerConfig(credentials);
43
- const userMcpServers = userMcpConfig.length ? userMcpConfig.reduce((acc, server) => {
44
- const { name, options } = server;
45
- acc[name] = options;
46
- return acc;
47
- }, {}) : null;
48
- const userConfigClient = userMcpServers ? new mcpAdapters.MultiServerMCPClient({
49
- prefixToolNameWithServerName: true,
50
- useStandardContentBlocks: true,
51
- mcpServers: userMcpServers
52
- }) : null;
53
- const userMcpTools = userConfigClient ? await userConfigClient.getTools() : [];
54
- const preConfiguredMcpTools = preConfiguredMcpClient ? await preConfiguredMcpClient.getTools() : [];
55
- const mcpTools = [...userMcpTools, ...preConfiguredMcpTools];
56
- const tools = mcpTools.map((mcpTool) => {
57
- const { name, description, schema } = mcpTool;
58
- return backstagePluginAiAssistantNode.createAssistantTool({
59
- tool: {
60
- name,
61
- description,
62
- schema,
63
- func: async (params) => {
64
- const result = await mcpTool.invoke(params);
65
- return JSON.stringify(result);
66
- }
67
- }
68
- });
69
- });
70
- return tools;
71
- };
72
- const validateMcpServerConfig = async (mcpConfig) => {
73
- try {
74
- const userMcpServers = mcpConfig.reduce((acc, server) => {
75
- const { name, options } = server;
76
- acc[name] = options;
77
- return acc;
78
- }, {});
79
- const userConfigClient = new mcpAdapters.MultiServerMCPClient({
80
- prefixToolNameWithServerName: true,
81
- useStandardContentBlocks: true,
82
- mcpServers: userMcpServers
83
- });
84
- await userConfigClient.getTools();
85
- } catch (e) {
86
- const error = new Error("Invalid MCP server configuration");
87
- error.name = "McpConfigurationError";
88
- throw error;
89
- }
90
- };
91
- const createUserMcpServerConfig = async (credentials, mcpConfig) => {
92
- await validateMcpServerConfig([mcpConfig]);
93
- const { userEntityRef } = await userInfo.getUserInfo(credentials);
94
- const { name, options } = mcpConfig;
95
- const encryptedOptions = backstagePluginAiAssistantNode.encrypt(JSON.stringify(options), encryptionKey);
96
- await mcpStore$1.createUserMcpConfig(userEntityRef, name, encryptedOptions);
97
- };
98
- const updateUserMcpServerConfig = async (credentials, mcpConfig) => {
99
- await validateMcpServerConfig([mcpConfig]);
100
- const { userEntityRef } = await userInfo.getUserInfo(credentials);
101
- const { name, options } = mcpConfig;
102
- const encryptedOptions = backstagePluginAiAssistantNode.encrypt(JSON.stringify(options), encryptionKey);
103
- await mcpStore$1.updateUserMcpConfig(userEntityRef, name, encryptedOptions);
104
- };
105
- const deleteUserMcpServerConfig = async (credentials, name) => {
106
- const { userEntityRef } = await userInfo.getUserInfo(credentials);
107
- await mcpStore$1.deleteUserMcpConfig(userEntityRef, name);
108
- };
109
- return {
110
- getTools,
111
- createUserMcpServerConfig,
112
- updateUserMcpServerConfig,
113
- getUserMcpServerConfigNames,
114
- deleteUserMcpServerConfig
115
- };
116
- };
117
-
118
- exports.createMcpService = createMcpService;
119
- //# sourceMappingURL=mcp.cjs.js.map