mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-27 12:46:13 +01:00
698 lines
20 KiB
TypeScript
698 lines
20 KiB
TypeScript
|
|
import { EToolResources } from 'librechat-data-provider';
|
||
|
|
import { convertOcrToContextInPlace, mergeAgentOcrConversion } from './legacy';
|
||
|
|
import type { AgentToolResources, TFile } from 'librechat-data-provider';
|
||
|
|
|
||
|
|
describe('OCR to Context Conversion for updateAgentHandler', () => {
|
||
|
|
describe('convertOcrToContextInPlace', () => {
|
||
|
|
it('should do nothing when no OCR resource exists', () => {
|
||
|
|
const data = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.execute_code]: {
|
||
|
|
file_ids: ['file1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
tools: ['execute_code'],
|
||
|
|
};
|
||
|
|
|
||
|
|
const originalCopy = JSON.parse(JSON.stringify(data));
|
||
|
|
convertOcrToContextInPlace(data);
|
||
|
|
|
||
|
|
expect(data).toEqual(originalCopy);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should convert OCR to context when context does not exist', () => {
|
||
|
|
const data = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1', 'ocr2'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'ocr1',
|
||
|
|
filename: 'doc.pdf',
|
||
|
|
filepath: '/doc.pdf',
|
||
|
|
type: 'application/pdf',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 1024,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
} as AgentToolResources,
|
||
|
|
};
|
||
|
|
|
||
|
|
convertOcrToContextInPlace(data);
|
||
|
|
|
||
|
|
expect(data.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(data.tool_resources?.[EToolResources.context]).toEqual({
|
||
|
|
file_ids: ['ocr1', 'ocr2'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'ocr1',
|
||
|
|
filename: 'doc.pdf',
|
||
|
|
filepath: '/doc.pdf',
|
||
|
|
type: 'application/pdf',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file',
|
||
|
|
bytes: 1024,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should merge OCR into existing context', () => {
|
||
|
|
const data = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['context1'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'context1',
|
||
|
|
filename: 'existing.txt',
|
||
|
|
filepath: '/existing.txt',
|
||
|
|
type: 'text/plain',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 256,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1', 'ocr2'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'ocr1',
|
||
|
|
filename: 'scan.pdf',
|
||
|
|
filepath: '/scan.pdf',
|
||
|
|
type: 'application/pdf',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 1024,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
convertOcrToContextInPlace(data);
|
||
|
|
|
||
|
|
expect(data.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(data.tool_resources?.[EToolResources.context]?.file_ids).toEqual([
|
||
|
|
'context1',
|
||
|
|
'ocr1',
|
||
|
|
'ocr2',
|
||
|
|
]);
|
||
|
|
expect(data.tool_resources?.[EToolResources.context]?.files).toHaveLength(2);
|
||
|
|
expect(data.tool_resources?.[EToolResources.context]?.files?.map((f) => f.file_id)).toEqual([
|
||
|
|
'context1',
|
||
|
|
'ocr1',
|
||
|
|
]);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should deduplicate file_ids when merging', () => {
|
||
|
|
const data = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['file1', 'file2'],
|
||
|
|
},
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['file2', 'file3'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
convertOcrToContextInPlace(data);
|
||
|
|
|
||
|
|
expect(data.tool_resources?.[EToolResources.context]?.file_ids).toEqual([
|
||
|
|
'file1',
|
||
|
|
'file2',
|
||
|
|
'file3',
|
||
|
|
]);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should deduplicate files by file_id when merging', () => {
|
||
|
|
const sharedFile: TFile = {
|
||
|
|
file_id: 'shared',
|
||
|
|
filename: 'shared.txt',
|
||
|
|
filepath: '/shared.txt',
|
||
|
|
type: 'text/plain',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file',
|
||
|
|
bytes: 256,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
};
|
||
|
|
|
||
|
|
const data = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
files: [sharedFile],
|
||
|
|
},
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
files: [
|
||
|
|
sharedFile,
|
||
|
|
{
|
||
|
|
file_id: 'unique',
|
||
|
|
filename: 'unique.pdf',
|
||
|
|
filepath: '/unique.pdf',
|
||
|
|
type: 'application/pdf',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 1024,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
convertOcrToContextInPlace(data);
|
||
|
|
|
||
|
|
expect(data.tool_resources?.[EToolResources.context]?.files).toHaveLength(2);
|
||
|
|
expect(
|
||
|
|
data.tool_resources?.[EToolResources.context]?.files?.map((f) => f.file_id).sort(),
|
||
|
|
).toEqual(['shared', 'unique']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should replace OCR with context in tools array', () => {
|
||
|
|
const data = {
|
||
|
|
tools: ['execute_code', 'ocr', 'file_search'],
|
||
|
|
};
|
||
|
|
|
||
|
|
convertOcrToContextInPlace(data);
|
||
|
|
|
||
|
|
expect(data.tools).toEqual(['execute_code', 'context', 'file_search']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should remove duplicates when context already exists in tools', () => {
|
||
|
|
const data = {
|
||
|
|
tools: ['context', 'ocr', 'execute_code'],
|
||
|
|
};
|
||
|
|
|
||
|
|
convertOcrToContextInPlace(data);
|
||
|
|
|
||
|
|
expect(data.tools).toEqual(['context', 'execute_code']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should handle both tool_resources and tools conversion', () => {
|
||
|
|
const data = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
},
|
||
|
|
} as AgentToolResources,
|
||
|
|
tools: ['ocr', 'execute_code'],
|
||
|
|
};
|
||
|
|
|
||
|
|
convertOcrToContextInPlace(data);
|
||
|
|
|
||
|
|
expect(data.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(data.tool_resources?.[EToolResources.context]).toEqual({
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
});
|
||
|
|
expect(data.tools).toEqual(['context', 'execute_code']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should preserve other tool resources during OCR conversion', () => {
|
||
|
|
const data = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.execute_code]: {
|
||
|
|
file_ids: ['exec1', 'exec2'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'exec1',
|
||
|
|
filename: 'script.py',
|
||
|
|
filepath: '/script.py',
|
||
|
|
type: 'text/x-python',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 512,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
[EToolResources.file_search]: {
|
||
|
|
file_ids: ['search1'],
|
||
|
|
vector_store_ids: ['vector1', 'vector2'],
|
||
|
|
},
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
},
|
||
|
|
} as AgentToolResources,
|
||
|
|
tools: ['execute_code', 'file_search', 'ocr'],
|
||
|
|
};
|
||
|
|
|
||
|
|
const originalExecuteCode = JSON.parse(JSON.stringify(data.tool_resources.execute_code));
|
||
|
|
const originalFileSearch = JSON.parse(JSON.stringify(data.tool_resources.file_search));
|
||
|
|
|
||
|
|
convertOcrToContextInPlace(data);
|
||
|
|
|
||
|
|
// OCR should be converted to context
|
||
|
|
expect(data.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(data.tool_resources?.[EToolResources.context]).toEqual({
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
});
|
||
|
|
|
||
|
|
// Other resources should remain unchanged
|
||
|
|
expect(data.tool_resources?.[EToolResources.execute_code]).toEqual(originalExecuteCode);
|
||
|
|
expect(data.tool_resources?.[EToolResources.file_search]).toEqual(originalFileSearch);
|
||
|
|
|
||
|
|
// Tools array should have ocr replaced with context
|
||
|
|
expect(data.tools).toEqual(['execute_code', 'file_search', 'context']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should preserve image_edit resource during OCR conversion', () => {
|
||
|
|
const data = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.image_edit]: {
|
||
|
|
file_ids: ['image1'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'image1',
|
||
|
|
filename: 'photo.png',
|
||
|
|
filepath: '/photo.png',
|
||
|
|
type: 'image/png',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 2048,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
width: 800,
|
||
|
|
height: 600,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
},
|
||
|
|
} as AgentToolResources,
|
||
|
|
};
|
||
|
|
|
||
|
|
const originalImageEdit = JSON.parse(JSON.stringify(data.tool_resources.image_edit));
|
||
|
|
|
||
|
|
convertOcrToContextInPlace(data);
|
||
|
|
|
||
|
|
expect(data.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(data.tool_resources?.[EToolResources.context]).toEqual({
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
});
|
||
|
|
expect(data.tool_resources?.[EToolResources.image_edit]).toEqual(originalImageEdit);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('mergeAgentOcrConversion', () => {
|
||
|
|
it('should return empty object when existing agent has no OCR', () => {
|
||
|
|
const existingAgent = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.execute_code]: {
|
||
|
|
file_ids: ['file1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
tools: ['execute_code'],
|
||
|
|
};
|
||
|
|
|
||
|
|
const updateData = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['context1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
const result = mergeAgentOcrConversion(existingAgent, updateData);
|
||
|
|
|
||
|
|
expect(result).toEqual({});
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should convert existing OCR to context when no context exists', () => {
|
||
|
|
const existingAgent = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1', 'ocr2'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'ocr1',
|
||
|
|
filename: 'doc.pdf',
|
||
|
|
filepath: '/doc.pdf',
|
||
|
|
type: 'application/pdf',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 1024,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
tools: ['ocr', 'execute_code'],
|
||
|
|
};
|
||
|
|
|
||
|
|
const updateData = {};
|
||
|
|
|
||
|
|
const result = mergeAgentOcrConversion(existingAgent, updateData);
|
||
|
|
|
||
|
|
expect(result.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(result.tool_resources?.[EToolResources.context]).toEqual({
|
||
|
|
file_ids: ['ocr1', 'ocr2'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'ocr1',
|
||
|
|
filename: 'doc.pdf',
|
||
|
|
filepath: '/doc.pdf',
|
||
|
|
type: 'application/pdf',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file',
|
||
|
|
bytes: 1024,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
});
|
||
|
|
expect(result.tools).toEqual(['context', 'execute_code']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should merge existing OCR with existing context', () => {
|
||
|
|
const existingAgent = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['context1'],
|
||
|
|
},
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
const updateData = {};
|
||
|
|
|
||
|
|
const result = mergeAgentOcrConversion(existingAgent, updateData);
|
||
|
|
|
||
|
|
expect(result.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(result.tool_resources?.[EToolResources.context]?.file_ids).toEqual([
|
||
|
|
'context1',
|
||
|
|
'ocr1',
|
||
|
|
]);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should merge converted context with updateData context', () => {
|
||
|
|
const existingAgent = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
const updateData = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['update-context1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
const result = mergeAgentOcrConversion(existingAgent, updateData);
|
||
|
|
|
||
|
|
expect(result.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(result.tool_resources?.[EToolResources.context]?.file_ids?.sort()).toEqual([
|
||
|
|
'ocr1',
|
||
|
|
'update-context1',
|
||
|
|
]);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should handle complex merge with files and file_ids', () => {
|
||
|
|
const existingAgent = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['context1'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'context1',
|
||
|
|
filename: 'existing.txt',
|
||
|
|
filepath: '/existing.txt',
|
||
|
|
type: 'text/plain',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 256,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1', 'ocr2'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'ocr1',
|
||
|
|
filename: 'scan.pdf',
|
||
|
|
filepath: '/scan.pdf',
|
||
|
|
type: 'application/pdf',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 1024,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
tools: ['context', 'ocr'],
|
||
|
|
};
|
||
|
|
|
||
|
|
const updateData = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['update1'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'update1',
|
||
|
|
filename: 'update.txt',
|
||
|
|
filepath: '/update.txt',
|
||
|
|
type: 'text/plain',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 512,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
const result = mergeAgentOcrConversion(existingAgent, updateData);
|
||
|
|
|
||
|
|
expect(result.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(result.tool_resources?.[EToolResources.context]?.file_ids?.sort()).toEqual([
|
||
|
|
'context1',
|
||
|
|
'ocr1',
|
||
|
|
'ocr2',
|
||
|
|
'update1',
|
||
|
|
]);
|
||
|
|
expect(result.tool_resources?.[EToolResources.context]?.files).toHaveLength(3);
|
||
|
|
expect(result.tools).toEqual(['context']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should not mutate original objects', () => {
|
||
|
|
const existingAgent = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
tools: ['ocr'],
|
||
|
|
};
|
||
|
|
|
||
|
|
const updateData = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['context1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
const existingCopy = JSON.parse(JSON.stringify(existingAgent));
|
||
|
|
const updateCopy = JSON.parse(JSON.stringify(updateData));
|
||
|
|
|
||
|
|
mergeAgentOcrConversion(existingAgent, updateData);
|
||
|
|
|
||
|
|
expect(existingAgent).toEqual(existingCopy);
|
||
|
|
expect(updateData).toEqual(updateCopy);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should preserve other tool resources in existing agent during merge', () => {
|
||
|
|
const existingAgent = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.execute_code]: {
|
||
|
|
file_ids: ['exec1', 'exec2'],
|
||
|
|
files: [
|
||
|
|
{
|
||
|
|
file_id: 'exec1',
|
||
|
|
filename: 'script.py',
|
||
|
|
filepath: '/script.py',
|
||
|
|
type: 'text/x-python',
|
||
|
|
user: 'user1',
|
||
|
|
object: 'file' as const,
|
||
|
|
bytes: 512,
|
||
|
|
embedded: false,
|
||
|
|
usage: 0,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
[EToolResources.file_search]: {
|
||
|
|
file_ids: ['search1'],
|
||
|
|
vector_store_ids: ['vector1', 'vector2'],
|
||
|
|
},
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
tools: ['execute_code', 'file_search', 'ocr'],
|
||
|
|
};
|
||
|
|
|
||
|
|
const updateData = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['new-context1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
const originalExecuteCode = JSON.parse(
|
||
|
|
JSON.stringify(existingAgent.tool_resources.execute_code),
|
||
|
|
);
|
||
|
|
const originalFileSearch = JSON.parse(
|
||
|
|
JSON.stringify(existingAgent.tool_resources.file_search),
|
||
|
|
);
|
||
|
|
|
||
|
|
const result = mergeAgentOcrConversion(existingAgent, updateData);
|
||
|
|
|
||
|
|
// OCR should be converted to context and merged with updateData context
|
||
|
|
expect(result.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(result.tool_resources?.[EToolResources.context]?.file_ids?.sort()).toEqual([
|
||
|
|
'new-context1',
|
||
|
|
'ocr1',
|
||
|
|
]);
|
||
|
|
|
||
|
|
// Other resources should be preserved
|
||
|
|
expect(result.tool_resources?.[EToolResources.execute_code]).toEqual(originalExecuteCode);
|
||
|
|
expect(result.tool_resources?.[EToolResources.file_search]).toEqual(originalFileSearch);
|
||
|
|
|
||
|
|
// Tools should have ocr replaced with context
|
||
|
|
expect(result.tools).toEqual(['execute_code', 'file_search', 'context']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should not affect updateData tool resources that are not context', () => {
|
||
|
|
const existingAgent = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
tools: ['ocr'],
|
||
|
|
};
|
||
|
|
|
||
|
|
const updateData = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.execute_code]: {
|
||
|
|
file_ids: ['update-exec1'],
|
||
|
|
},
|
||
|
|
[EToolResources.file_search]: {
|
||
|
|
file_ids: ['update-search1'],
|
||
|
|
vector_store_ids: ['update-vector1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
tools: ['execute_code', 'file_search'],
|
||
|
|
};
|
||
|
|
|
||
|
|
const originalUpdateData = JSON.parse(JSON.stringify(updateData));
|
||
|
|
|
||
|
|
const result = mergeAgentOcrConversion(existingAgent, updateData);
|
||
|
|
|
||
|
|
// OCR should be converted to context
|
||
|
|
expect(result.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(result.tool_resources?.[EToolResources.context]).toEqual({
|
||
|
|
file_ids: ['ocr1'],
|
||
|
|
});
|
||
|
|
|
||
|
|
// UpdateData's other resources should not be affected
|
||
|
|
expect(updateData.tool_resources?.[EToolResources.execute_code]).toEqual(
|
||
|
|
originalUpdateData.tool_resources.execute_code,
|
||
|
|
);
|
||
|
|
expect(updateData.tool_resources?.[EToolResources.file_search]).toEqual(
|
||
|
|
originalUpdateData.tool_resources.file_search,
|
||
|
|
);
|
||
|
|
|
||
|
|
// Result should only have the converted OCR resources and tools
|
||
|
|
expect(result.tools).toEqual(['context']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should handle all tool resources together', () => {
|
||
|
|
const existingAgent = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.execute_code]: {
|
||
|
|
file_ids: ['exec1'],
|
||
|
|
},
|
||
|
|
[EToolResources.file_search]: {
|
||
|
|
file_ids: ['search1'],
|
||
|
|
vector_store_ids: ['vector1'],
|
||
|
|
},
|
||
|
|
[EToolResources.image_edit]: {
|
||
|
|
file_ids: ['image1'],
|
||
|
|
},
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['existing-context1'],
|
||
|
|
},
|
||
|
|
[EToolResources.ocr]: {
|
||
|
|
file_ids: ['ocr1', 'ocr2'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
tools: ['execute_code', 'file_search', 'image_edit', 'context', 'ocr'],
|
||
|
|
};
|
||
|
|
|
||
|
|
const updateData = {
|
||
|
|
tool_resources: {
|
||
|
|
[EToolResources.context]: {
|
||
|
|
file_ids: ['update-context1'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
const result = mergeAgentOcrConversion(existingAgent, updateData);
|
||
|
|
|
||
|
|
// OCR should be merged with existing context and update context
|
||
|
|
expect(result.tool_resources?.[EToolResources.ocr]).toBeUndefined();
|
||
|
|
expect(result.tool_resources?.[EToolResources.context]?.file_ids?.sort()).toEqual([
|
||
|
|
'existing-context1',
|
||
|
|
'ocr1',
|
||
|
|
'ocr2',
|
||
|
|
'update-context1',
|
||
|
|
]);
|
||
|
|
|
||
|
|
// All other resources should be preserved
|
||
|
|
expect(result.tool_resources?.[EToolResources.execute_code]).toEqual({
|
||
|
|
file_ids: ['exec1'],
|
||
|
|
});
|
||
|
|
expect(result.tool_resources?.[EToolResources.file_search]).toEqual({
|
||
|
|
file_ids: ['search1'],
|
||
|
|
vector_store_ids: ['vector1'],
|
||
|
|
});
|
||
|
|
expect(result.tool_resources?.[EToolResources.image_edit]).toEqual({
|
||
|
|
file_ids: ['image1'],
|
||
|
|
});
|
||
|
|
|
||
|
|
// Tools should have ocr replaced with context (no duplicates)
|
||
|
|
expect(result.tools).toEqual(['execute_code', 'file_search', 'image_edit', 'context']);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|