Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ describe('fromEs', () => {
space: 'space',
description: 'description',
labels: ['foo', 'bar'],
configuration: {
avatar_color: 'blue',
avatar_symbol: 'star',
config: {
instructions: 'instructions',
tools: [{ tool_ids: ['id_1', 'id_2'] }],
},
Expand All @@ -35,7 +37,7 @@ describe('fromEs', () => {
};
};

it('converts an agent document to its definition', () => {
it('converts an agent document with new config field to its definition', () => {
const document = getSampleDoc();

const definition = fromEs(document);
Expand All @@ -54,10 +56,42 @@ describe('fromEs', () => {
},
description: 'description',
labels: ['foo', 'bar'],
avatar_color: 'blue',
avatar_symbol: 'star',
});
});

it('handles legacy doc format', () => {
it('converts an agent document with legacy configuration field to its definition', () => {
const document = getSampleDoc();
// @ts-ignore simulating legacy document
delete document._source.config;
document._source!.configuration = {
instructions: 'legacy instructions',
tools: [{ tool_ids: ['legacy_id_1', 'legacy_id_2'] }],
};

const definition = fromEs(document);

expect(definition).toEqual({
type: AgentType.chat,
id: 'id',
name: 'name',
configuration: {
instructions: 'legacy instructions',
tools: [
{
tool_ids: ['legacy_id_1', 'legacy_id_2'],
},
],
},
description: 'description',
labels: ['foo', 'bar'],
avatar_color: 'blue',
avatar_symbol: 'star',
});
});

it('handles legacy doc format without id field', () => {
const document = getSampleDoc();
document._id = '_id';
// @ts-ignore testing edge case
Expand All @@ -70,7 +104,7 @@ describe('fromEs', () => {
});

describe('createRequestToEs', () => {
it('converts a request to the document format', () => {
it('converts a request to the document format using new config field', () => {
const createRequest: AgentCreateRequest = {
id: 'id',
name: 'name',
Expand All @@ -84,6 +118,8 @@ describe('createRequestToEs', () => {
],
},
labels: ['foo', 'bar'],
avatar_color: 'green',
avatar_symbol: 'circle',
};

const date = new Date();
Expand All @@ -100,7 +136,7 @@ describe('createRequestToEs', () => {
name: 'name',
space: 'space-2',
description: 'description',
configuration: {
config: {
instructions: 'instructions',
tools: [
{
Expand All @@ -109,14 +145,16 @@ describe('createRequestToEs', () => {
],
},
labels: ['foo', 'bar'],
avatar_color: 'green',
avatar_symbol: 'circle',
created_at: expect.any(String),
updated_at: expect.any(String),
});
});
});

describe('updateRequestToEs', () => {
it('converts an update request to the document format', () => {
it('migrates legacy document with configuration field to new config field', () => {
const newUpdateDate = new Date();

const agentProps: AgentProperties = {
Expand All @@ -125,6 +163,14 @@ describe('updateRequestToEs', () => {
name: 'name',
description: 'description',
space: 'space',
config: {
instructions: 'instructions',
tools: [
{
tool_ids: ['id_1', 'id_2'],
},
],
},
configuration: {
instructions: 'instructions',
tools: [
Expand All @@ -134,6 +180,8 @@ describe('updateRequestToEs', () => {
],
},
labels: ['foo', 'bar'],
avatar_color: 'red',
avatar_symbol: 'triangle',
created_at: creationDate,
updated_at: updateDate,
};
Expand All @@ -152,13 +200,14 @@ describe('updateRequestToEs', () => {
updateDate: newUpdateDate,
});

// Should use config field and omit configuration
expect(docProperties).toEqual({
id: 'id',
type: AgentType.chat,
space: 'space',
name: 'new name',
description: 'description',
configuration: {
config: {
instructions: 'instructions',
tools: [
{
Expand All @@ -167,8 +216,74 @@ describe('updateRequestToEs', () => {
],
},
labels: ['foo', 'bar'],
avatar_color: 'red',
avatar_symbol: 'triangle',
created_at: creationDate,
updated_at: newUpdateDate.toISOString(),
});
// Verify configuration is not present
expect(docProperties.configuration).toBeUndefined();
});

it('updates document with new config field and keeps using config', () => {
const newUpdateDate = new Date();

const agentProps: AgentProperties = {
id: 'id',
type: AgentType.chat,
name: 'name',
description: 'description',
space: 'space',
config: {
instructions: 'instructions',
tools: [
{
tool_ids: ['id_1', 'id_2'],
},
],
},
labels: ['foo', 'bar'],
avatar_color: 'yellow',
avatar_symbol: 'square',
created_at: creationDate,
updated_at: updateDate,
};

const updateRequest: AgentUpdateRequest = {
name: 'new name',
description: 'new description',
configuration: {
instructions: 'new instructions',
},
};

const docProperties = updateRequestToEs({
agentId: 'id',
currentProps: agentProps,
update: updateRequest,
updateDate: newUpdateDate,
});

expect(docProperties).toEqual({
id: 'id',
type: AgentType.chat,
space: 'space',
name: 'new name',
description: 'new description',
config: {
instructions: 'new instructions',
tools: [
{
tool_ids: ['id_1', 'id_2'],
},
],
},
labels: ['foo', 'bar'],
avatar_color: 'yellow',
avatar_symbol: 'square',
created_at: creationDate,
updated_at: newUpdateDate.toISOString(),
});
expect(docProperties.configuration).toBeUndefined();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import type { GetResponse } from '@elastic/elasticsearch/lib/api/types';
import { AgentType } from '@kbn/onechat-common';
import type { AgentCreateRequest, AgentUpdateRequest } from '../../../../../common/agents';
import type { AgentProperties } from './storage';
import type { AgentProperties, AgentConfigurationProperties } from './storage';
import type { PersistedAgentDefinition } from '../types';

export type Document = Pick<GetResponse<AgentProperties>, '_id' | '_source'>;
Expand All @@ -20,6 +20,9 @@ export const fromEs = (document: Document): PersistedAgentDefinition => {
throw new Error('No source found on get conversation response');
}

const configuration: AgentConfigurationProperties =
document._source.configuration ?? document._source.config;

return {
// backward compatibility with M1 - we check the document id.
id: document._source.id ?? document._id,
Expand All @@ -30,8 +33,8 @@ export const fromEs = (document: Document): PersistedAgentDefinition => {
avatar_color: document._source.avatar_color,
avatar_symbol: document._source.avatar_symbol,
configuration: {
instructions: document._source.configuration.instructions,
tools: document._source.configuration.tools,
instructions: configuration.instructions,
tools: configuration.tools,
},
};
};
Expand All @@ -54,7 +57,7 @@ export const createRequestToEs = ({
labels: profile.labels,
avatar_color: profile.avatar_color,
avatar_symbol: profile.avatar_symbol,
configuration: {
config: {
instructions: profile.configuration.instructions,
tools: profile.configuration.tools,
},
Expand All @@ -74,12 +77,16 @@ export const updateRequestToEs = ({
update: AgentUpdateRequest;
updateDate: Date;
}): AgentProperties => {
const currentConfig = currentProps.configuration ?? currentProps.config;

const updated: AgentProperties = {
...currentProps,
...update,
id: agentId,
configuration: {
...currentProps.configuration,
// Explicitly omit configuration to ensure migration
configuration: undefined,
config: {
...currentConfig,
...update.configuration,
},
updated_at: updateDate.toISOString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const storageSettings = {
labels: types.keyword({}),
avatar_color: types.keyword({}),
avatar_symbol: types.keyword({}),
configuration: types.object({ dynamic: true }),
config: types.object({ properties: {}, dynamic: false }),
created_at: types.date({}),
updated_at: types.date({}),
},
Expand All @@ -41,12 +41,16 @@ export interface AgentProperties {
labels?: string[];
avatar_color?: string;
avatar_symbol?: string;
configuration: {
instructions?: string;
tools: ToolSelection[];
};
config: AgentConfigurationProperties;
created_at: string;
updated_at: string;
// deprecated fields
configuration?: AgentConfigurationProperties;
}

export interface AgentConfigurationProperties {
instructions?: string;
tools: ToolSelection[];
}

export type AgentProfileStorageSettings = typeof storageSettings;
Expand Down
Loading