fix: add items to parameter manifest (#293)

`items` are not specified in the manifest for parameters, which means
the client doesn't parse them correctly when presented to the LLMs. This
PR adds `items` as part of manifest.

Example manifest:
```
{
    "serverVersion": "0.1.0",
    "tools": {
        "tool_name": {
            "description": "description of the tool...",
            "parameters": [{
                "name": "foos",
                "type": "array",
                "description": "A list of foo.",
                "authSources": [],
                "items": {"name": "foo", "type": "string", "description": "foobar.", "authSources": []}
            }]
        }
    }
}
```

Fixes #292 🦕
This commit is contained in:
Yuan
2025-02-14 15:29:16 -08:00
committed by GitHub
parent 914f8437b1
commit 541612d72d
2 changed files with 71 additions and 6 deletions

View File

@@ -234,11 +234,11 @@ func (ps Parameters) Manifest() []ParameterManifest {
// ParameterManifest represents parameters when served as part of a ToolManifest. // ParameterManifest represents parameters when served as part of a ToolManifest.
type ParameterManifest struct { type ParameterManifest struct {
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
Description string `json:"description"` Description string `json:"description"`
AuthSources []string `json:"authSources"` AuthSources []string `json:"authSources"`
// Parameter *ParameterManifest `json:"parameter,omitempty"` Items *ParameterManifest `json:"items,omitempty"`
} }
// CommonParameter are default fields that are emebdding in most Parameter implementations. Embedding this stuct will give the object Name() and Type() functions. // CommonParameter are default fields that are emebdding in most Parameter implementations. Embedding this stuct will give the object Name() and Type() functions.
@@ -259,7 +259,7 @@ func (p *CommonParameter) GetType() string {
return p.Type return p.Type
} }
// GetType returns the type specified for the Parameter. // Manifest returns the manifest for the Parameter.
func (p *CommonParameter) Manifest() ParameterManifest { func (p *CommonParameter) Manifest() ParameterManifest {
// only list ParamAuthSource names (without fields) in manifest // only list ParamAuthSource names (without fields) in manifest
authNames := make([]string, len(p.AuthSources)) authNames := make([]string, len(p.AuthSources))
@@ -560,3 +560,20 @@ func (p *ArrayParameter) Parse(v any) (any, error) {
func (p *ArrayParameter) GetAuthSources() []ParamAuthSource { func (p *ArrayParameter) GetAuthSources() []ParamAuthSource {
return p.AuthSources return p.AuthSources
} }
// Manifest returns the manifest for the ArrayParameter.
func (p *ArrayParameter) Manifest() ParameterManifest {
// only list ParamAuthSource names (without fields) in manifest
authNames := make([]string, len(p.AuthSources))
for i, a := range p.AuthSources {
authNames[i] = a.Name
}
items := p.Items.Manifest()
return ParameterManifest{
Name: p.Name,
Type: p.Type,
Description: p.Desc,
AuthSources: authNames,
Items: &items,
}
}

View File

@@ -661,3 +661,51 @@ func TestParamValues(t *testing.T) {
}) })
} }
} }
func TestParamManifest(t *testing.T) {
tcs := []struct {
name string
in tools.Parameter
want tools.ParameterManifest
}{
{
name: "string",
in: tools.NewStringParameter("foo-string", "bar"),
want: tools.ParameterManifest{Name: "foo-string", Type: "string", Description: "bar", AuthSources: []string{}},
},
{
name: "int",
in: tools.NewIntParameter("foo-int", "bar"),
want: tools.ParameterManifest{Name: "foo-int", Type: "integer", Description: "bar", AuthSources: []string{}},
},
{
name: "float",
in: tools.NewFloatParameter("foo-float", "bar"),
want: tools.ParameterManifest{Name: "foo-float", Type: "float", Description: "bar", AuthSources: []string{}},
},
{
name: "boolean",
in: tools.NewBooleanParameter("foo-bool", "bar"),
want: tools.ParameterManifest{Name: "foo-bool", Type: "boolean", Description: "bar", AuthSources: []string{}},
},
{
name: "array",
in: tools.NewArrayParameter("foo-array", "bar", tools.NewStringParameter("foo-string", "bar")),
want: tools.ParameterManifest{
Name: "foo-array",
Type: "array",
Description: "bar",
AuthSources: []string{},
Items: &tools.ParameterManifest{Name: "foo-string", Type: "string", Description: "bar", AuthSources: []string{}},
},
},
}
for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) {
got := tc.in.Manifest()
if !reflect.DeepEqual(got, tc.want) {
t.Fatalf("unexpected manifest: got %+v, want %+v", got, tc.want)
}
})
}
}