From 744214e04cd12b11d166e6eb7da8ce4714904abc Mon Sep 17 00:00:00 2001 From: Wenxin Du <117315983+duwenxin99@users.noreply.github.com> Date: Thu, 4 Dec 2025 13:25:16 -0500 Subject: [PATCH] fix(tools/mongodb): remove `required` tag from the `canonical` field (#2099) The `required` tag raises validation failure error when a boolean field is defined as `false`: ``` ERROR "unable to parse tool file at "mongodb_tools.yaml": unable to parse tool "insert-one-device" as kind "mongodb-insert-one": [2:12] Key: 'Config.Canonical' Error:Field validation for 'Canonical' failed on the 'required' tag\n 1 | authRequired: []\n> 2 | canonical: false\n ^\n 3 | collection: Device\n 4 | database: xiar\n 5 | description: Inserts a single new document into the Device collection. The 'data' parameter must be a string containing the JSON object to insert.\n 6 | " ``` All the `required` tags are removed from the boolean `canonical` field of the MongoDB tools. Unit tests are added. --- .../tools/mongodb/mongodb-insert-many.md | 16 +-- .../tools/mongodb/mongodb-insert-one.md | 16 +-- .../tools/mongodb/mongodb-update-many.md | 26 ++-- .../tools/mongodb/mongodb-update-one.md | 26 ++-- .../mongodbinsertmany/mongodbinsertmany.go | 2 +- .../mongodbinsertmany_test.go | 49 ++++++++ .../mongodbinsertone/mongodbinsertone.go | 2 +- .../mongodbinsertone/mongodbinsertone_test.go | 49 ++++++++ .../mongodbupdatemany/mongodbupdatemany.go | 2 +- .../mongodbupdatemany_test.go | 113 +++++++++++++++++ .../mongodbupdateone/mongodbupdateone.go | 2 +- .../mongodbupdateone/mongodbupdateone_test.go | 117 ++++++++++++++++++ 12 files changed, 374 insertions(+), 46 deletions(-) diff --git a/docs/en/resources/tools/mongodb/mongodb-insert-many.md b/docs/en/resources/tools/mongodb/mongodb-insert-many.md index a126f9da29..cc6c385375 100644 --- a/docs/en/resources/tools/mongodb/mongodb-insert-many.md +++ b/docs/en/resources/tools/mongodb/mongodb-insert-many.md @@ -48,11 +48,11 @@ in the `data` parameter, like this: ## Reference -| **field** | **type** | **required** | **description** | -|:------------|:---------|:-------------|:---------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-insert-many`. | -| source | string | true | The name of the `mongodb` source to use. | -| description | string | true | A description of the tool that is passed to the LLM. | -| database | string | true | The name of the MongoDB database containing the collection. | -| collection | string | true | The name of the MongoDB collection into which the documents will be inserted. | -| canonical | bool | true | Determines if the data string is parsed using MongoDB's Canonical or Relaxed Extended JSON format. | +| **field** | **type** | **required** | **description** | +|:------------|:---------|:-------------|:------------------------------------------------------------------------------------------------------------------------| +| kind | string | true | Must be `mongodb-insert-many`. | +| source | string | true | The name of the `mongodb` source to use. | +| description | string | true | A description of the tool that is passed to the LLM. | +| database | string | true | The name of the MongoDB database containing the collection. | +| collection | string | true | The name of the MongoDB collection into which the documents will be inserted. | +| canonical | bool | false | Determines if the data string is parsed using MongoDB's Canonical or Relaxed Extended JSON format. Defaults to `false`. | diff --git a/docs/en/resources/tools/mongodb/mongodb-insert-one.md b/docs/en/resources/tools/mongodb/mongodb-insert-one.md index d82a332f38..7214f2b4d6 100644 --- a/docs/en/resources/tools/mongodb/mongodb-insert-one.md +++ b/docs/en/resources/tools/mongodb/mongodb-insert-one.md @@ -43,11 +43,11 @@ An LLM would call this tool by providing the document as a JSON string in the ## Reference -| **field** | **type** | **required** | **description** | -|:------------|:---------|:-------------|:---------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-insert-one`. | -| source | string | true | The name of the `mongodb` source to use. | -| description | string | true | A description of the tool that is passed to the LLM. | -| database | string | true | The name of the MongoDB database containing the collection. | -| collection | string | true | The name of the MongoDB collection into which the document will be inserted. | -| canonical | bool | true | Determines if the data string is parsed using MongoDB's Canonical or Relaxed Extended JSON format. | +| **field** | **type** | **required** | **description** | +|:------------|:---------|:-------------|:------------------------------------------------------------------------------------------------------------------------| +| kind | string | true | Must be `mongodb-insert-one`. | +| source | string | true | The name of the `mongodb` source to use. | +| description | string | true | A description of the tool that is passed to the LLM. | +| database | string | true | The name of the MongoDB database containing the collection. | +| collection | string | true | The name of the MongoDB collection into which the document will be inserted. | +| canonical | bool | false | Determines if the data string is parsed using MongoDB's Canonical or Relaxed Extended JSON format. Defaults to `false`. | diff --git a/docs/en/resources/tools/mongodb/mongodb-update-many.md b/docs/en/resources/tools/mongodb/mongodb-update-many.md index 2ed8a1fb6d..ef3b144364 100644 --- a/docs/en/resources/tools/mongodb/mongodb-update-many.md +++ b/docs/en/resources/tools/mongodb/mongodb-update-many.md @@ -57,16 +57,16 @@ tools: ## Reference -| **field** | **type** | **required** | **description** | -|:--------------|:---------|:-------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-update-many`. | -| source | string | true | The name of the `mongodb` source to use. | -| description | string | true | A description of the tool that is passed to the LLM. | -| database | string | true | The name of the MongoDB database containing the collection. | -| collection | string | true | The name of the MongoDB collection in which to update documents. | -| filterPayload | string | true | The MongoDB query filter document to select the documents for updating. It's written as a Go template, using `{{json .param_name}}` to insert parameters. | -| filterParams | list | false | A list of parameter objects that define the variables used in the `filterPayload`. | -| updatePayload | string | true | The MongoDB update document, It's written as a Go template, using `{{json .param_name}}` to insert parameters. | -| updateParams | list | true | A list of parameter objects that define the variables used in the `updatePayload`. | -| canonical | bool | true | Determines if the `filterPayload` and `updatePayload` strings are parsed using MongoDB's Canonical or Relaxed Extended JSON format. **Canonical** is stricter about type representation, while **Relaxed** is more lenient. | -| upsert | bool | false | If `true`, a new document is created if no document matches the `filterPayload`. Defaults to `false`. | +| **field** | **type** | **required** | **description** | +|:--------------|:---------|:-------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| kind | string | true | Must be `mongodb-update-many`. | +| source | string | true | The name of the `mongodb` source to use. | +| description | string | true | A description of the tool that is passed to the LLM. | +| database | string | true | The name of the MongoDB database containing the collection. | +| collection | string | true | The name of the MongoDB collection in which to update documents. | +| filterPayload | string | true | The MongoDB query filter document to select the documents for updating. It's written as a Go template, using `{{json .param_name}}` to insert parameters. | +| filterParams | list | false | A list of parameter objects that define the variables used in the `filterPayload`. | +| updatePayload | string | true | The MongoDB update document, It's written as a Go template, using `{{json .param_name}}` to insert parameters. | +| updateParams | list | true | A list of parameter objects that define the variables used in the `updatePayload`. | +| canonical | bool | false | Determines if the `filterPayload` and `updatePayload` strings are parsed using MongoDB's Canonical or Relaxed Extended JSON format. **Canonical** is stricter about type representation, while **Relaxed** is more lenient. Defaults to `false`. | +| upsert | bool | false | If `true`, a new document is created if no document matches the `filterPayload`. Defaults to `false`. | diff --git a/docs/en/resources/tools/mongodb/mongodb-update-one.md b/docs/en/resources/tools/mongodb/mongodb-update-one.md index 7ecf0662aa..063ea0b192 100644 --- a/docs/en/resources/tools/mongodb/mongodb-update-one.md +++ b/docs/en/resources/tools/mongodb/mongodb-update-one.md @@ -57,16 +57,16 @@ tools: ## Reference -| **field** | **type** | **required** | **description** | -|:--------------|:---------|:-------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-update-one`. | -| source | string | true | The name of the `mongodb` source to use. | -| description | string | true | A description of the tool that is passed to the LLM. | -| database | string | true | The name of the MongoDB database containing the collection. | -| collection | string | true | The name of the MongoDB collection to update a document in. | -| filterPayload | string | true | The MongoDB query filter document to select the document for updating. It's written as a Go template, using `{{json .param_name}}` to insert parameters. | -| filterParams | list | false | A list of parameter objects that define the variables used in the `filterPayload`. | -| updatePayload | string | true | The MongoDB update document, which specifies the modifications. This often uses update operators like `$set`. It's written as a Go template, using `{{json .param_name}}` to insert parameters. | -| updateParams | list | true | A list of parameter objects that define the variables used in the `updatePayload`. | -| canonical | bool | true | Determines if the `updatePayload` string is parsed using MongoDB's Canonical or Relaxed Extended JSON format. **Canonical** is stricter about type representation (e.g., `{"$numberInt": "42"}`), while **Relaxed** is more lenient (e.g., `42`). | -| upsert | bool | false | If `true`, a new document is created if no document matches the `filterPayload`. Defaults to `false`. | +| **field** | **type** | **required** | **description** | +|:--------------|:---------|:-------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| kind | string | true | Must be `mongodb-update-one`. | +| source | string | true | The name of the `mongodb` source to use. | +| description | string | true | A description of the tool that is passed to the LLM. | +| database | string | true | The name of the MongoDB database containing the collection. | +| collection | string | true | The name of the MongoDB collection to update a document in. | +| filterPayload | string | true | The MongoDB query filter document to select the document for updating. It's written as a Go template, using `{{json .param_name}}` to insert parameters. | +| filterParams | list | false | A list of parameter objects that define the variables used in the `filterPayload`. | +| updatePayload | string | true | The MongoDB update document, which specifies the modifications. This often uses update operators like `$set`. It's written as a Go template, using `{{json .param_name}}` to insert parameters. | +| updateParams | list | true | A list of parameter objects that define the variables used in the `updatePayload`. | +| canonical | bool | false | Determines if the `updatePayload` string is parsed using MongoDB's Canonical or Relaxed Extended JSON format. **Canonical** is stricter about type representation (e.g., `{"$numberInt": "42"}`), while **Relaxed** is more lenient (e.g., `42`). Defaults to `false`. | +| upsert | bool | false | If `true`, a new document is created if no document matches the `filterPayload`. Defaults to `false`. | diff --git a/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go b/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go index f3cef20125..ea19e17901 100644 --- a/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go +++ b/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go @@ -54,7 +54,7 @@ type Config struct { Description string `yaml:"description" validate:"required"` Database string `yaml:"database" validate:"required"` Collection string `yaml:"collection" validate:"required"` - Canonical bool `yaml:"canonical" validate:"required"` //i want to force the user to choose + Canonical bool `yaml:"canonical"` } // validate interface diff --git a/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany_test.go b/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany_test.go index 2d8a1cdb30..19ac3ce0c1 100644 --- a/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany_test.go +++ b/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany_test.go @@ -39,6 +39,30 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` + tools: + example_tool: + kind: mongodb-insert-many + source: my-instance + description: some description + database: test_db + collection: test_coll + `, + want: server.ToolConfigs{ + "example_tool": mongodbinsertmany.Config{ + Name: "example_tool", + Kind: "mongodb-insert-many", + Source: "my-instance", + AuthRequired: []string{}, + Database: "test_db", + Collection: "test_coll", + Description: "some description", + Canonical: false, + }, + }, + }, + { + desc: "true canonical", + in: ` tools: example_tool: kind: mongodb-insert-many @@ -61,6 +85,31 @@ func TestParseFromYamlMongoQuery(t *testing.T) { }, }, }, + { + desc: "false canonical", + in: ` + tools: + example_tool: + kind: mongodb-insert-many + source: my-instance + description: some description + database: test_db + collection: test_coll + canonical: false + `, + want: server.ToolConfigs{ + "example_tool": mongodbinsertmany.Config{ + Name: "example_tool", + Kind: "mongodb-insert-many", + Source: "my-instance", + AuthRequired: []string{}, + Database: "test_db", + Collection: "test_coll", + Description: "some description", + Canonical: false, + }, + }, + }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { diff --git a/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go b/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go index aa89b712ad..957dd47e7e 100644 --- a/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go +++ b/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go @@ -54,7 +54,7 @@ type Config struct { Description string `yaml:"description" validate:"required"` Database string `yaml:"database" validate:"required"` Collection string `yaml:"collection" validate:"required"` - Canonical bool `yaml:"canonical" validate:"required"` //i want to force the user to choose + Canonical bool `yaml:"canonical"` } // validate interface diff --git a/internal/tools/mongodb/mongodbinsertone/mongodbinsertone_test.go b/internal/tools/mongodb/mongodbinsertone/mongodbinsertone_test.go index 2e4563efd4..a61dde20b0 100644 --- a/internal/tools/mongodb/mongodbinsertone/mongodbinsertone_test.go +++ b/internal/tools/mongodb/mongodbinsertone/mongodbinsertone_test.go @@ -39,6 +39,30 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` + tools: + example_tool: + kind: mongodb-insert-one + source: my-instance + description: some description + database: test_db + collection: test_coll + `, + want: server.ToolConfigs{ + "example_tool": mongodbinsertone.Config{ + Name: "example_tool", + Kind: "mongodb-insert-one", + Source: "my-instance", + AuthRequired: []string{}, + Database: "test_db", + Collection: "test_coll", + Canonical: false, + Description: "some description", + }, + }, + }, + { + desc: "true canonical", + in: ` tools: example_tool: kind: mongodb-insert-one @@ -61,6 +85,31 @@ func TestParseFromYamlMongoQuery(t *testing.T) { }, }, }, + { + desc: "false canonical", + in: ` + tools: + example_tool: + kind: mongodb-insert-one + source: my-instance + description: some description + database: test_db + collection: test_coll + canonical: false + `, + want: server.ToolConfigs{ + "example_tool": mongodbinsertone.Config{ + Name: "example_tool", + Kind: "mongodb-insert-one", + Source: "my-instance", + AuthRequired: []string{}, + Database: "test_db", + Collection: "test_coll", + Canonical: false, + Description: "some description", + }, + }, + }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { diff --git a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go index ebca8736e3..723e400e3e 100644 --- a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go +++ b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go @@ -56,7 +56,7 @@ type Config struct { FilterParams parameters.Parameters `yaml:"filterParams"` UpdatePayload string `yaml:"updatePayload" validate:"required"` UpdateParams parameters.Parameters `yaml:"updateParams" validate:"required"` - Canonical bool `yaml:"canonical" validate:"required"` + Canonical bool `yaml:"canonical"` Upsert bool `yaml:"upsert"` } diff --git a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go index 209fffc565..b7353afe08 100644 --- a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go +++ b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go @@ -40,6 +40,62 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` + tools: + example_tool: + kind: mongodb-update-many + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + updatePayload: | + { $set: { name: {{json .name}} } } + updateParams: + - name: name + type: string + description: small description + `, + want: server.ToolConfigs{ + "example_tool": mongodbupdatemany.Config{ + Name: "example_tool", + Kind: "mongodb-update-many", + Source: "my-instance", + AuthRequired: []string{}, + Database: "test_db", + Collection: "test_coll", + FilterPayload: "{ name: {{json .name}} }\n", + FilterParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ + Name: "name", + Type: "string", + Desc: "small description", + }, + }, + }, + UpdatePayload: "{ $set: { name: {{json .name}} } }\n", + UpdateParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ + Name: "name", + Type: "string", + Desc: "small description", + }, + }, + }, + Description: "some description", + Canonical: false, + }, + }, + }, + { + desc: "true canonical", + in: ` tools: example_tool: kind: mongodb-update-many @@ -94,6 +150,63 @@ func TestParseFromYamlMongoQuery(t *testing.T) { }, }, }, + { + desc: "false canonical", + in: ` + tools: + example_tool: + kind: mongodb-update-many + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + canonical: false + updatePayload: | + { $set: { name: {{json .name}} } } + updateParams: + - name: name + type: string + description: small description + `, + want: server.ToolConfigs{ + "example_tool": mongodbupdatemany.Config{ + Name: "example_tool", + Kind: "mongodb-update-many", + Source: "my-instance", + AuthRequired: []string{}, + Database: "test_db", + Collection: "test_coll", + FilterPayload: "{ name: {{json .name}} }\n", + FilterParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ + Name: "name", + Type: "string", + Desc: "small description", + }, + }, + }, + UpdatePayload: "{ $set: { name: {{json .name}} } }\n", + UpdateParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ + Name: "name", + Type: "string", + Desc: "small description", + }, + }, + }, + Description: "some description", + Canonical: false, + }, + }, + }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { diff --git a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go index a2d2c909aa..c656353ae6 100644 --- a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go +++ b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go @@ -57,7 +57,7 @@ type Config struct { UpdatePayload string `yaml:"updatePayload" validate:"required"` UpdateParams parameters.Parameters `yaml:"updateParams" validate:"required"` - Canonical bool `yaml:"canonical" validate:"required"` + Canonical bool `yaml:"canonical"` Upsert bool `yaml:"upsert"` } diff --git a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go index 4f0398bd1e..b450892fb2 100644 --- a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go +++ b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go @@ -40,6 +40,123 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` + tools: + example_tool: + kind: mongodb-update-one + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + updatePayload: | + { $set : { item: {{json .item}} } } + updateParams: + - name: item + type: string + description: small description + upsert: true + `, + want: server.ToolConfigs{ + "example_tool": mongodbupdateone.Config{ + Name: "example_tool", + Kind: "mongodb-update-one", + Source: "my-instance", + AuthRequired: []string{}, + Database: "test_db", + Collection: "test_coll", + Canonical: false, + FilterPayload: "{ name: {{json .name}} }\n", + FilterParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ + Name: "name", + Type: "string", + Desc: "small description", + }, + }, + }, + UpdatePayload: "{ $set : { item: {{json .item}} } }\n", + UpdateParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ + Name: "item", + Type: "string", + Desc: "small description", + }, + }, + }, + Upsert: true, + Description: "some description", + }, + }, + }, + { + desc: "false canonical", + in: ` + tools: + example_tool: + kind: mongodb-update-one + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + updatePayload: | + { $set : { item: {{json .item}} } } + updateParams: + - name: item + type: string + description: small description + canonical: false + upsert: true + `, + want: server.ToolConfigs{ + "example_tool": mongodbupdateone.Config{ + Name: "example_tool", + Kind: "mongodb-update-one", + Source: "my-instance", + AuthRequired: []string{}, + Database: "test_db", + Collection: "test_coll", + Canonical: false, + FilterPayload: "{ name: {{json .name}} }\n", + FilterParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ + Name: "name", + Type: "string", + Desc: "small description", + }, + }, + }, + UpdatePayload: "{ $set : { item: {{json .item}} } }\n", + UpdateParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ + Name: "item", + Type: "string", + Desc: "small description", + }, + }, + }, + Upsert: true, + Description: "some description", + }, + }, + }, + { + desc: "true canonical", + in: ` tools: example_tool: kind: mongodb-update-one