From 3a1f463d01f35c76b5bc7d76de7817a9a6b65685 Mon Sep 17 00:00:00 2001 From: KavinduZoysa Date: Tue, 6 May 2025 11:14:15 +0530 Subject: [PATCH 1/4] Resolve merge conflicts --- .../flowmodelgenerator/core/AgentsGenerator.java | 16 ++++++++++++---- .../core/model/SourceBuilder.java | 15 ++++++++++++--- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/AgentsGenerator.java b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/AgentsGenerator.java index 475bf4218..f2b78a07c 100644 --- a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/AgentsGenerator.java +++ b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/AgentsGenerator.java @@ -372,8 +372,8 @@ public JsonElement genTool(JsonElement node, String toolName, String connectionN Property.CONNECTION_KEY, Property.CHECK_ERROR_KEY)); keys.removeAll(ignoredKeys); List paramList = new ArrayList<>(); - for (String key : keys) { - Property property = properties.get(key); + for (String k : keys) { + Property property = properties.get(k); if (property == null) { continue; } @@ -385,6 +385,10 @@ public JsonElement genTool(JsonElement node, String toolName, String connectionN continue; } } + String key = k; + if (k.startsWith("$")) { + key = "'" + k.substring(1); + } if (hasDescription) { sourceBuilder.token().parameterDoc(key, property.metadata().description()); } @@ -465,8 +469,8 @@ public JsonElement genTool(JsonElement node, String toolName, String connectionN keys.removeAll(ignoredKeys); List paramList = new ArrayList<>(); Set pathParams = new HashSet<>(); - for (String key : keys) { - Property property = properties.get(key); + for (String k : keys) { + Property property = properties.get(k); if (property == null) { continue; } @@ -481,6 +485,10 @@ public JsonElement genTool(JsonElement node, String toolName, String connectionN continue; } } + String key = k; + if (k.startsWith("$")) { + key = "'" + k.substring(1); + } if (hasDescription) { sourceBuilder.token().parameterDoc(key, property.metadata().description()); } diff --git a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java index 854223b18..ec6e5a2be 100644 --- a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java +++ b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java @@ -446,7 +446,7 @@ public SourceBuilder functionParameters(FlowNode nodeTemplate, Set ignor if (firstParamAdded) { tokenBuilder.keyword(SyntaxKind.COMMA_TOKEN); } - tokenBuilder.expression(prop); + tokenBuilder.param(prop); } else if (kind.equals(ParameterData.Kind.INCLUDED_RECORD.name())) { if (isPropValueEmpty(prop)) { continue; @@ -454,7 +454,7 @@ public SourceBuilder functionParameters(FlowNode nodeTemplate, Set ignor if (firstParamAdded) { tokenBuilder.keyword(SyntaxKind.COMMA_TOKEN); } - tokenBuilder.expression(prop); + tokenBuilder.param(prop); } else if (kind.equals(ParameterData.Kind.DEFAULTABLE.name())) { if (isPropValueEmpty(prop)) { missedDefaultValue = true; @@ -470,7 +470,7 @@ public SourceBuilder functionParameters(FlowNode nodeTemplate, Set ignor tokenBuilder.name(prop.codedata().originalName()).whiteSpace() .keyword(SyntaxKind.EQUAL_TOKEN).expression(prop); } else { - tokenBuilder.expression(prop); + tokenBuilder.param(prop); } } else if (kind.equals(ParameterData.Kind.INCLUDED_FIELD.name())) { if (isPropValueEmpty(prop)) { @@ -679,6 +679,15 @@ public TokenBuilder expression(Property property) { return this; } + public TokenBuilder param(Property property) { + String source = property.toSourceCode(); + if (source.startsWith("$")) { + source = "'" + source.substring(1); + } + sb.append(source); + return this; + } + public TokenBuilder expression(String exprAsStr) { sb.append(exprAsStr); return this; From 166938bbb11985d5f8db31952aee7c30fabc6f24 Mon Sep 17 00:00:00 2001 From: KavinduZoysa Date: Thu, 8 May 2025 15:48:20 +0530 Subject: [PATCH 2/4] Handle new line in description on AI tool (cherry picked from commit 31e7d31a142093906af2003d37370407d059ebec) --- .../core/model/SourceBuilder.java | 33 +- .../extension/agentsmanager/GenToolsTest.java | 1 + .../config/remote_action_tool6.json | 325 ++++++++++++++++++ 3 files changed, 351 insertions(+), 8 deletions(-) create mode 100644 flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/agents_manager/config/remote_action_tool6.json diff --git a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java index ec6e5a2be..f89924a18 100644 --- a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java +++ b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java @@ -757,8 +757,9 @@ public TokenBuilder skipFormatting() { public TokenBuilder descriptionDoc(String description) { sb.append(SyntaxKind.HASH_TOKEN.stringValue()) - .append(WHITE_SPACE) - .append(description); + .append(WHITE_SPACE); + + appendDescription(description.split(System.lineSeparator())); if (!description.endsWith(System.lineSeparator())) { sb.append(System.lineSeparator()); } @@ -774,9 +775,12 @@ public TokenBuilder parameterDoc(String paramName, String description) { .append(paramName) .append(WHITE_SPACE) .append("-") - .append(WHITE_SPACE) - .append(description) - .append(System.lineSeparator()); + .append(WHITE_SPACE); + + appendDescription(description.split(System.lineSeparator())); + if (!description.endsWith(System.lineSeparator())) { + sb.append(System.lineSeparator()); + } } return this; } @@ -790,13 +794,26 @@ public TokenBuilder returnDoc(String returnDescription) { .append(SyntaxKind.RETURN_KEYWORD.stringValue()) .append(WHITE_SPACE) .append("-") - .append(WHITE_SPACE) - .append(returnDescription) - .append(System.lineSeparator()); + .append(WHITE_SPACE); + + appendDescription(returnDescription.split(System.lineSeparator())); + if (!returnDescription.endsWith(System.lineSeparator())) { + sb.append(System.lineSeparator()); + } } return this; } + private void appendDescription(String[] descLines) { + sb.append(descLines[0]); + for (int i = 1; i < descLines.length; i++) { + sb.append(System.lineSeparator()); + sb.append(SyntaxKind.HASH_TOKEN.stringValue()) + .append(WHITE_SPACE) + .append(descLines[i]); + } + } + public String build(SourceKind kind) { String outputStr = sb.toString(); if (skipFormatting) { diff --git a/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/java/io/ballerina/flowmodelgenerator/extension/agentsmanager/GenToolsTest.java b/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/java/io/ballerina/flowmodelgenerator/extension/agentsmanager/GenToolsTest.java index 756b1a60a..bf095615a 100644 --- a/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/java/io/ballerina/flowmodelgenerator/extension/agentsmanager/GenToolsTest.java +++ b/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/java/io/ballerina/flowmodelgenerator/extension/agentsmanager/GenToolsTest.java @@ -57,6 +57,7 @@ protected Object[] getConfigsList() { {Path.of("remote_action_tool3.json")}, {Path.of("remote_action_tool4.json")}, {Path.of("remote_action_tool5.json")}, + {Path.of("remote_action_tool6.json")}, }; } diff --git a/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/agents_manager/config/remote_action_tool6.json b/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/agents_manager/config/remote_action_tool6.json new file mode 100644 index 000000000..b796eb79b --- /dev/null +++ b/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/agents_manager/config/remote_action_tool6.json @@ -0,0 +1,325 @@ +{ + "source": "agent_1/agents.bal", + "name": "toolFunc", + "connection": "gmailClient", + "description": "Sample diagram node", + "toolDescription": "", + "diagram": { + "id": "31", + "metadata": { + "label": "get", + "description": "List repositories for a user", + "icon": "https://bcentral-packageicons.azureedge.net/images/ballerinax_github_5.1.0.png" + }, + "codedata": { + "node": "RESOURCE_ACTION_CALL", + "org": "ballerinax", + "module": "github", + "object": "Client", + "symbol": "get", + "isNew": true, + "lineRange": { + "fileName": "agents.bal", + "startLine": { + "line": 13, + "offset": 0 + }, + "endLine": { + "line": 13, + "offset": 0 + } + } + }, + "returning": false, + "properties": { + "connection": { + "metadata": { + "label": "Connection", + "description": "Connection to use" + }, + "valueType": "EXPRESSION", + "valueTypeConstraint": "github:Client", + "value": "connection", + "optional": false, + "editable": false, + "advanced": false, + "hidden": false + }, + "resourcePath": { + "metadata": { + "label": "Resource Path", + "description": "Resource Path" + }, + "valueType": "EXPRESSION", + "value": "resourcePath", + "optional": false, + "editable": false, + "advanced": false, + "hidden": false, + "codedata": { + "originalName": "/users/[username]/repos" + } + }, + "username": { + "metadata": { + "label": "username", + "description": "The handle for the GitHub user account." + }, + "valueType": "EXPRESSION", + "valueTypeConstraint": "string", + "placeholder": "\"\"", + "optional": false, + "editable": true, + "advanced": false, + "hidden": false, + "codedata": { + "kind": "PATH_PARAM", + "originalName": "username" + }, + "typeMembers": [], + "value": "username" + }, + "$type": { + "metadata": { + "label": "type", + "description": "Limit results to repositories of the specified type." + }, + "valueType": "EXPRESSION", + "valueTypeConstraint": "\"all\"|\"owner\"|\"member\"", + "placeholder": "\"owner\"", + "optional": true, + "editable": true, + "advanced": true, + "hidden": false, + "codedata": { + "kind": "DEFAULTABLE", + "originalName": "'type" + }, + "typeMembers": [ + { + "type": "\"all\"", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + }, + { + "type": "\"member\"", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + }, + { + "type": "\"owner\"", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + } + ], + "value": "$type" + }, + "sort": { + "metadata": { + "label": "sort", + "description": "The property to sort the results by." + }, + "valueType": "EXPRESSION", + "valueTypeConstraint": "\"created\"|\"updated\"|\"pushed\"|\"full_name\"", + "placeholder": "\"full_name\"", + "optional": true, + "editable": true, + "advanced": true, + "hidden": false, + "codedata": { + "kind": "DEFAULTABLE", + "originalName": "sort" + }, + "typeMembers": [ + { + "type": "\"created\"", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + }, + { + "type": "\"full_name\"", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + }, + { + "type": "\"pushed\"", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + }, + { + "type": "\"updated\"", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + } + ], + "value": "sort" + }, + "direction": { + "metadata": { + "label": "direction", + "description": "The order to sort by. Default: `asc` when using `full_name`, otherwise `desc`." + }, + "valueType": "EXPRESSION", + "valueTypeConstraint": "\"desc\"|()|\"asc\"", + "placeholder": "()", + "optional": true, + "editable": true, + "advanced": true, + "hidden": false, + "codedata": { + "kind": "DEFAULTABLE", + "originalName": "direction" + }, + "typeMembers": [ + { + "type": "\"asc\"", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + }, + { + "type": "\"desc\"", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + }, + { + "type": "()", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + } + ], + "value": "direction" + }, + "per_page": { + "metadata": { + "label": "per_page", + "description": "The number of results per page (max 100)." + }, + "valueType": "EXPRESSION", + "valueTypeConstraint": "int", + "placeholder": "30", + "optional": true, + "editable": true, + "advanced": true, + "hidden": false, + "codedata": { + "kind": "DEFAULTABLE", + "originalName": "per_page" + }, + "typeMembers": [ + { + "type": "int", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + } + ], + "value": "per_page" + }, + "page": { + "metadata": { + "label": "page", + "description": "Page number of the results to fetch." + }, + "valueType": "EXPRESSION", + "valueTypeConstraint": "int", + "placeholder": "1", + "optional": true, + "editable": true, + "advanced": true, + "hidden": false, + "codedata": { + "kind": "DEFAULTABLE", + "originalName": "page" + }, + "typeMembers": [ + { + "type": "int", + "packageInfo": "", + "kind": "BASIC_TYPE", + "selected": false + } + ], + "value": "page" + }, + "type": { + "metadata": { + "label": "Variable Type", + "description": "Type of the variable" + }, + "valueType": "TYPE", + "value": "github:MinimalRepository[]", + "placeholder": "var", + "optional": false, + "editable": false, + "advanced": false, + "hidden": false, + "codedata": {} + }, + "variable": { + "metadata": { + "label": "Variable Name", + "description": "Name of the variable" + }, + "valueType": "IDENTIFIER", + "value": "githubMinimalrepository", + "optional": false, + "editable": true, + "advanced": false, + "hidden": false + }, + "checkError": { + "metadata": { + "label": "Check Error", + "description": "Trigger error flow" + }, + "valueType": "FLAG", + "value": true, + "optional": false, + "editable": true, + "advanced": true, + "hidden": false + } + }, + "flags": 0 + }, + "output": { + "agent_1/agents.bal": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "import ballerinax/github;" + }, + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "# List repositories for a user\n# + username - The handle for the GitHub user account.\n@ai:AgentTool\n@display {label: \"\",iconPath: \"https://bcentral-packageicons.azureedge.net/images/ballerinax_github_5.1.0.png\"}\nisolated function toolFunc( string username) returns github:MinimalRepository[]| error { github:MinimalRepository[] githubMinimalrepository = check gmailClient-> /users/[username]/repos. get( 'type) ;\nreturn githubMinimalrepository;\n}" + } + ] + } +} From f0d85a0854a7c8fc0e1dca51fb87b4c031ada05d Mon Sep 17 00:00:00 2001 From: Nipuna Ranasinghe Date: Mon, 26 May 2025 21:52:51 +0530 Subject: [PATCH 3/4] Fix merge conflict issues --- .../ballerina/flowmodelgenerator/core/AgentsGenerator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/AgentsGenerator.java b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/AgentsGenerator.java index f2b78a07c..9f0571ebc 100644 --- a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/AgentsGenerator.java +++ b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/AgentsGenerator.java @@ -381,7 +381,7 @@ public JsonElement genTool(JsonElement node, String toolName, String connectionN if (codedata != null) { String kind = codedata.kind(); if (kind != null && kind.equals(ParameterData.Kind.DEFAULTABLE.name())) { - ignoredKeys.add(key); + ignoredKeys.add(k); continue; } } @@ -479,9 +479,9 @@ public JsonElement genTool(JsonElement node, String toolName, String connectionN String kind = codedata.kind(); if (kind.equals(ParameterData.Kind.PATH_PARAM.name()) || kind.equals(ParameterData.Kind.PATH_REST_PARAM.name())) { - pathParams.add(key); + pathParams.add(k); } else if (kind.equals(ParameterData.Kind.DEFAULTABLE.name())) { - ignoredKeys.add(key); + ignoredKeys.add(k); continue; } } From f22e0b86356945615909252c492a6faf92d5136b Mon Sep 17 00:00:00 2001 From: Nipuna Ranasinghe Date: Mon, 26 May 2025 22:17:44 +0530 Subject: [PATCH 4/4] Update failing tests --- .../resources/agents_manager/config/remote_action_tool6.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/agents_manager/config/remote_action_tool6.json b/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/agents_manager/config/remote_action_tool6.json index b796eb79b..945b846fa 100644 --- a/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/agents_manager/config/remote_action_tool6.json +++ b/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/agents_manager/config/remote_action_tool6.json @@ -318,7 +318,7 @@ "character": 0 } }, - "newText": "# List repositories for a user\n# + username - The handle for the GitHub user account.\n@ai:AgentTool\n@display {label: \"\",iconPath: \"https://bcentral-packageicons.azureedge.net/images/ballerinax_github_5.1.0.png\"}\nisolated function toolFunc( string username) returns github:MinimalRepository[]| error { github:MinimalRepository[] githubMinimalrepository = check gmailClient-> /users/[username]/repos. get( 'type) ;\nreturn githubMinimalrepository;\n}" + "newText": "# List repositories for a user\n# + username - The handle for the GitHub user account.\n@ai:AgentTool\n@display {label: \"\",iconPath: \"https://bcentral-packageicons.azureedge.net/images/ballerinax_github_5.1.0.png\"}\nisolated function toolFunc( string username) returns github:MinimalRepository[]| error { github:MinimalRepository[] githubMinimalrepository = check gmailClient-> /users/[username]/repos. get( ) ;\nreturn githubMinimalrepository;\n}" } ] }