Skip to content

Commit a02f6f7

Browse files
committed
Add chat settings API
1 parent efdd70c commit a02f6f7

File tree

5 files changed

+243
-0
lines changed

5 files changed

+243
-0
lines changed

src/indexes.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ import type {
5050
PrefixSearch,
5151
RecordAny,
5252
EnqueuedTaskPromise,
53+
ChatSettings,
54+
ChatSettingsPayload,
5355
} from "./types/index.js";
5456
import { HttpRequests } from "./http-requests.js";
5557
import {
@@ -1377,4 +1379,32 @@ export class Index<T extends RecordAny = RecordAny> {
13771379
path: `indexes/${this.uid}/settings/prefix-search`,
13781380
});
13791381
}
1382+
1383+
///
1384+
/// CHAT SETTINGS
1385+
///
1386+
1387+
/**
1388+
* Get the index's chat settings.
1389+
*
1390+
* @returns Promise containing a ChatSettings object
1391+
*/
1392+
async getChat(): Promise<ChatSettings> {
1393+
return await this.httpRequest.get<ChatSettings>({
1394+
path: `indexes/${this.uid}/settings/chat`,
1395+
});
1396+
}
1397+
1398+
/**
1399+
* Update the index's chat settings.
1400+
*
1401+
* @param chatSettings - ChatSettings object
1402+
* @returns Promise containing an EnqueuedTask
1403+
*/
1404+
updateChat(chatSettings: ChatSettingsPayload): EnqueuedTaskPromise {
1405+
return this.#httpRequestsWithTask.put({
1406+
path: `indexes/${this.uid}/settings/chat`,
1407+
body: chatSettings,
1408+
});
1409+
}
13801410
}

src/types/types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,20 @@ export type ChatCompletionRequest = {
726726
stream: boolean;
727727
};
728728

729+
export type ChatSettings = {
730+
description: string;
731+
documentTemplate: string;
732+
documentTemplateMaxBytes: number;
733+
searchParameters: SearchParams;
734+
};
735+
736+
export type ChatSettingsPayload = {
737+
description?: string;
738+
documentTemplate?: string;
739+
documentTemplateMaxBytes?: number;
740+
searchParameters?: Partial<SearchParams>;
741+
};
742+
729743
/*
730744
** Keys
731745
*/
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`Test on chat settings > Admin key: Get an index chat settings 1`] = `
4+
{
5+
"description": "",
6+
"documentTemplate": "{% for field in fields %}{% if field.is_searchable and field.value != nil %}{{ field.name }}: {{ field.value }}
7+
{% endif %}{% endfor %}",
8+
"documentTemplateMaxBytes": 400,
9+
"searchParameters": {},
10+
}
11+
`;
12+
13+
exports[`Test on chat settings > Admin key: Get default chat settings on index 1`] = `
14+
{
15+
"description": "",
16+
"documentTemplate": "{% for field in fields %}{% if field.is_searchable and field.value != nil %}{{ field.name }}: {{ field.value }}
17+
{% endif %}{% endfor %}",
18+
"documentTemplateMaxBytes": 400,
19+
"searchParameters": {},
20+
}
21+
`;
22+
23+
exports[`Test on chat settings > Admin key: Update chat settings with all properties 1`] = `
24+
{
25+
"description": "A comprehensive movie database containing titles, overviews, genres, and release dates to help users find movies",
26+
"documentTemplate": "Title: {{ title }}
27+
Description: {{ overview }}
28+
Genres: {{ genres }}
29+
Release Date: {{ release_date }}
30+
",
31+
"documentTemplateMaxBytes": 500,
32+
"searchParameters": {
33+
"attributesToSearchOn": [
34+
"title",
35+
"overview",
36+
],
37+
"distinct": "title",
38+
"hybrid": {
39+
"embedder": "default",
40+
"semanticRatio": 0.5,
41+
},
42+
"limit": 20,
43+
"matchingStrategy": "last",
44+
"rankingScoreThreshold": 0.5,
45+
"sort": [
46+
"release_date:desc",
47+
],
48+
},
49+
}
50+
`;
51+
52+
exports[`Test on chat settings > Master key: Get an index chat settings 1`] = `
53+
{
54+
"description": "",
55+
"documentTemplate": "{% for field in fields %}{% if field.is_searchable and field.value != nil %}{{ field.name }}: {{ field.value }}
56+
{% endif %}{% endfor %}",
57+
"documentTemplateMaxBytes": 400,
58+
"searchParameters": {},
59+
}
60+
`;
61+
62+
exports[`Test on chat settings > Master key: Get default chat settings on index 1`] = `
63+
{
64+
"description": "",
65+
"documentTemplate": "{% for field in fields %}{% if field.is_searchable and field.value != nil %}{{ field.name }}: {{ field.value }}
66+
{% endif %}{% endfor %}",
67+
"documentTemplateMaxBytes": 400,
68+
"searchParameters": {},
69+
}
70+
`;
71+
72+
exports[`Test on chat settings > Master key: Update chat settings with all properties 1`] = `
73+
{
74+
"description": "A comprehensive movie database containing titles, overviews, genres, and release dates to help users find movies",
75+
"documentTemplate": "Title: {{ title }}
76+
Description: {{ overview }}
77+
Genres: {{ genres }}
78+
Release Date: {{ release_date }}
79+
",
80+
"documentTemplateMaxBytes": 500,
81+
"searchParameters": {
82+
"attributesToSearchOn": [
83+
"title",
84+
"overview",
85+
],
86+
"distinct": "title",
87+
"hybrid": {
88+
"embedder": "default",
89+
"semanticRatio": 0.5,
90+
},
91+
"limit": 20,
92+
"matchingStrategy": "last",
93+
"rankingScoreThreshold": 0.5,
94+
"sort": [
95+
"release_date:desc",
96+
],
97+
},
98+
}
99+
`;

tests/chat-settings.test.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import {
2+
afterAll,
3+
expect,
4+
test,
5+
describe,
6+
beforeEach,
7+
expectTypeOf,
8+
} from "vitest";
9+
import {
10+
ErrorStatusCode,
11+
type ChatSettings,
12+
type SearchParams,
13+
} from "../src/types/index.js";
14+
import {
15+
clearAllIndexes,
16+
config,
17+
getClient,
18+
dataset,
19+
} from "./utils/meilisearch-test-utils.js";
20+
21+
const index = {
22+
uid: "chat_settings_test",
23+
};
24+
25+
afterAll(() => {
26+
return clearAllIndexes(config);
27+
});
28+
29+
describe.each([{ permission: "Master" }, { permission: "Admin" }])(
30+
"Test on chat settings",
31+
({ permission }) => {
32+
beforeEach(async () => {
33+
await clearAllIndexes(config);
34+
const client = await getClient("Master");
35+
await client.index(index.uid).addDocuments(dataset).waitTask();
36+
});
37+
38+
test(`${permission} key: Get an index chat settings`, async () => {
39+
const client = await getClient(permission);
40+
41+
const response = await client.index(index.uid).getChat();
42+
expect(response).toHaveProperty("description");
43+
expect(response).toHaveProperty("documentTemplate");
44+
expect(response).toHaveProperty("documentTemplateMaxBytes");
45+
expect(response).toHaveProperty("searchParameters");
46+
expectTypeOf(response.searchParameters).toEqualTypeOf<SearchParams>();
47+
});
48+
49+
test(`${permission} key: Update chat settings with all properties`, async () => {
50+
const client = await getClient(permission);
51+
const newChatSettings = {
52+
description:
53+
"A comprehensive movie database containing titles, overviews, genres, and release dates to help users find movies",
54+
documentTemplate:
55+
"Title: {{ title }}\nDescription: {{ overview }}\nGenres: {{ genres }}\nRelease Date: {{ release_date }}\n",
56+
documentTemplateMaxBytes: 500,
57+
searchParameters: {
58+
hybrid: { embedder: "default" },
59+
limit: 20,
60+
sort: ["release_date:desc"],
61+
distinct: "title",
62+
matchingStrategy: "last",
63+
attributesToSearchOn: ["title", "overview"],
64+
rankingScoreThreshold: 0.5,
65+
},
66+
} satisfies ChatSettings;
67+
68+
await client.index(index.uid).updateChat(newChatSettings).waitTask();
69+
70+
const response = await client.index(index.uid).getChat();
71+
expect(response).toMatchObject(newChatSettings);
72+
});
73+
},
74+
);
75+
76+
describe.each([
77+
{ permission: "Search", errorCode: ErrorStatusCode.INVALID_API_KEY },
78+
{ permission: "No", errorCode: ErrorStatusCode.MISSING_AUTHORIZATION_HEADER },
79+
])("Test on chat settings", ({ permission, errorCode }) => {
80+
beforeEach(async () => {
81+
await clearAllIndexes(config);
82+
const client = await getClient("Master");
83+
await client.createIndex(index.uid).waitTask();
84+
});
85+
86+
test(`${permission} key: try to get chat settings and be denied`, async () => {
87+
const client = await getClient(permission);
88+
await expect(client.index(index.uid).getChat()).rejects.toHaveProperty(
89+
"cause.code",
90+
errorCode,
91+
);
92+
});
93+
94+
test(`${permission} key: try to update chat settings and be denied`, async () => {
95+
const client = await getClient(permission);
96+
await expect(
97+
client.index(index.uid).updateChat({ description: "test" }),
98+
).rejects.toHaveProperty("cause.code", errorCode);
99+
});
100+
});
File renamed without changes.

0 commit comments

Comments
 (0)