Skip to content

Commit

Permalink
[8.x] [Obs AI Assistant] unskip kb user instructions test in serverle…
Browse files Browse the repository at this point in the history
…ss (#205519) (#205564)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Obs AI Assistant] unskip kb user instructions test in serverless
(#205519)](#205519)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Sandra
G","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-01-04T21:32:32Z","message":"[Obs
AI Assistant] unskip kb user instructions test in serverless
(#205519)\n\n## Summary\r\nResolves
https://github.com/elastic/kibana/issues/192886\r\n\r\n- Unskips
`knowledge_base_user_instructions.spec.ts` in serverless\r\n - stays
skipped in mki due to proxy usage issue\r\n - Duplicates new changes
from non serverless\r\n- Removes `skipInMKI` tags
for:\r\n`knowledge_base_setup.spec.ts`\r\n`knowledge_base.spec.ts
`\r\n`knowledge_base_status.spec.ts`\r\n\r\n\r\nIf
#192718 is merged
before\r\nthis, I will move `knowledge_base_user_instructions.spec.ts`
to\r\ndeployment agnostic. Otherwise It can be done in that PR or
another.","sha":"b17b10eea1aa465a4291ce716dba473eb9195cb1","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:prev-minor","Team:Obs
AI Assistant"],"title":"[Obs AI Assistant] unskip kb user instructions
test in
serverless","number":205519,"url":"https://github.com/elastic/kibana/pull/205519","mergeCommit":{"message":"[Obs
AI Assistant] unskip kb user instructions test in serverless
(#205519)\n\n## Summary\r\nResolves
https://github.com/elastic/kibana/issues/192886\r\n\r\n- Unskips
`knowledge_base_user_instructions.spec.ts` in serverless\r\n - stays
skipped in mki due to proxy usage issue\r\n - Duplicates new changes
from non serverless\r\n- Removes `skipInMKI` tags
for:\r\n`knowledge_base_setup.spec.ts`\r\n`knowledge_base.spec.ts
`\r\n`knowledge_base_status.spec.ts`\r\n\r\n\r\nIf
#192718 is merged
before\r\nthis, I will move `knowledge_base_user_instructions.spec.ts`
to\r\ndeployment agnostic. Otherwise It can be done in that PR or
another.","sha":"b17b10eea1aa465a4291ce716dba473eb9195cb1"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/205519","number":205519,"mergeCommit":{"message":"[Obs
AI Assistant] unskip kb user instructions test in serverless
(#205519)\n\n## Summary\r\nResolves
https://github.com/elastic/kibana/issues/192886\r\n\r\n- Unskips
`knowledge_base_user_instructions.spec.ts` in serverless\r\n - stays
skipped in mki due to proxy usage issue\r\n - Duplicates new changes
from non serverless\r\n- Removes `skipInMKI` tags
for:\r\n`knowledge_base_setup.spec.ts`\r\n`knowledge_base.spec.ts
`\r\n`knowledge_base_status.spec.ts`\r\n\r\n\r\nIf
#192718 is merged
before\r\nthis, I will move `knowledge_base_user_instructions.spec.ts`
to\r\ndeployment agnostic. Otherwise It can be done in that PR or
another.","sha":"b17b10eea1aa465a4291ce716dba473eb9195cb1"}}]}]
BACKPORT-->

Co-authored-by: Sandra G <[email protected]>
  • Loading branch information
kibanamachine and neptunian authored Jan 4, 2025
1 parent 2c7c1c7 commit 3881274
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ export default function ApiTest({ getService }: FtrProviderContext) {
const observabilityAIAssistantAPIClient = getService('observabilityAIAssistantAPIClient');

describe('Knowledge base', function () {
// TODO: https://github.com/elastic/kibana/issues/192886 kb/setup error
this.tags(['skipMKI']);
before(async () => {
await createKnowledgeBaseModel(ml);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ export default function ApiTest({ getService }: FtrProviderContext) {
const observabilityAIAssistantAPIClient = getService('observabilityAIAssistantAPIClient');

describe('/internal/observability_ai_assistant/kb/setup', function () {
// TODO: https://github.com/elastic/kibana/issues/192886 kb/setup error
this.tags(['skipMKI']);

before(async () => {
await deleteKnowledgeBaseModel(ml).catch(() => {});
await deleteInferenceEndpoint({ es }).catch(() => {});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ export default function ApiTest({ getService }: FtrProviderContext) {
const observabilityAIAssistantAPIClient = getService('observabilityAIAssistantAPIClient');

describe('/internal/observability_ai_assistant/kb/status', function () {
this.tags(['skipMKI']);

before(async () => {
await createKnowledgeBaseModel(ml);
await observabilityAIAssistantAPIClient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import expect from '@kbn/expect';
import { sortBy } from 'lodash';
import { Message, MessageRole } from '@kbn/observability-ai-assistant-plugin/common';
import { CONTEXT_FUNCTION_NAME } from '@kbn/observability-ai-assistant-plugin/server/functions/context';
import { Instruction } from '@kbn/observability-ai-assistant-plugin/common/types';
import {
clearConversations,
clearKnowledgeBase,
createKnowledgeBaseModel,
deleteInferenceEndpoint,
deleteKnowledgeBaseModel,
TINY_ELSER,
} from '@kbn/test-suites-xpack/observability_ai_assistant_api_integration/tests/knowledge_base/helpers';
import { getConversationCreatedEvent } from '@kbn/test-suites-xpack/observability_ai_assistant_api_integration/tests/conversations/helpers';
import {
Expand All @@ -33,8 +35,10 @@ export default function ApiTest({ getService }: FtrProviderContext) {
const log = getService('log');
const svlUserManager = getService('svlUserManager');
const svlCommonApi = getService('svlCommonApi');
const retry = getService('retry');

describe.skip('Knowledge base user instructions', function () {
describe('Knowledge base user instructions', function () {
// TODO: https://github.com/elastic/kibana/issues/192751
this.tags(['skipMKI']);
let editorRoleAuthc: RoleCredentials;
let internalReqHeader: InternalRequestHeader;
Expand All @@ -45,8 +49,13 @@ export default function ApiTest({ getService }: FtrProviderContext) {
await createKnowledgeBaseModel(ml);

await observabilityAIAssistantAPIClient
.slsEditor({
.slsAdmin({
endpoint: 'POST /internal/observability_ai_assistant/kb/setup',
params: {
query: {
model_id: TINY_ELSER.id,
},
},
})
.expect(200);
});
Expand All @@ -64,10 +73,22 @@ export default function ApiTest({ getService }: FtrProviderContext) {
await clearKnowledgeBase(es);

const promises = [
{ username: 'editor', isPublic: true },
{ username: 'editor', isPublic: false },
{ username: 'john', isPublic: true },
{ username: 'john', isPublic: false },
{
username: 'editor' as const,
isPublic: true,
},
{
username: 'editor' as const,
isPublic: false,
},
{
username: 'secondary_editor' as const,
isPublic: true,
},
{
username: 'secondary_editor' as const,
isPublic: false,
},
].map(async ({ username, isPublic }) => {
const visibility = isPublic ? 'Public' : 'Private';
const user = username === 'editor' ? 'slsEditor' : 'slsAdmin';
Expand All @@ -88,61 +109,69 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});

it('"editor" can retrieve their own private instructions and the public instruction', async () => {
const res = await observabilityAIAssistantAPIClient.slsEditor({
endpoint: 'GET /internal/observability_ai_assistant/kb/user_instructions',
await retry.try(async () => {
const res = await observabilityAIAssistantAPIClient.slsEditor({
endpoint: 'GET /internal/observability_ai_assistant/kb/user_instructions',
});

const instructions = res.body.userInstructions;
// TODO: gets 4 in serverless, bufferFlush event?
expect(instructions).to.have.length(3);

const sortById = (data: Array<Instruction & { public?: boolean }>) => sortBy(data, 'id');
expect(sortById(instructions)).to.eql(
sortById([
{
id: 'private-doc-from-editor',
public: false,
text: 'Private user instruction from "editor"',
},
{
id: 'public-doc-from-editor',
public: true,
text: 'Public user instruction from "editor"',
},
{
id: 'public-doc-from-secondary_editor',
public: true,
text: 'Public user instruction from "secondary_editor"',
},
])
);
});

const instructions = res.body.userInstructions;

const sortByDocId = (data: any) => sortBy(data, 'doc_id');
expect(sortByDocId(instructions)).to.eql(
sortByDocId([
{
doc_id: 'private-doc-from-editor',
public: false,
text: 'Private user instruction from "editor"',
},
{
doc_id: 'public-doc-from-editor',
public: true,
text: 'Public user instruction from "editor"',
},
{
doc_id: 'public-doc-from-john',
public: true,
text: 'Public user instruction from "john"',
},
])
);
});

it('"john" can retrieve their own private instructions and the public instruction', async () => {
const res = await observabilityAIAssistantAPIClient.slsAdmin({
endpoint: 'GET /internal/observability_ai_assistant/kb/user_instructions',
});
it('"secondaryEditor" can retrieve their own private instructions and the public instruction', async () => {
await retry.try(async () => {
const res = await observabilityAIAssistantAPIClient.slsAdmin({
endpoint: 'GET /internal/observability_ai_assistant/kb/user_instructions',
});

const instructions = res.body.userInstructions;
const instructions = res.body.userInstructions;
expect(instructions).to.have.length(3);

const sortByDocId = (data: any) => sortBy(data, 'doc_id');
expect(sortByDocId(instructions)).to.eql(
sortByDocId([
{
doc_id: 'public-doc-from-editor',
public: true,
text: 'Public user instruction from "editor"',
},
{
doc_id: 'public-doc-from-john',
public: true,
text: 'Public user instruction from "john"',
},
{
doc_id: 'private-doc-from-john',
public: false,
text: 'Private user instruction from "john"',
},
])
);
const sortById = (data: Array<Instruction & { public?: boolean }>) => sortBy(data, 'id');

expect(sortById(instructions)).to.eql(
sortById([
{
id: 'public-doc-from-editor',
public: true,
text: 'Public user instruction from "editor"',
},
{
id: 'public-doc-from-secondary_editor',
public: true,
text: 'Public user instruction from "secondary_editor"',
},
{
id: 'private-doc-from-secondary_editor',
public: false,
text: 'Private user instruction from "secondary_editor"',
},
])
);
});
});
});

Expand Down Expand Up @@ -186,7 +215,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {

expect(instructions).to.eql([
{
doc_id: 'doc-to-update',
id: 'doc-to-update',
text: 'Updated text',
public: false,
},
Expand Down Expand Up @@ -330,6 +359,37 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});

describe('Instructions can be saved and cleared again', () => {
async function updateInstruction(text: string) {
await observabilityAIAssistantAPIClient
.slsEditor({
endpoint: 'PUT /internal/observability_ai_assistant/kb/user_instructions',
params: {
body: {
id: 'my-instruction-that-will-be-cleared',
text,
public: false,
},
},
})
.expect(200);

const res = await observabilityAIAssistantAPIClient
.slsEditor({ endpoint: 'GET /internal/observability_ai_assistant/kb/user_instructions' })
.expect(200);

return res.body.userInstructions[0].text;
}

it('can clear the instruction', async () => {
const res1 = await updateInstruction('This is a user instruction that will be cleared');
expect(res1).to.be('This is a user instruction that will be cleared');

const res2 = await updateInstruction('');
expect(res2).to.be('');
});
});

describe('security roles and access privileges', () => {
describe('should deny access for users without the ai_assistant privilege', () => {
it('PUT /internal/observability_ai_assistant/kb/user_instructions', async () => {
Expand Down

0 comments on commit 3881274

Please sign in to comment.