Skip to content

Commit

Permalink
Add better handling of initializing function code prompt according to…
Browse files Browse the repository at this point in the history
… schema
  • Loading branch information
CoenWarmer committed Aug 9, 2023
1 parent 119ffcd commit 24bf9cc
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { useMemo } from 'react';
import { monaco } from '@kbn/monaco';
import { useObservabilityAIAssistant } from './use_observability_ai_assistant';
import { createInitializedObject } from '../utils/create_initialized_object';

const { editor, languages, Uri } = monaco;

Expand Down Expand Up @@ -35,13 +36,7 @@ export const useJsonEditorModel = ({
const initialJsonString = initialJson
? initialJson
: functionDefinition.options.parameters.properties
? Object.keys(functionDefinition.options.parameters.properties).reduce(
(acc, curr, index, arr) => {
const val = `${acc} "${curr}": "",\n`;
return index === arr.length - 1 ? `${val}}` : val;
},
'{\n'
)
? JSON.stringify(createInitializedObject(functionDefinition.options.parameters), null, 4)
: '';

languages.json.jsonDefaults.setDiagnosticsOptions({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { createInitializedObject } from './create_initialized_object';

describe('createInitializedObject', () => {
it('should return an object with properties of type "string" set to a default value of ""', () => {
expect(
createInitializedObject({
type: 'object',
properties: {
foo: {
type: 'string',
},
},
required: ['foo'],
})
).toStrictEqual({ foo: '' });
});

it('should return an object with properties of type "number" set to a default value of 1', () => {
expect(
createInitializedObject({
type: 'object',
properties: {
foo: {
type: 'number',
},
},
required: ['foo'],
})
).toStrictEqual({ foo: 1 });
});

it('should return an object with properties of type "array" set to a default value of []', () => {
expect(
createInitializedObject({
type: 'object',
properties: {
foo: {
type: 'array',
},
},
required: ['foo'],
})
).toStrictEqual({ foo: [] });
});

it('should return an object with default values for properties that are required', () => {
expect(
createInitializedObject({
type: 'object',
properties: {
requiredProperty: {
type: 'string',
},
notRequiredProperty: {
type: 'string',
},
},
required: ['requiredProperty'],
})
).toStrictEqual({ requiredProperty: '' });
});

it('should return an object with nested fields if they are present in the schema', () => {
expect(
createInitializedObject({
type: 'object',
properties: {
foo: {
type: 'object',
properties: {
bar: {
type: 'object',
properties: {
baz: {
type: 'string',
},
},
required: ['baz'],
},
},
required: ['bar'],
},
},
})
).toStrictEqual({ foo: { bar: { baz: '' } } });

expect(
createInitializedObject({
type: 'object',
properties: {
foo: {
type: 'object',
properties: {
bar: {
type: 'string',
},
},
},
},
})
).toStrictEqual({ foo: {} });
});

it('should handle a real life example', () => {
expect(
createInitializedObject({
type: 'object',
properties: {
method: {
type: 'string',
description: 'The HTTP method of the Elasticsearch endpoint',
enum: ['GET', 'PUT', 'POST', 'DELETE', 'PATCH'] as const,
},
path: {
type: 'string',
description: 'The path of the Elasticsearch endpoint, including query parameters',
},
notRequired: {
type: 'string',
description: 'This property is not required.',
},
},
required: ['method', 'path'] as const,
})
).toStrictEqual({ method: '', path: '' });
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { FunctionDefinition } from '../../common/types';

type Params = FunctionDefinition['options']['parameters'];

export function createInitializedObject(parameters: Params) {
const emptyObject: Record<string, string | any> = {};

function traverseProperties({ properties, required }: Params) {
for (const propName in properties) {
if (properties.hasOwnProperty(propName)) {
const prop = properties[propName] as Params;

if (prop.type === 'object') {
emptyObject[propName] = createInitializedObject(prop);
} else if (required?.includes(propName)) {
if (prop.type === 'array') {
emptyObject[propName] = [];
}

if (prop.type === 'number') {
emptyObject[propName] = 1;
}

if (prop.type === 'string') {
emptyObject[propName] = '';
}
}
}
}
}

traverseProperties(parameters);

return emptyObject;
}

0 comments on commit 24bf9cc

Please sign in to comment.