File size: 4,331 Bytes
d9494a5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { buildToolInputJsonSchema } from '@/logic-function/build-tool-input-json-schema';

describe('buildToolInputJsonSchema', () => {
  it('should collapse a record-typed object to an id string with a resolved label', () => {
    const result = buildToolInputJsonSchema(
      {
        type: 'object',
        objectUniversalIdentifier: 'company-universal-identifier',
      },
      (universalIdentifier) =>
        universalIdentifier === 'company-universal-identifier'
          ? 'Company'
          : undefined,
    );

    expect(result).toEqual({
      type: 'string',
      description: 'Id of the Company record',
    });
  });

  it('should fall back to a generic label when none resolves', () => {
    expect(
      buildToolInputJsonSchema({
        type: 'object',
        objectUniversalIdentifier: 'company-universal-identifier',
      }),
    ).toEqual({
      type: 'string',
      description: 'Id of the linked record',
    });
  });

  it('should collapse arrays of records to arrays of id strings', () => {
    const result = buildToolInputJsonSchema(
      {
        type: 'array',
        items: {
          type: 'object',
          objectUniversalIdentifier: 'person-universal-identifier',
        },
      },
      () => 'Person',
    );

    expect(result).toEqual({
      type: 'array',
      items: { type: 'string', description: 'Id of the Person record' },
    });
  });

  it('should collapse a record type to an id string', () => {
    expect(
      buildToolInputJsonSchema(
        {
          type: 'record',
          objectUniversalIdentifier: 'company-universal-identifier',
        },
        () => 'Company',
      ),
    ).toEqual({ type: 'string', description: 'Id of the Company record' });
  });

  it('should collapse a records type to an array of id strings', () => {
    expect(
      buildToolInputJsonSchema(
        {
          type: 'records',
          objectUniversalIdentifier: 'person-universal-identifier',
        },
        () => 'Person',
      ),
    ).toEqual({
      type: 'array',
      items: { type: 'string', description: 'Id of the Person record' },
    });
  });

  it('should strip custom keywords recursively while keeping standard ones', () => {
    const result = buildToolInputJsonSchema(
      {
        type: 'object',
        label: 'Params',
        properties: {
          company: {
            type: 'object',
            objectUniversalIdentifier: 'company-universal-identifier',
            description: 'A company',
          },
          people: {
            type: 'array',
            label: 'People',
            items: {
              type: 'object',
              objectUniversalIdentifier: 'person-universal-identifier',
            },
          },
          note: { type: 'string', multiline: true },
          kind: { type: 'string', enum: ['a', 'b'] },
        },
        required: ['company'],
      },
      () => 'Company',
    );

    expect(result).toEqual({
      type: 'object',
      properties: {
        company: { type: 'string', description: 'Id of the Company record' },
        people: {
          type: 'array',
          items: { type: 'string', description: 'Id of the Company record' },
        },
        note: { type: 'string' },
        kind: { type: 'string', enum: ['a', 'b'] },
      },
      required: ['company'],
    });
  });

  it('should keep boolean additionalProperties and sanitize object ones', () => {
    expect(
      buildToolInputJsonSchema({
        type: 'object',
        additionalProperties: false,
      }),
    ).toEqual({ type: 'object', additionalProperties: false });

    expect(
      buildToolInputJsonSchema({
        type: 'object',
        additionalProperties: { type: 'string', multiline: true },
      }),
    ).toEqual({ type: 'object', additionalProperties: { type: 'string' } });
  });

  it('should leave non-record nodes untouched aside from custom keywords', () => {
    expect(
      buildToolInputJsonSchema({
        type: 'object',
        properties: {
          plainObject: { type: 'object' },
          count: { type: 'number', minimum: 0, maximum: 10 },
        },
      }),
    ).toEqual({
      type: 'object',
      properties: {
        plainObject: { type: 'object' },
        count: { type: 'number', minimum: 0, maximum: 10 },
      },
    });
  });
});