Skip to content

Commit 63aea80

Browse files
authored
fix(conversation): model list tool query name infinite recursion (#3037)
1 parent b51f790 commit 63aea80

File tree

3 files changed

+15
-24
lines changed

3 files changed

+15
-24
lines changed

packages/amplify-graphql-conversation-transformer/src/__tests__/__snapshots__/amplify-graphql-conversation-transformer.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1545,7 +1545,7 @@ export function request(ctx) {
15451545
const clientTools = args.toolConfiguration?.tools?.map((tool) => {
15461546
return { ...tool.toolSpec };
15471547
});
1548-
const dataTools = [{"name":"list_customers","description":"Provides data about the customer sending a message","inputSchema":{"json":{"type":"object","properties":{},"required":[]}},"graphqlRequestInputDescriptor":{"selectionSet":"items { name email activeCart { products { name price } customerId id createdAt updatedAt owner } orderHistory { items { products { name price } customerId id createdAt updatedAt owner } nextToken } id createdAt updatedAt owner } nextToken","propertyTypes":{},"queryName":"listCustomers"}}];
1548+
const dataTools = [{"name":"random_name","description":"Provides data about the customer sending a message","inputSchema":{"json":{"type":"object","properties":{},"required":[]}},"graphqlRequestInputDescriptor":{"selectionSet":"items { name email activeCart { products { name price } customerId id createdAt updatedAt owner } orderHistory { items { products { name price } customerId id createdAt updatedAt owner } nextToken } id createdAt updatedAt owner } nextToken","propertyTypes":{},"queryName":"listCustomers"}}];
15491549
const toolsConfiguration = { dataTools, clientTools };
15501550

15511551
const messageHistoryQuery = {

packages/amplify-graphql-conversation-transformer/src/__tests__/schemas/conversation-route-model-query-tool-with-relationships.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ type Mutation {
3434
systemPrompt: "You are a helpful chatbot. Answer questions to the best of your ability.",
3535
tools: [
3636
{
37-
name: "list_customers",
37+
name: "random_name",
3838
description: "Provides data about the customer sending a message",
3939
modelName: "Customer",
4040
modelOperation: list,

packages/amplify-graphql-conversation-transformer/src/tools/process-tools.ts

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,16 @@ export const processTools = (toolDefinitions: ToolDefinition[], ctx: Transformer
5656

5757
// Process each tool definition
5858
const tools: Tool[] = toolDefinitions.map((toolDefinition) => {
59-
const { name: toolName, description } = toolDefinition;
6059
const queryName = isModelOperationToolPredicate(toolDefinition) ? modelListQueryName(toolDefinition, ctx) : toolDefinition.queryName;
6160
const queryField = queryType.fields?.find((field) => field.name.value === queryName);
6261

6362
if (!queryField) {
64-
throw new InvalidDirectiveError(`Tool "${toolName}" defined in @conversation directive has no matching Query field definition`);
63+
throw new InvalidDirectiveError(
64+
`Tool "${toolDefinition.name}" defined in @conversation directive has no matching Query field definition`,
65+
);
6566
}
6667

67-
return createTool({ toolName, description, queryField, ctx });
68+
return createTool({ toolDefinition, queryField, ctx });
6869
});
6970

7071
return tools;
@@ -150,23 +151,19 @@ const getObjectTypeFromName = (name: string, ctx: TransformerContextProvider): O
150151
* @param {TransformerContextProvider} ctx - The transformer context provider.
151152
* @returns {Tool} A Tool object.
152153
*/
153-
const createTool = (input: {
154-
toolName: string;
155-
description: string;
156-
queryField: FieldDefinitionNode;
157-
ctx: TransformerContextProvider;
158-
}): Tool => {
159-
const { toolName, description, queryField, ctx } = input;
154+
const createTool = (input: { toolDefinition: ToolDefinition; queryField: FieldDefinitionNode; ctx: TransformerContextProvider }): Tool => {
155+
const { toolDefinition, queryField, ctx } = input;
156+
const { name: toolName, description } = toolDefinition;
160157
const { type: returnType, arguments: fieldArguments } = queryField;
161158

162159
// Generate tool properties and required fields
163-
const { properties, required } = generateToolProperties(fieldArguments, ctx, toolName, returnType);
160+
const { properties, required } = generateToolProperties(fieldArguments, ctx, toolDefinition);
164161

165162
// Generate selection set for the return type
166163
const selectionSet = generateSelectionSet(returnType, ctx).trim();
167164

168165
// Generate property types for GraphQL request input
169-
const propertyTypes = generatePropertyTypes(fieldArguments, toolName, returnType);
166+
const propertyTypes = generatePropertyTypes(fieldArguments, toolDefinition);
170167

171168
// Create GraphQL request input descriptor
172169
const graphqlRequestInputDescriptor: GraphQLRequestInputDescriptor = {
@@ -199,14 +196,13 @@ const createTool = (input: {
199196
const generateToolProperties = (
200197
fieldArguments: readonly InputValueDefinitionNode[] | undefined,
201198
ctx: TransformerContextProvider,
202-
toolName: string,
203-
returnType: TypeNode,
199+
toolDefinition: ToolDefinition,
204200
): { properties: Record<string, JSONSchema>; required: string[] } => {
205201
if (!fieldArguments || fieldArguments.length === 0) {
206202
return { properties: {}, required: [] };
207203
}
208204

209-
if (isModelListOperation(toolName, returnType)) {
205+
if (isModelOperationToolPredicate(toolDefinition)) {
210206
return { properties: {}, required: [] };
211207
}
212208

@@ -233,14 +229,13 @@ const generateToolProperties = (
233229
*/
234230
const generatePropertyTypes = (
235231
fieldArguments: readonly InputValueDefinitionNode[] | undefined,
236-
toolName: string,
237-
returnType: TypeNode,
232+
toolDefinition: ToolDefinition,
238233
): Record<string, string> => {
239234
if (!fieldArguments || fieldArguments.length === 0) {
240235
return {};
241236
}
242237

243-
if (isModelListOperation(toolName, returnType)) {
238+
if (isModelOperationToolPredicate(toolDefinition)) {
244239
return {};
245240
}
246241

@@ -252,10 +247,6 @@ const generatePropertyTypes = (
252247
}, {} as Record<string, string>);
253248
};
254249

255-
const isModelListOperation = (toolName: string, responseType: TypeNode): boolean => {
256-
return getBaseType(responseType).startsWith('Model') && toolName.startsWith('list');
257-
};
258-
259250
const modelListQueryName = (modelTool: ModelOperationTool, ctx: TransformerContextProvider): string => {
260251
const { modelName } = modelTool;
261252
const model = getObjectTypeFromName(modelName, ctx);

0 commit comments

Comments
 (0)