@sweetoburrito/backstage-plugin-ai-assistant-backend 0.0.0-snapshot-20251210121031 → 0.0.0-snapshot-20251210134851
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/dist/plugin.cjs.js +2 -1
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/services/router/chat.cjs.js +1 -6
- package/dist/services/router/chat.cjs.js.map +1 -1
- package/dist/services/router/index.cjs.js +2 -0
- package/dist/services/router/index.cjs.js.map +1 -1
- package/dist/services/router/tools.cjs.js +21 -0
- package/dist/services/router/tools.cjs.js.map +1 -0
- package/dist/services/tools.cjs.js +13 -6
- package/dist/services/tools.cjs.js.map +1 -1
- package/package.json +3 -3
package/dist/plugin.cjs.js
CHANGED
|
@@ -98,7 +98,8 @@ const aiAssistantPlugin = backendPluginApi.createBackendPlugin({
|
|
|
98
98
|
ingestors
|
|
99
99
|
});
|
|
100
100
|
const searchKnowledgeTool = searchKnowledge.createSearchKnowledgeTool({ vectorStore });
|
|
101
|
-
tool.registerTools(
|
|
101
|
+
tool.registerTools(tools$1);
|
|
102
|
+
tool.registerCoreTools([searchKnowledgeTool]);
|
|
102
103
|
callback.registerCallbacks(callbacks$1);
|
|
103
104
|
model.registerModels(models);
|
|
104
105
|
httpRouter.use(await index$2.createRouter(options));
|
package/dist/plugin.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './services/router';\nimport {\n dataIngestorExtensionPoint,\n EmbeddingsProvider,\n embeddingsProviderExtensionPoint,\n Ingestor,\n Model,\n modelProviderExtensionPoint,\n toolExtensionPoint,\n callbackProviderExtensionPoint,\n CallbackProvider,\n} from '@sweetoburrito/backstage-plugin-ai-assistant-node';\nimport { Tool } from '@sweetoburrito/backstage-plugin-ai-assistant-common';\nimport { createDataIngestionPipeline } from './services/ingestor';\nimport { applyDatabaseMigrations } from './database/migrations';\nimport { PgVectorStore } from './database';\nimport { createSearchKnowledgeTool } from './tools/searchKnowledge';\nimport {\n callbackServiceRef,\n summarizerServiceRef,\n modelServiceRef,\n mcpServiceRef,\n toolsServiceRef,\n chatServiceRef,\n userSettingsServiceRef,\n conversationServiceRef,\n agentServiceRef,\n} from './services';\n\n/**\n * aiAssistantPlugin backend plugin\n *\n * @public\n */\n\nexport const aiAssistantPlugin = createBackendPlugin({\n pluginId: 'ai-assistant',\n register(env) {\n const ingestors: Ingestor[] = [];\n const models: Model[] = [];\n const tools: Tool[] = [];\n const callbacks: CallbackProvider[] = [];\n\n let embeddingsProvider: EmbeddingsProvider;\n\n env.registerExtensionPoint(dataIngestorExtensionPoint, {\n registerIngestor: ingestor => {\n const existingIngestor = ingestors.find(i => i.id === ingestor.id);\n if (existingIngestor) {\n throw new Error(\n `Ingestor with id ${ingestor.id} is already registered.`,\n );\n }\n ingestors.push(ingestor);\n },\n });\n\n env.registerExtensionPoint(embeddingsProviderExtensionPoint, {\n register: provider => {\n embeddingsProvider = provider;\n },\n });\n\n env.registerExtensionPoint(modelProviderExtensionPoint, {\n register: model => {\n const existingModel = models.find(m => m.id === model.id);\n if (existingModel) {\n throw new Error(`Model with id ${model.id} is already registered.`);\n }\n models.push(model);\n },\n });\n\n env.registerExtensionPoint(toolExtensionPoint, {\n register: tool => {\n const existingTool = tools.find(t => t.name === tool.name);\n if (existingTool) {\n throw new Error(`Tool with name ${tool.name} is already registered.`);\n }\n tools.push(tool);\n },\n });\n\n env.registerExtensionPoint(callbackProviderExtensionPoint, {\n register: callbackProvider => {\n callbacks.push(callbackProvider);\n },\n });\n\n env.registerInit({\n deps: {\n httpRouter: coreServices.httpRouter,\n database: coreServices.database,\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n scheduler: coreServices.scheduler,\n httpAuth: coreServices.httpAuth,\n userInfo: coreServices.userInfo,\n callback: callbackServiceRef,\n summarizer: summarizerServiceRef,\n model: modelServiceRef,\n mcp: mcpServiceRef,\n tool: toolsServiceRef,\n chat: chatServiceRef,\n userSettings: userSettingsServiceRef,\n conversation: conversationServiceRef,\n agent: agentServiceRef,\n },\n\n async init(options) {\n const { httpRouter, database, callback, model, tool } = options;\n\n const client = await database.getClient();\n\n await applyDatabaseMigrations(client);\n\n const vectorStore = await PgVectorStore.fromConfig(options);\n\n if (!embeddingsProvider) {\n throw new Error('No Embeddings Provider was registered.');\n }\n\n vectorStore.connectEmbeddings(await embeddingsProvider.getEmbeddings());\n\n const dataIngestionPipeline = createDataIngestionPipeline({\n ...options,\n vectorStore,\n ingestors,\n });\n\n const searchKnowledgeTool = createSearchKnowledgeTool({ vectorStore });\n\n tool.registerTools([
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './services/router';\nimport {\n dataIngestorExtensionPoint,\n EmbeddingsProvider,\n embeddingsProviderExtensionPoint,\n Ingestor,\n Model,\n modelProviderExtensionPoint,\n toolExtensionPoint,\n callbackProviderExtensionPoint,\n CallbackProvider,\n} from '@sweetoburrito/backstage-plugin-ai-assistant-node';\nimport { Tool } from '@sweetoburrito/backstage-plugin-ai-assistant-common';\nimport { createDataIngestionPipeline } from './services/ingestor';\nimport { applyDatabaseMigrations } from './database/migrations';\nimport { PgVectorStore } from './database';\nimport { createSearchKnowledgeTool } from './tools/searchKnowledge';\nimport {\n callbackServiceRef,\n summarizerServiceRef,\n modelServiceRef,\n mcpServiceRef,\n toolsServiceRef,\n chatServiceRef,\n userSettingsServiceRef,\n conversationServiceRef,\n agentServiceRef,\n} from './services';\n\n/**\n * aiAssistantPlugin backend plugin\n *\n * @public\n */\n\nexport const aiAssistantPlugin = createBackendPlugin({\n pluginId: 'ai-assistant',\n register(env) {\n const ingestors: Ingestor[] = [];\n const models: Model[] = [];\n const tools: Tool[] = [];\n const callbacks: CallbackProvider[] = [];\n\n let embeddingsProvider: EmbeddingsProvider;\n\n env.registerExtensionPoint(dataIngestorExtensionPoint, {\n registerIngestor: ingestor => {\n const existingIngestor = ingestors.find(i => i.id === ingestor.id);\n if (existingIngestor) {\n throw new Error(\n `Ingestor with id ${ingestor.id} is already registered.`,\n );\n }\n ingestors.push(ingestor);\n },\n });\n\n env.registerExtensionPoint(embeddingsProviderExtensionPoint, {\n register: provider => {\n embeddingsProvider = provider;\n },\n });\n\n env.registerExtensionPoint(modelProviderExtensionPoint, {\n register: model => {\n const existingModel = models.find(m => m.id === model.id);\n if (existingModel) {\n throw new Error(`Model with id ${model.id} is already registered.`);\n }\n models.push(model);\n },\n });\n\n env.registerExtensionPoint(toolExtensionPoint, {\n register: tool => {\n const existingTool = tools.find(t => t.name === tool.name);\n if (existingTool) {\n throw new Error(`Tool with name ${tool.name} is already registered.`);\n }\n tools.push(tool);\n },\n });\n\n env.registerExtensionPoint(callbackProviderExtensionPoint, {\n register: callbackProvider => {\n callbacks.push(callbackProvider);\n },\n });\n\n env.registerInit({\n deps: {\n httpRouter: coreServices.httpRouter,\n database: coreServices.database,\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n scheduler: coreServices.scheduler,\n httpAuth: coreServices.httpAuth,\n userInfo: coreServices.userInfo,\n callback: callbackServiceRef,\n summarizer: summarizerServiceRef,\n model: modelServiceRef,\n mcp: mcpServiceRef,\n tool: toolsServiceRef,\n chat: chatServiceRef,\n userSettings: userSettingsServiceRef,\n conversation: conversationServiceRef,\n agent: agentServiceRef,\n },\n\n async init(options) {\n const { httpRouter, database, callback, model, tool } = options;\n\n const client = await database.getClient();\n\n await applyDatabaseMigrations(client);\n\n const vectorStore = await PgVectorStore.fromConfig(options);\n\n if (!embeddingsProvider) {\n throw new Error('No Embeddings Provider was registered.');\n }\n\n vectorStore.connectEmbeddings(await embeddingsProvider.getEmbeddings());\n\n const dataIngestionPipeline = createDataIngestionPipeline({\n ...options,\n vectorStore,\n ingestors,\n });\n\n const searchKnowledgeTool = createSearchKnowledgeTool({ vectorStore });\n\n tool.registerTools(tools);\n tool.registerCoreTools([searchKnowledgeTool]);\n callback.registerCallbacks(callbacks);\n model.registerModels(models);\n\n httpRouter.use(await createRouter(options));\n dataIngestionPipeline.start();\n },\n });\n },\n});\n"],"names":["createBackendPlugin","tools","callbacks","dataIngestorExtensionPoint","embeddingsProviderExtensionPoint","modelProviderExtensionPoint","toolExtensionPoint","callbackProviderExtensionPoint","coreServices","callbackServiceRef","summarizerServiceRef","modelServiceRef","mcpServiceRef","toolsServiceRef","chatServiceRef","userSettingsServiceRef","conversationServiceRef","agentServiceRef","applyDatabaseMigrations","PgVectorStore","createDataIngestionPipeline","createSearchKnowledgeTool","createRouter"],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
|
11
11
|
var z__default = /*#__PURE__*/_interopDefaultCompat(z);
|
|
12
12
|
|
|
13
13
|
async function createChatRouter(options) {
|
|
14
|
-
const { chat, httpAuth, userInfo,
|
|
14
|
+
const { chat, httpAuth, userInfo, conversation } = options;
|
|
15
15
|
const router = Router__default.default();
|
|
16
16
|
const messageSchema = z__default.default.object({
|
|
17
17
|
messages: z__default.default.array(
|
|
@@ -62,11 +62,6 @@ async function createChatRouter(options) {
|
|
|
62
62
|
});
|
|
63
63
|
res.json({ conversations });
|
|
64
64
|
});
|
|
65
|
-
router.get("/tools", async (req, res) => {
|
|
66
|
-
const credentials = await httpAuth.credentials(req);
|
|
67
|
-
const tools = await tool.getAvailableUserTools({ credentials });
|
|
68
|
-
res.json({ tools });
|
|
69
|
-
});
|
|
70
65
|
router.get("/:id", validation.validation(chatSchema, "params"), async (req, res) => {
|
|
71
66
|
const { id } = req.params;
|
|
72
67
|
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 HttpAuthService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport {
|
|
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 HttpAuthService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport { ConversationService } from '../conversation';\n\nexport type ChatRouterOptions = {\n chat: ChatService;\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n conversation: ConversationService;\n};\n\nexport async function createChatRouter(\n options: ChatRouterOptions,\n): Promise<express.Router> {\n const { chat, httpAuth, userInfo, conversation } = options;\n\n const router = Router();\n\n const messageSchema = z.object({\n messages: z.array(\n z.object({\n id: z.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 credentials = await httpAuth.credentials(req);\n\n const responseMessages = await chat.prompt({\n modelId,\n messages,\n conversationId,\n stream,\n credentials,\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 conversation.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 conversationMessages = await conversation.getConversation({\n conversationId: id,\n userEntityRef,\n });\n\n res.json({ conversation: conversationMessages });\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 conversation.scoreMessage(messageId, score);\n\n res.status(204).end();\n },\n );\n\n return router;\n}\n"],"names":["Router","z","uuid","validation"],"mappings":";;;;;;;;;;;;AAmBA,eAAsB,iBACpB,OAAA,EACyB;AACzB,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,QAAA,EAAU,cAAa,GAAI,OAAA;AAEnD,EAAA,MAAM,SAASA,uBAAA,EAAO;AAEtB,EAAA,MAAM,aAAA,GAAgBC,mBAAE,MAAA,CAAO;AAAA,IAC7B,UAAUA,kBAAA,CAAE,KAAA;AAAA,MACVA,mBAAE,MAAA,CAAO;AAAA,QACP,IAAIA,kBAAA,CAAE,IAAA,GAAO,QAAA,EAAS,CAAE,QAAQC,OAAI,CAAA;AAAA,QACpC,IAAA,EAAMD,mBAAE,MAAA,EAAO;AAAA,QACf,OAAA,EAASA,mBAAE,MAAA;AAAO,OACnB;AAAA,KACH;AAAA,IACA,OAAA,EAASA,mBAAE,MAAA,EAAO;AAAA,IAClB,gBAAgBA,kBAAA,CAAE,IAAA,GAAO,QAAA,EAAS,CAAE,QAAQC,OAAI,CAAA;AAAA,IAChD,MAAA,EAAQD,kBAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,IAC7B,OAAOA,kBAAA,CACJ,KAAA;AAAA,MACCA,mBAAE,MAAA,CAAO;AAAA,QACP,IAAA,EAAMA,mBAAE,MAAA,EAAO;AAAA,QACf,QAAA,EAAUA,mBAAE,MAAA;AAAO,OACpB;AAAA,MAEF,QAAA;AAAS,GACb,CAAA;AAED,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,UAAA;AAAA,IACAE,qBAAA,CAAW,eAAe,MAAM,CAAA;AAAA,IAChC,OAAO,KAAK,GAAA,KAAQ;AAClB,MAAA,MAAM,EAAE,QAAA,EAAU,cAAA,EAAgB,SAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,CAAI,IAAA;AAEjE,MAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAElD,MAAA,MAAM,gBAAA,GAAmB,MAAM,IAAA,CAAK,MAAA,CAAO;AAAA,QACzC,OAAA;AAAA,QACA,QAAA;AAAA,QACA,cAAA;AAAA,QACA,MAAA;AAAA,QACA,WAAA;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,QAAA,EAAU,gBAAA;AAAA,QACV;AAAA,OACD,CAAA;AAAA,IACH;AAAA,GACF;AAEA,EAAA,MAAM,UAAA,GAAaF,mBAAE,MAAA,CAAO;AAAA,IAC1B,EAAA,EAAIA,mBAAE,IAAA;AAAK,GACZ,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,gBAAA,EAAkB,OAAO,GAAA,EAAK,GAAA,KAAQ;AAC/C,IAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAClD,IAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM,QAAA,CAAS,YAAY,WAAW,CAAA;AAEhE,IAAA,MAAM,aAAA,GAAgB,MAAM,YAAA,CAAa,gBAAA,CAAiB;AAAA,MACxD;AAAA,KACD,CAAA;AAED,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,aAAA,EAAe,CAAA;AAAA,EAC5B,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,QAAQE,qBAAA,CAAW,UAAA,EAAY,QAAQ,CAAA,EAAG,OAAO,KAAK,GAAA,KAAQ;AACvE,IAAA,MAAM,EAAE,EAAA,EAAG,GAAI,GAAA,CAAI,MAAA;AAEnB,IAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAClD,IAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM,QAAA,CAAS,YAAY,WAAW,CAAA;AAEhE,IAAA,MAAM,oBAAA,GAAuB,MAAM,YAAA,CAAa,eAAA,CAAgB;AAAA,MAC9D,cAAA,EAAgB,EAAA;AAAA,MAChB;AAAA,KACD,CAAA;AAED,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,YAAA,EAAc,oBAAA,EAAsB,CAAA;AAAA,EACjD,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,2BAAA;AAAA,IACAA,qBAAA;AAAA,MACEF,mBAAE,MAAA,CAAO;AAAA,QACP,SAAA,EAAWA,kBAAA,CAAE,MAAA,EAAO,CAAE,IAAA;AAAK,OAC5B,CAAA;AAAA,MACD;AAAA,KACF;AAAA,IACAE,qBAAA;AAAA,MACEF,mBAAE,MAAA,CAAO;AAAA,QACP,KAAA,EAAOA,mBAAE,MAAA;AAAO,OACjB,CAAA;AAAA,MACD;AAAA,KACF;AAAA,IACA,OAAO,KAAK,GAAA,KAAQ;AAClB,MAAA,MAAM,EAAE,SAAA,EAAU,GAAI,GAAA,CAAI,MAAA;AAC1B,MAAA,MAAM,EAAE,KAAA,EAAM,GAAI,GAAA,CAAI,IAAA;AAEtB,MAAA,MAAM,YAAA,CAAa,YAAA,CAAa,SAAA,EAAW,KAAK,CAAA;AAEhD,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,GAAA,EAAI;AAAA,IACtB;AAAA,GACF;AAEA,EAAA,OAAO,MAAA;AACT;;;;"}
|
|
@@ -8,6 +8,7 @@ var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
|
|
|
8
8
|
var summary = require('./summary.cjs.js');
|
|
9
9
|
var index = require('./settings/index.cjs.js');
|
|
10
10
|
var agent = require('./agent.cjs.js');
|
|
11
|
+
var tools = require('./tools.cjs.js');
|
|
11
12
|
|
|
12
13
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
13
14
|
|
|
@@ -22,6 +23,7 @@ async function createRouter(options) {
|
|
|
22
23
|
router.use("/summary", await summary.createSummaryRouter(options));
|
|
23
24
|
router.use("/settings", await index.createSettingsRouter(options));
|
|
24
25
|
router.use("/agent", await agent.createAgentRouter(options));
|
|
26
|
+
router.use("/tools", await tools.createToolRouter(options));
|
|
25
27
|
const middleware = rootHttpRouter.MiddlewareFactory.create(options);
|
|
26
28
|
router.use(middleware.error());
|
|
27
29
|
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, 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';\nimport { createAgentRouter, AgentRouterOptions } from './agent';\n\nexport type RouterOptions = ChatRouterOptions &\n SummaryRouterOptions &\n ModelRouterOptions &\n SettingsRouterOptions &\n AgentRouterOptions & {\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 router.use('/agent', await createAgentRouter(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","createAgentRouter","MiddlewareFactory"],"mappings":"
|
|
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';\nimport { createAgentRouter, AgentRouterOptions } from './agent';\nimport { createToolRouter, ToolRouterOptions } from './tools';\n\nexport type RouterOptions = ChatRouterOptions &\n SummaryRouterOptions &\n ModelRouterOptions &\n SettingsRouterOptions &\n AgentRouterOptions &\n ToolRouterOptions & {\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 router.use('/agent', await createAgentRouter(options));\n router.use('/tools', await createToolRouter(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","createAgentRouter","createToolRouter","MiddlewareFactory"],"mappings":";;;;;;;;;;;;;;;;;AAwBA,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;AAC3D,EAAA,MAAA,CAAO,GAAA,CAAI,QAAA,EAAU,MAAMC,uBAAA,CAAkB,OAAO,CAAC,CAAA;AACrD,EAAA,MAAA,CAAO,GAAA,CAAI,QAAA,EAAU,MAAMC,sBAAA,CAAiB,OAAO,CAAC,CAAA;AAEpD,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,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var Router = require('express-promise-router');
|
|
4
|
+
|
|
5
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
8
|
+
|
|
9
|
+
async function createToolRouter(options) {
|
|
10
|
+
const { httpAuth, tool } = options;
|
|
11
|
+
const router = Router__default.default();
|
|
12
|
+
router.get("/", async (req, res) => {
|
|
13
|
+
const credentials = await httpAuth.credentials(req);
|
|
14
|
+
const tools = await tool.getAvailableUserTools({ credentials });
|
|
15
|
+
res.json({ tools });
|
|
16
|
+
});
|
|
17
|
+
return router;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.createToolRouter = createToolRouter;
|
|
21
|
+
//# sourceMappingURL=tools.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.cjs.js","sources":["../../../src/services/router/tools.ts"],"sourcesContent":["import express from 'express';\nimport Router from 'express-promise-router';\nimport { HttpAuthService } from '@backstage/backend-plugin-api';\nimport { ToolsService } from '../tools';\n\nexport type ToolRouterOptions = {\n httpAuth: HttpAuthService;\n tool: ToolsService;\n};\n\nexport async function createToolRouter(\n options: ToolRouterOptions,\n): Promise<express.Router> {\n const { httpAuth, tool } = options;\n const router = Router();\n\n router.get('/', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n\n const tools = await tool.getAvailableUserTools({ credentials });\n\n res.json({ tools });\n });\n\n return router;\n}\n"],"names":["Router"],"mappings":";;;;;;;;AAUA,eAAsB,iBACpB,OAAA,EACyB;AACzB,EAAA,MAAM,EAAE,QAAA,EAAU,IAAA,EAAK,GAAI,OAAA;AAC3B,EAAA,MAAM,SAASA,uBAAA,EAAO;AAEtB,EAAA,MAAA,CAAO,GAAA,CAAI,GAAA,EAAK,OAAO,GAAA,EAAK,GAAA,KAAQ;AAClC,IAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAElD,IAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,qBAAA,CAAsB,EAAE,aAAa,CAAA;AAE9D,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,KAAA,EAAO,CAAA;AAAA,EACpB,CAAC,CAAA;AAED,EAAA,OAAO,MAAA;AACT;;;;"}
|
|
@@ -9,17 +9,18 @@ const createToolsService = async ({
|
|
|
9
9
|
auth
|
|
10
10
|
}) => {
|
|
11
11
|
const tools$1 = [];
|
|
12
|
+
const coreTools = [];
|
|
12
13
|
const registerTools = async (providers) => {
|
|
13
14
|
tools$1.push(...providers);
|
|
14
15
|
};
|
|
15
|
-
const
|
|
16
|
-
|
|
16
|
+
const registerCoreTools = async (providers) => {
|
|
17
|
+
coreTools.push(...providers.map((tool) => ({ ...tool, provider: "core" })));
|
|
17
18
|
};
|
|
18
19
|
const getAvailableUserTools = async ({
|
|
19
20
|
credentials
|
|
20
21
|
}) => {
|
|
21
22
|
const mcpTools = await mcp.getTools(credentials);
|
|
22
|
-
const availableTools = tools$1.concat(mcpTools).map((tool) => ({
|
|
23
|
+
const availableTools = tools$1.concat(mcpTools).concat(coreTools).map((tool) => ({
|
|
23
24
|
name: tool.name,
|
|
24
25
|
provider: tool.provider,
|
|
25
26
|
description: tool.description
|
|
@@ -35,10 +36,16 @@ const createToolsService = async ({
|
|
|
35
36
|
return tools$1.filter(filter).map((t) => new tools.DynamicStructuredTool(t));
|
|
36
37
|
}
|
|
37
38
|
const mcpTools = await mcp.getTools(credentials);
|
|
38
|
-
const
|
|
39
|
-
|
|
39
|
+
const userTools = tools$1.concat(mcpTools);
|
|
40
|
+
const allTools = userTools.filter(filter).concat(coreTools.filter(filter));
|
|
41
|
+
return allTools.map((t) => new tools.DynamicStructuredTool(t));
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
registerTools,
|
|
45
|
+
registerCoreTools,
|
|
46
|
+
getAvailableUserTools,
|
|
47
|
+
getPrincipalTools
|
|
40
48
|
};
|
|
41
|
-
return { registerTools, getTools, getAvailableUserTools, getPrincipalTools };
|
|
42
49
|
};
|
|
43
50
|
const toolsServiceRef = backendPluginApi.createServiceRef({
|
|
44
51
|
id: "ai-assistant.tools-service",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.cjs.js","sources":["../../src/services/tools.ts"],"sourcesContent":["import {\n BackstageCredentials,\n coreServices,\n createServiceFactory,\n createServiceRef,\n ServiceRef,\n AuthService,\n} from '@backstage/backend-plugin-api';\nimport {\n Tool,\n
|
|
1
|
+
{"version":3,"file":"tools.cjs.js","sources":["../../src/services/tools.ts"],"sourcesContent":["import {\n BackstageCredentials,\n coreServices,\n createServiceFactory,\n createServiceRef,\n ServiceRef,\n AuthService,\n} from '@backstage/backend-plugin-api';\nimport {\n Tool,\n EnabledTool,\n} from '@sweetoburrito/backstage-plugin-ai-assistant-common';\nimport { McpService, mcpServiceRef } from './mcp';\nimport { DynamicStructuredTool } from '@langchain/core/tools';\n\nexport type ToolsService = {\n registerTools: (tools: Tool[]) => void;\n registerCoreTools: (tools: Tool[]) => void;\n getAvailableUserTools: (options: {\n credentials: BackstageCredentials;\n }) => Promise<EnabledTool[]>;\n getPrincipalTools: (options: {\n credentials: BackstageCredentials;\n filter?: (tool: Tool) => boolean;\n }) => Promise<DynamicStructuredTool[]>;\n};\n\nexport type CreateToolsServiceOptions = {\n mcp: McpService;\n auth: AuthService;\n};\n\nconst createToolsService = async ({\n mcp,\n auth,\n}: CreateToolsServiceOptions): Promise<ToolsService> => {\n const tools: Tool[] = [];\n const coreTools: Tool[] = [];\n\n const registerTools: ToolsService['registerTools'] = async providers => {\n tools.push(...providers);\n };\n\n const registerCoreTools: ToolsService['registerCoreTools'] =\n async providers => {\n coreTools.push(...providers.map(tool => ({ ...tool, provider: 'core' })));\n };\n\n const getAvailableUserTools: ToolsService['getAvailableUserTools'] = async ({\n credentials,\n }) => {\n const mcpTools = await mcp.getTools(credentials);\n\n const availableTools: EnabledTool[] = tools\n .concat(mcpTools)\n .concat(coreTools)\n .map(tool => ({\n name: tool.name,\n provider: tool.provider,\n description: tool.description,\n }));\n\n return availableTools;\n };\n\n const getPrincipalTools: ToolsService['getPrincipalTools'] = async ({\n credentials,\n filter = () => true,\n }) => {\n const isUser = auth.isPrincipal(credentials, 'user');\n\n if (!isUser) {\n return tools.filter(filter).map(t => new DynamicStructuredTool(t));\n }\n\n const mcpTools = await mcp.getTools(credentials);\n\n const userTools = tools.concat(mcpTools);\n\n const allTools: Tool[] = userTools\n .filter(filter)\n .concat(coreTools.filter(filter));\n return allTools.map(t => new DynamicStructuredTool(t));\n };\n\n return {\n registerTools,\n registerCoreTools,\n getAvailableUserTools,\n getPrincipalTools,\n };\n};\n\nexport const toolsServiceRef: ServiceRef<ToolsService, 'plugin', 'singleton'> =\n createServiceRef<ToolsService>({\n id: 'ai-assistant.tools-service',\n defaultFactory: async service =>\n createServiceFactory({\n service,\n deps: {\n mcp: mcpServiceRef,\n auth: coreServices.auth,\n },\n factory: async options => {\n return createToolsService(options);\n },\n }),\n });\n"],"names":["tools","DynamicStructuredTool","createServiceRef","createServiceFactory","mcpServiceRef","coreServices"],"mappings":";;;;;;AAgCA,MAAM,qBAAqB,OAAO;AAAA,EAChC,GAAA;AAAA,EACA;AACF,CAAA,KAAwD;AACtD,EAAA,MAAMA,UAAgB,EAAC;AACvB,EAAA,MAAM,YAAoB,EAAC;AAE3B,EAAA,MAAM,aAAA,GAA+C,OAAM,SAAA,KAAa;AACtE,IAAAA,OAAA,CAAM,IAAA,CAAK,GAAG,SAAS,CAAA;AAAA,EACzB,CAAA;AAEA,EAAA,MAAM,iBAAA,GACJ,OAAM,SAAA,KAAa;AACjB,IAAA,SAAA,CAAU,IAAA,CAAK,GAAG,SAAA,CAAU,GAAA,CAAI,CAAA,IAAA,MAAS,EAAE,GAAG,IAAA,EAAM,QAAA,EAAU,MAAA,EAAO,CAAE,CAAC,CAAA;AAAA,EAC1E,CAAA;AAEF,EAAA,MAAM,wBAA+D,OAAO;AAAA,IAC1E;AAAA,GACF,KAAM;AACJ,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,QAAA,CAAS,WAAW,CAAA;AAE/C,IAAA,MAAM,cAAA,GAAgCA,QACnC,MAAA,CAAO,QAAQ,EACf,MAAA,CAAO,SAAS,CAAA,CAChB,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,MACZ,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,aAAa,IAAA,CAAK;AAAA,KACpB,CAAE,CAAA;AAEJ,IAAA,OAAO,cAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,oBAAuD,OAAO;AAAA,IAClE,WAAA;AAAA,IACA,SAAS,MAAM;AAAA,GACjB,KAAM;AACJ,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,WAAA,CAAY,WAAA,EAAa,MAAM,CAAA;AAEnD,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,OAAOA,OAAA,CAAM,OAAO,MAAM,CAAA,CAAE,IAAI,CAAA,CAAA,KAAK,IAAIC,2BAAA,CAAsB,CAAC,CAAC,CAAA;AAAA,IACnE;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,QAAA,CAAS,WAAW,CAAA;AAE/C,IAAA,MAAM,SAAA,GAAYD,OAAA,CAAM,MAAA,CAAO,QAAQ,CAAA;AAEvC,IAAA,MAAM,QAAA,GAAmB,UACtB,MAAA,CAAO,MAAM,EACb,MAAA,CAAO,SAAA,CAAU,MAAA,CAAO,MAAM,CAAC,CAAA;AAClC,IAAA,OAAO,SAAS,GAAA,CAAI,CAAA,CAAA,KAAK,IAAIC,2BAAA,CAAsB,CAAC,CAAC,CAAA;AAAA,EACvD,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,aAAA;AAAA,IACA,iBAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAA,GACF;AACF,CAAA;AAEO,MAAM,kBACXC,iCAAA,CAA+B;AAAA,EAC7B,EAAA,EAAI,4BAAA;AAAA,EACJ,cAAA,EAAgB,OAAM,OAAA,KACpBC,qCAAA,CAAqB;AAAA,IACnB,OAAA;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,GAAA,EAAKC,mBAAA;AAAA,MACL,MAAMC,6BAAA,CAAa;AAAA,KACrB;AAAA,IACA,OAAA,EAAS,OAAM,OAAA,KAAW;AACxB,MAAA,OAAO,mBAAmB,OAAO,CAAA;AAAA,IACnC;AAAA,GACD;AACL,CAAC;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sweetoburrito/backstage-plugin-ai-assistant-backend",
|
|
3
|
-
"version": "0.0.0-snapshot-
|
|
3
|
+
"version": "0.0.0-snapshot-20251210134851",
|
|
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": "
|
|
47
|
-
"@sweetoburrito/backstage-plugin-ai-assistant-node": "0.0.0-snapshot-
|
|
46
|
+
"@sweetoburrito/backstage-plugin-ai-assistant-common": "0.0.0-snapshot-20251210134851",
|
|
47
|
+
"@sweetoburrito/backstage-plugin-ai-assistant-node": "0.0.0-snapshot-20251210134851",
|
|
48
48
|
"express": "^4.17.1",
|
|
49
49
|
"express-promise-router": "^4.1.0",
|
|
50
50
|
"knex": "^3.1.0",
|