@sweetoburrito/backstage-plugin-ai-assistant-backend 0.9.0 → 0.11.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/config.d.ts +8 -0
- package/dist/constants/prompts.cjs.js +15 -7
- package/dist/constants/prompts.cjs.js.map +1 -1
- package/dist/database/chat-store.cjs.js +22 -2
- package/dist/database/chat-store.cjs.js.map +1 -1
- package/dist/database/mcp-store.cjs.js +46 -0
- package/dist/database/mcp-store.cjs.js.map +1 -0
- package/dist/plugin.cjs.js +26 -3
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/services/callbacks.cjs.js +49 -0
- package/dist/services/callbacks.cjs.js.map +1 -0
- package/dist/services/chat.cjs.js +73 -34
- package/dist/services/chat.cjs.js.map +1 -1
- package/dist/services/mcp.cjs.js +121 -0
- package/dist/services/mcp.cjs.js.map +1 -0
- package/dist/services/router/chat.cjs.js +23 -3
- package/dist/services/router/chat.cjs.js.map +1 -1
- package/dist/services/router/index.cjs.js +4 -0
- package/dist/services/router/index.cjs.js.map +1 -1
- package/dist/services/router/mcp.cjs.js +81 -0
- package/dist/services/router/mcp.cjs.js.map +1 -0
- package/dist/services/router/summary.cjs.js +56 -0
- package/dist/services/router/summary.cjs.js.map +1 -0
- package/dist/services/summarizer.cjs.js +38 -14
- package/dist/services/summarizer.cjs.js.map +1 -1
- package/dist/services/tools/searchKnowledge.cjs.js +12 -2
- package/dist/services/tools/searchKnowledge.cjs.js.map +1 -1
- package/migrations/20251029_mcp.js +42 -0
- package/migrations/20251029_score.js +52 -0
- package/package.json +6 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchKnowledge.cjs.js","sources":["../../../src/services/tools/searchKnowledge.ts"],"sourcesContent":["import {\n createAssistantTool,\n Tool,\n VectorStore,\n} from '@sweetoburrito/backstage-plugin-ai-assistant-node';\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 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 if (results.length === 0) {\n return 'No relevant information found.';\n }\n
|
|
1
|
+
{"version":3,"file":"searchKnowledge.cjs.js","sources":["../../../src/services/tools/searchKnowledge.ts"],"sourcesContent":["import {\n createAssistantTool,\n Tool,\n VectorStore,\n} from '@sweetoburrito/backstage-plugin-ai-assistant-node';\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 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 console.log(results);\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,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,OAAA,CAAQ,IAAI,OAAO,CAAA;AAEnB,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,42 @@
|
|
|
1
|
+
const mcpConfigTable = 'user_mcp_config';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {import('knex').knex} knex
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
exports.down = async knex => {
|
|
9
|
+
const hasMcpConfigTable = await knex.schema.hasTable(mcpConfigTable);
|
|
10
|
+
|
|
11
|
+
if (hasMcpConfigTable) {
|
|
12
|
+
await knex.schema.dropTable(mcpConfigTable);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @param {import('knex').knex} knex
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
exports.up = async knex => {
|
|
22
|
+
await knex.schema.createTable(mcpConfigTable, table => {
|
|
23
|
+
table
|
|
24
|
+
.uuid('id')
|
|
25
|
+
.primary()
|
|
26
|
+
.notNullable()
|
|
27
|
+
.defaultTo(knex.raw('gen_random_uuid()'));
|
|
28
|
+
table
|
|
29
|
+
.text('userRef')
|
|
30
|
+
.notNullable()
|
|
31
|
+
.comment('Reference to the user who sent the message');
|
|
32
|
+
table
|
|
33
|
+
.text('name')
|
|
34
|
+
.notNullable()
|
|
35
|
+
.comment('Name of the MCP server configuration');
|
|
36
|
+
table
|
|
37
|
+
.text('encryptedOptions')
|
|
38
|
+
.notNullable()
|
|
39
|
+
.comment('Encrypted MCP server configuration');
|
|
40
|
+
table.timestamps(true, true);
|
|
41
|
+
});
|
|
42
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {import('knex').knex} knex
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
exports.down = async knex => {
|
|
7
|
+
const hasScoreColumn = await knex.schema.hasColumn('message', 'score');
|
|
8
|
+
const hasTraceIdColumn = await knex.schema.hasColumn('message', 'trace_id');
|
|
9
|
+
|
|
10
|
+
if (hasScoreColumn || hasTraceIdColumn) {
|
|
11
|
+
await knex.schema.alterTable('message', table => {
|
|
12
|
+
if (hasScoreColumn) {
|
|
13
|
+
table.dropColumn('score');
|
|
14
|
+
}
|
|
15
|
+
if (hasTraceIdColumn) {
|
|
16
|
+
table.dropColumn('trace_id');
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @param {import('knex').knex} knex
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
exports.up = async knex => {
|
|
28
|
+
const hasScoreColumn = await knex.schema.hasColumn('message', 'score');
|
|
29
|
+
const hasTraceIdColumn = await knex.schema.hasColumn('message', 'trace_id');
|
|
30
|
+
|
|
31
|
+
if (!hasScoreColumn || !hasTraceIdColumn) {
|
|
32
|
+
await knex.schema.alterTable('message', table => {
|
|
33
|
+
if (!hasScoreColumn) {
|
|
34
|
+
table
|
|
35
|
+
.float('score')
|
|
36
|
+
.nullable()
|
|
37
|
+
.defaultTo(0)
|
|
38
|
+
.comment(
|
|
39
|
+
'User feedback score for the message: 0 = no feedback, 1 = helpful, -1 = not helpful',
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
if (!hasTraceIdColumn) {
|
|
43
|
+
table
|
|
44
|
+
.string('trace_id')
|
|
45
|
+
.nullable()
|
|
46
|
+
.comment(
|
|
47
|
+
'Langfuse trace ID for the message, used for scoring and observability',
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sweetoburrito/backstage-plugin-ai-assistant-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -41,9 +41,10 @@
|
|
|
41
41
|
"@backstage/plugin-signals-node": "backstage:^",
|
|
42
42
|
"@langchain/core": "^0.3.72",
|
|
43
43
|
"@langchain/langgraph": "^0.4.9",
|
|
44
|
+
"@langchain/mcp-adapters": "^1.0.0",
|
|
44
45
|
"@langchain/textsplitters": "^0.1.0",
|
|
45
|
-
"@sweetoburrito/backstage-plugin-ai-assistant-common": "^0.
|
|
46
|
-
"@sweetoburrito/backstage-plugin-ai-assistant-node": "^0.
|
|
46
|
+
"@sweetoburrito/backstage-plugin-ai-assistant-common": "^0.6.0",
|
|
47
|
+
"@sweetoburrito/backstage-plugin-ai-assistant-node": "^0.7.0",
|
|
47
48
|
"express": "^4.17.1",
|
|
48
49
|
"express-promise-router": "^4.1.0",
|
|
49
50
|
"knex": "^3.1.0",
|
|
@@ -59,12 +60,14 @@
|
|
|
59
60
|
"@backstage/plugin-events-backend": "backstage:^",
|
|
60
61
|
"@backstage/plugin-signals-backend": "backstage:^",
|
|
61
62
|
"@backstage/types": "backstage:^",
|
|
63
|
+
"@sweetoburrito/backstage-plugin-ai-assistant-backend-module-callback-provider-langfuse": "workspace:^",
|
|
62
64
|
"@sweetoburrito/backstage-plugin-ai-assistant-backend-module-embeddings-provider-azure-open-ai": "workspace:^",
|
|
63
65
|
"@sweetoburrito/backstage-plugin-ai-assistant-backend-module-embeddings-provider-ollama": "workspace:^",
|
|
64
66
|
"@sweetoburrito/backstage-plugin-ai-assistant-backend-module-ingestor-azure-devops": "workspace:^",
|
|
65
67
|
"@sweetoburrito/backstage-plugin-ai-assistant-backend-module-ingestor-catalog": "workspace:^",
|
|
66
68
|
"@sweetoburrito/backstage-plugin-ai-assistant-backend-module-ingestor-github": "workspace:^",
|
|
67
69
|
"@sweetoburrito/backstage-plugin-ai-assistant-backend-module-model-provider-azure-ai": "workspace:^",
|
|
70
|
+
"@sweetoburrito/backstage-plugin-ai-assistant-backend-module-model-provider-google-vertex-ai": "workspace:^",
|
|
68
71
|
"@sweetoburrito/backstage-plugin-ai-assistant-backend-module-model-provider-ollama": "workspace:^",
|
|
69
72
|
"@sweetoburrito/backstage-plugin-ai-assistant-backend-module-tool-provider-backstage": "workspace:^",
|
|
70
73
|
"@types/express": "^4.0.0",
|