Skip to content

Commit 8e964e1

Browse files
authored
fix(ai-constructs): invalid graphql generation for query tools (#1988)
* add defensive check for empty tool properties * fix invalid selection set for gql tools with scalar response types * add changeset
1 parent c10f6fc commit 8e964e1

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed

.changeset/fuzzy-poems-walk.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@aws-amplify/ai-constructs': patch
3+
---
4+
5+
fix invalid graphql in tool query generation

packages/ai-constructs/src/conversation/runtime/event-tools-provider/graphql_query_factory.test.ts

+25-6
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ const testCases: Array<TestCase> = [
3737
},
3838
expectedQuery: `
3939
query ToolQuery($property1: String!, $property2: Int) {
40-
testQueryName1(property1: $property1, property2: $property2) {
41-
testSelection1 testSelection2
42-
}
40+
testQueryName1(property1: $property1, property2: $property2) { testSelection1 testSelection2 }
4341
}
4442
`,
4543
},
@@ -58,9 +56,30 @@ const testCases: Array<TestCase> = [
5856
},
5957
expectedQuery: `
6058
query ToolQuery {
61-
testQueryName2 {
62-
testSelection3 testSelection4
63-
}
59+
testQueryName2 { testSelection3 testSelection4 }
60+
}
61+
`,
62+
},
63+
{
64+
toolDefinition: {
65+
name: 'toolName3',
66+
description: 'toolDescription3',
67+
inputSchema: {
68+
json: {
69+
type: 'object',
70+
properties: {},
71+
required: [],
72+
},
73+
},
74+
graphqlRequestInputDescriptor: {
75+
queryName: 'testQueryName3',
76+
selectionSet: '',
77+
propertyTypes: {},
78+
},
79+
},
80+
expectedQuery: `
81+
query ToolQuery {
82+
testQueryName3
6483
}
6584
`,
6685
},

packages/ai-constructs/src/conversation/runtime/event-tools-provider/graphql_query_factory.ts

+17-5
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@ export class GraphQlQueryFactory {
1515
const { graphqlRequestInputDescriptor } = toolDefinition;
1616
const { selectionSet, queryName } = graphqlRequestInputDescriptor;
1717
const [topLevelQueryArgs, queryArgs] = this.createQueryArgs(toolDefinition);
18-
18+
const fieldSelection =
19+
selectionSet.length > 0 ? ` { ${selectionSet} }` : '';
1920
const query = `
2021
query ToolQuery${topLevelQueryArgs} {
21-
${queryName}${queryArgs} {
22-
${selectionSet}
23-
}
22+
${queryName}${queryArgs}${fieldSelection}
2423
}
2524
`;
2625

@@ -36,7 +35,20 @@ export class GraphQlQueryFactory {
3635
}
3736

3837
const { properties } = inputSchema.json as InputSchemaJson;
39-
if (!properties) {
38+
39+
// The conversation resolver should not pass an empty object as input,
40+
// but we're defensively checking for it here anyway because if `properties: {}`
41+
// is passed, it will generate invalid GraphQL. e.g.
42+
// Valid:
43+
// query ToolQuery {
44+
// exampleQuery
45+
// }
46+
//
47+
// Invalid:
48+
// query ToolQuery {
49+
// exampleQuery()
50+
// }
51+
if (!properties || Object.keys(properties).length === 0) {
4052
return ['', ''];
4153
}
4254
const { propertyTypes } = toolDefinition.graphqlRequestInputDescriptor;

0 commit comments

Comments
 (0)