Skip to content

Commit 41a47a2

Browse files
arturoliduenakibanamachineneptunianviduni94
authored
[9.2] [Obs AI Assistant] aware of new .integration_knowledge* system index (#237085) (#239263)
Closes elastic/obs-ai-team#380 # Backport This will backport the following commits from `main` to `9.2`: - [[Obs AI Assistant] aware of new .integration_knowledge* system index (#237085)](#237085) <!--- Backport version: 10.0.2 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Arturo Lidueña","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-10-14T07:13:31Z","message":"[Obs AI Assistant] aware of new .integration_knowledge* system index (#237085)\n\nCloses https://github.com/elastic/obs-ai-assistant-team/issues/357\n## Summary\n\nThis PR adds the awareness of `.integration_knowledge*` index as another\nindex for recalling. The Obs AI Assistant will retrieve integration\nknowledge from the index\n\nValue added to the Obs AI Assistant\n(https://github.com/elastic/obs-ai-assistant-team/issues/357#issuecomment-3303692842):\n> The assistant will become aware of LLM-facing documentation for any\ninstalled integrations in the user's cluster. For example, the Logstash\nintegration might ship documentation that explains how to understand the\nhealth reporting metrics collected by the integration and the assistant\ncould answer prompts like \"why was my logstash server down yesterday?\"\nusing the user's real data.\n\nManual Testing: \n1 -> Follow the instructions from\nhttps://github.com//pull/230107#issue-3281157774:\n\n> 1. If elastic/elasticsearch#132506 has been\nmerged, run `yarn es snapshot` in Kibana, otherwise, checkout that\nbranch in your local ES and then in kibana run `yarn es source` in order\nto use that version of ES which contains the index management, mappings,\netc.\n>2. Install a package with any number of knowledge base docs in the\n`docs/knowledge_base` folder. You can use [this sample\npackage](https://github.com/user-attachments/files/21867395/masonstestpackage-0.0.1.zip),\nor create your own following the guide below:\n>\n> - Using `elastic-package`, create a new package using `elastic-package\ncreate integration`\n- Once created add `knowledge_base` as a folder inside of the generated\n`docs` folder of the integration\n- Add an arbitrary amount of `.md` files to the knowledge_base folder\n - Run `elastic-package build` to build the package\n- There are a lot of different options for installing the package in a\nlocal kibana instance. I prefer to just take the generated .zip folder\nfrom `/build` in `elastic-package` and upload it to kibana using the\ncustom integrations feature. You can also expose the package registry,\nor whatever you see fit.\n>3. Watch the Kibana logs for errors/debug messages etc\n>4. Use the new endpoint or just directly check the index using `GET\n/.integration_knowledge/_search` to verify that the documents are\ningested into the system index of `.integration_knowledge`\n>5. Update the package and verify that the KB documents are updated by\nchecking the response again, they should have the updated pkgVersion on\nthe associated docs.\n>6. Remove the package and then verify (using the endpoint) that the\ndocs are removed from the index\n\n2 - Ask the AI Assistant about information contained in the integration\ndocuments\n\n3- check that the documents are listed on the response of executed the\nfunction context inside learnings\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [ ]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [ ] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [ ] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [ ] This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.\n- [ ] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [ ] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [ ] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.\n\n### Identify risks\n\nDoes this PR introduce any risks? For example, consider risks like hard\nto test bugs, performance regression, potential of data loss.\n\nDescribe the risk, its severity, and mitigation for each identified\nrisk. Invite stakeholders and evaluate how to proceed before merging.\n\n- [ ] [See some risk\nexamples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx)\n- [ ] ...\n\n---------\n\nCo-authored-by: kibanamachine <[email protected]>\nCo-authored-by: Sandra G <[email protected]>","sha":"15878ad8a124539d4698de2510fd5d6ad90b8d38","branchLabelMapping":{"^v9.3.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:enhancement","backport:skip","Team:Obs AI Assistant","ci:project-deploy-observability","v9.3.0"],"title":"[Obs AI Assistant] aware of new .integration_knowledge* system index","number":237085,"url":"https://github.com/elastic/kibana/pull/237085","mergeCommit":{"message":"[Obs AI Assistant] aware of new .integration_knowledge* system index (#237085)\n\nCloses https://github.com/elastic/obs-ai-assistant-team/issues/357\n## Summary\n\nThis PR adds the awareness of `.integration_knowledge*` index as another\nindex for recalling. The Obs AI Assistant will retrieve integration\nknowledge from the index\n\nValue added to the Obs AI Assistant\n(https://github.com/elastic/obs-ai-assistant-team/issues/357#issuecomment-3303692842):\n> The assistant will become aware of LLM-facing documentation for any\ninstalled integrations in the user's cluster. For example, the Logstash\nintegration might ship documentation that explains how to understand the\nhealth reporting metrics collected by the integration and the assistant\ncould answer prompts like \"why was my logstash server down yesterday?\"\nusing the user's real data.\n\nManual Testing: \n1 -> Follow the instructions from\nhttps://github.com//pull/230107#issue-3281157774:\n\n> 1. If elastic/elasticsearch#132506 has been\nmerged, run `yarn es snapshot` in Kibana, otherwise, checkout that\nbranch in your local ES and then in kibana run `yarn es source` in order\nto use that version of ES which contains the index management, mappings,\netc.\n>2. Install a package with any number of knowledge base docs in the\n`docs/knowledge_base` folder. You can use [this sample\npackage](https://github.com/user-attachments/files/21867395/masonstestpackage-0.0.1.zip),\nor create your own following the guide below:\n>\n> - Using `elastic-package`, create a new package using `elastic-package\ncreate integration`\n- Once created add `knowledge_base` as a folder inside of the generated\n`docs` folder of the integration\n- Add an arbitrary amount of `.md` files to the knowledge_base folder\n - Run `elastic-package build` to build the package\n- There are a lot of different options for installing the package in a\nlocal kibana instance. I prefer to just take the generated .zip folder\nfrom `/build` in `elastic-package` and upload it to kibana using the\ncustom integrations feature. You can also expose the package registry,\nor whatever you see fit.\n>3. Watch the Kibana logs for errors/debug messages etc\n>4. Use the new endpoint or just directly check the index using `GET\n/.integration_knowledge/_search` to verify that the documents are\ningested into the system index of `.integration_knowledge`\n>5. Update the package and verify that the KB documents are updated by\nchecking the response again, they should have the updated pkgVersion on\nthe associated docs.\n>6. Remove the package and then verify (using the endpoint) that the\ndocs are removed from the index\n\n2 - Ask the AI Assistant about information contained in the integration\ndocuments\n\n3- check that the documents are listed on the response of executed the\nfunction context inside learnings\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [ ]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [ ] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [ ] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [ ] This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.\n- [ ] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [ ] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [ ] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.\n\n### Identify risks\n\nDoes this PR introduce any risks? For example, consider risks like hard\nto test bugs, performance regression, potential of data loss.\n\nDescribe the risk, its severity, and mitigation for each identified\nrisk. Invite stakeholders and evaluate how to proceed before merging.\n\n- [ ] [See some risk\nexamples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx)\n- [ ] ...\n\n---------\n\nCo-authored-by: kibanamachine <[email protected]>\nCo-authored-by: Sandra G <[email protected]>","sha":"15878ad8a124539d4698de2510fd5d6ad90b8d38"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.3.0","branchLabelMappingKey":"^v9.3.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/237085","number":237085,"mergeCommit":{"message":"[Obs AI Assistant] aware of new .integration_knowledge* system index (#237085)\n\nCloses https://github.com/elastic/obs-ai-assistant-team/issues/357\n## Summary\n\nThis PR adds the awareness of `.integration_knowledge*` index as another\nindex for recalling. The Obs AI Assistant will retrieve integration\nknowledge from the index\n\nValue added to the Obs AI Assistant\n(https://github.com/elastic/obs-ai-assistant-team/issues/357#issuecomment-3303692842):\n> The assistant will become aware of LLM-facing documentation for any\ninstalled integrations in the user's cluster. For example, the Logstash\nintegration might ship documentation that explains how to understand the\nhealth reporting metrics collected by the integration and the assistant\ncould answer prompts like \"why was my logstash server down yesterday?\"\nusing the user's real data.\n\nManual Testing: \n1 -> Follow the instructions from\nhttps://github.com//pull/230107#issue-3281157774:\n\n> 1. If elastic/elasticsearch#132506 has been\nmerged, run `yarn es snapshot` in Kibana, otherwise, checkout that\nbranch in your local ES and then in kibana run `yarn es source` in order\nto use that version of ES which contains the index management, mappings,\netc.\n>2. Install a package with any number of knowledge base docs in the\n`docs/knowledge_base` folder. You can use [this sample\npackage](https://github.com/user-attachments/files/21867395/masonstestpackage-0.0.1.zip),\nor create your own following the guide below:\n>\n> - Using `elastic-package`, create a new package using `elastic-package\ncreate integration`\n- Once created add `knowledge_base` as a folder inside of the generated\n`docs` folder of the integration\n- Add an arbitrary amount of `.md` files to the knowledge_base folder\n - Run `elastic-package build` to build the package\n- There are a lot of different options for installing the package in a\nlocal kibana instance. I prefer to just take the generated .zip folder\nfrom `/build` in `elastic-package` and upload it to kibana using the\ncustom integrations feature. You can also expose the package registry,\nor whatever you see fit.\n>3. Watch the Kibana logs for errors/debug messages etc\n>4. Use the new endpoint or just directly check the index using `GET\n/.integration_knowledge/_search` to verify that the documents are\ningested into the system index of `.integration_knowledge`\n>5. Update the package and verify that the KB documents are updated by\nchecking the response again, they should have the updated pkgVersion on\nthe associated docs.\n>6. Remove the package and then verify (using the endpoint) that the\ndocs are removed from the index\n\n2 - Ask the AI Assistant about information contained in the integration\ndocuments\n\n3- check that the documents are listed on the response of executed the\nfunction context inside learnings\n\n### Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [ ] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [ ]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [ ] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [ ] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [ ] This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.\n- [ ] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [ ] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [ ] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.\n\n### Identify risks\n\nDoes this PR introduce any risks? For example, consider risks like hard\nto test bugs, performance regression, potential of data loss.\n\nDescribe the risk, its severity, and mitigation for each identified\nrisk. Invite stakeholders and evaluate how to proceed before merging.\n\n- [ ] [See some risk\nexamples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx)\n- [ ] ...\n\n---------\n\nCo-authored-by: kibanamachine <[email protected]>\nCo-authored-by: Sandra G <[email protected]>","sha":"15878ad8a124539d4698de2510fd5d6ad90b8d38"}}]}] BACKPORT--> --------- Co-authored-by: kibanamachine <[email protected]> Co-authored-by: Sandra G <[email protected]> Co-authored-by: Viduni Wickramarachchi <[email protected]>
1 parent 0753e91 commit 41a47a2

File tree

2 files changed

+114
-26
lines changed
  • x-pack/platform/plugins/shared/observability_ai_assistant

2 files changed

+114
-26
lines changed

x-pack/platform/plugins/shared/observability_ai_assistant/common/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,12 @@ export enum ConversationAccess {
205205
SHARED = 'shared',
206206
PRIVATE = 'private',
207207
}
208+
209+
export interface IntegrationKnowledgeBaseEntry {
210+
content: string;
211+
package_name: string;
212+
filename: string;
213+
version: string;
214+
path: string;
215+
installed_at: string;
216+
}

x-pack/platform/plugins/shared/observability_ai_assistant/server/service/knowledge_base_service/index.ts

Lines changed: 105 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ import { encode } from 'gpt-tokenizer';
1313
import { isLockAcquisitionError } from '@kbn/lock-manager';
1414
import type { DocumentationManagerAPI } from '@kbn/product-doc-base-plugin/server/services/doc_manager';
1515
import { resourceNames } from '..';
16-
import type { Instruction, KnowledgeBaseEntry } from '../../../common/types';
16+
import type {
17+
Instruction,
18+
IntegrationKnowledgeBaseEntry,
19+
KnowledgeBaseEntry,
20+
} from '../../../common/types';
1721
import { KnowledgeBaseEntryRole, KnowledgeBaseType } from '../../../common/types';
1822
import { getAccessQuery, getUserAccessFilters } from '../util/get_access_query';
1923
import { getCategoryQuery } from '../util/get_category_query';
@@ -36,6 +40,8 @@ import { getInferenceIdFromWriteIndex } from './get_inference_id_from_write_inde
3640
import { createOrUpdateKnowledgeBaseIndexAssets } from '../index_assets/create_or_update_knowledge_base_index_assets';
3741
import { LEGACY_CUSTOM_INFERENCE_ID } from '../../../common/preconfigured_inference_ids';
3842

43+
const INTEGRATION_KNOWLEDGE_INDEX = '.integration_knowledge';
44+
3945
interface Dependencies {
4046
core: CoreSetup<ObservabilityAIAssistantPluginStartDependencies>;
4147
esClient: {
@@ -112,6 +118,64 @@ export class KnowledgeBaseService {
112118
}));
113119
}
114120

121+
private async recallFromIntegrationsKnowledge({
122+
queries,
123+
esClient,
124+
}: {
125+
queries: Array<{ text: string; boost?: number }>;
126+
esClient: { asCurrentUser: ElasticsearchClient; asInternalUser: ElasticsearchClient };
127+
}): Promise<RecalledEntry[]> {
128+
// Check if the .integration_knowledge index exists before searching for documents
129+
// This has to be done with `.search` since `.exists` and `.get` can't be performed
130+
// with the internal system user (lack of permissions)
131+
try {
132+
await esClient.asInternalUser.search({
133+
index: INTEGRATION_KNOWLEDGE_INDEX,
134+
size: 0,
135+
});
136+
} catch (error) {
137+
// If there's an error checking the index existence, assume it doesn't exist and don't attempt to recall
138+
this.dependencies.logger.debug(
139+
`Failed to access the index: "${INTEGRATION_KNOWLEDGE_INDEX}". Skipping integration knowledge recall.`
140+
);
141+
this.dependencies.logger.debug(error);
142+
return [];
143+
}
144+
145+
try {
146+
// Search the .integration_knowledge index using semantic search on the content field
147+
const response = await esClient.asInternalUser.search<IntegrationKnowledgeBaseEntry>({
148+
index: INTEGRATION_KNOWLEDGE_INDEX,
149+
query: {
150+
bool: {
151+
should: queries.map(({ text, boost = 1 }) => ({
152+
semantic: {
153+
field: 'content',
154+
query: text,
155+
boost,
156+
},
157+
})),
158+
},
159+
},
160+
size: 10,
161+
_source: ['package_name', 'filename', 'content', 'version'],
162+
});
163+
return response.hits.hits.map((hit) => ({
164+
text: hit._source?.content!,
165+
labels: { filename: hit._source?.filename ?? '', version: hit._source?.version ?? '' },
166+
title: hit._source?.package_name,
167+
esScore: hit._score!,
168+
id: hit._id!,
169+
}));
170+
} catch (error) {
171+
this.dependencies.logger.error(
172+
`Error recalling from index "${INTEGRATION_KNOWLEDGE_INDEX}": ${error?.message}`
173+
);
174+
this.dependencies.logger.debug(error);
175+
return [];
176+
}
177+
}
178+
115179
recall = async ({
116180
user,
117181
queries,
@@ -137,40 +201,55 @@ export class KnowledgeBaseService {
137201
() => `Recalling entries from KB for queries: "${JSON.stringify(queries)}"`
138202
);
139203

140-
const [documentsFromKb, documentsFromConnectors] = await Promise.all([
141-
this.recallFromKnowledgeBase({
142-
user,
143-
queries,
144-
categories,
145-
namespace,
146-
}).catch((error) => {
147-
if (isInferenceEndpointMissingOrUnavailable(error)) {
148-
throwKnowledgeBaseNotReady(error);
149-
}
150-
throw error;
151-
}),
152-
recallFromSearchConnectors({
153-
esClient,
154-
uiSettingsClient,
155-
queries,
156-
core: this.dependencies.core,
157-
logger: this.dependencies.logger,
158-
}).catch((error) => {
159-
this.dependencies.logger.error('Error getting data from search indices');
160-
this.dependencies.logger.debug(error);
161-
return [];
162-
}),
163-
]);
204+
const [documentsFromKb, documentsFromConnectors, documentsFromIntegrations] = await Promise.all(
205+
[
206+
this.recallFromKnowledgeBase({
207+
user,
208+
queries,
209+
categories,
210+
namespace,
211+
}).catch((error) => {
212+
if (isInferenceEndpointMissingOrUnavailable(error)) {
213+
throwKnowledgeBaseNotReady(error);
214+
}
215+
throw error;
216+
}),
217+
recallFromSearchConnectors({
218+
esClient,
219+
uiSettingsClient,
220+
queries,
221+
core: this.dependencies.core,
222+
logger: this.dependencies.logger,
223+
}).catch((error) => {
224+
this.dependencies.logger.error('Error getting data from search indices');
225+
this.dependencies.logger.debug(error);
226+
return [];
227+
}),
228+
this.recallFromIntegrationsKnowledge({
229+
esClient,
230+
queries,
231+
}).catch((error) => {
232+
this.dependencies.logger.error(
233+
`Error getting data from ${INTEGRATION_KNOWLEDGE_INDEX} index`
234+
);
235+
this.dependencies.logger.debug(error);
236+
return [];
237+
}),
238+
]
239+
);
164240

165241
this.dependencies.logger.debug(
166242
`documentsFromKb: ${JSON.stringify(documentsFromKb.slice(0, 5), null, 2)}`
167243
);
168244
this.dependencies.logger.debug(
169245
`documentsFromConnectors: ${JSON.stringify(documentsFromConnectors.slice(0, 5), null, 2)}`
170246
);
247+
this.dependencies.logger.debug(
248+
`documentsFromIntegrations: ${JSON.stringify(documentsFromIntegrations.slice(0, 5), null, 2)}`
249+
);
171250

172251
const sortedEntries = orderBy(
173-
documentsFromKb.concat(documentsFromConnectors),
252+
[...documentsFromKb, ...documentsFromConnectors, ...documentsFromIntegrations],
174253
'esScore',
175254
'desc'
176255
).slice(0, limit.size ?? 20);

0 commit comments

Comments
 (0)