From c892bf4b5f8089739b3085d7f52609de08066028 Mon Sep 17 00:00:00 2001 From: Donnie Adams Date: Tue, 4 Feb 2025 15:11:16 -0500 Subject: [PATCH] enhance: use new prompt style for more granular prompts Signed-off-by: Donnie Adams --- apiclient/go.mod | 5 +- apiclient/go.sum | 12 ++--- apiclient/types/invoke.go | 25 +++++++++- apiclient/types/zz_generated.deepcopy.go | 47 ++++++++++++++++++- go.mod | 6 +-- go.sum | 12 ++--- pkg/cli/events/printer.go | 4 +- pkg/controller/creds/creds.go | 17 ++++--- pkg/invoke/invoker.go | 2 +- .../openapi/generated/openapi_generated.go | 39 +++++++++++++-- ui/admin/app/components/chat/Message.tsx | 13 ++--- ui/admin/app/lib/model/chatEvents.ts | 8 +++- ui/user/src/lib/services/chat/types.ts | 8 +++- 13 files changed, 155 insertions(+), 43 deletions(-) diff --git a/apiclient/go.mod b/apiclient/go.mod index 64644e1b1..4fee3cbcc 100644 --- a/apiclient/go.mod +++ b/apiclient/go.mod @@ -4,7 +4,7 @@ go 1.23.1 require ( github.com/getkin/kin-openapi v0.124.0 - github.com/gptscript-ai/go-gptscript v0.9.4 + github.com/gptscript-ai/go-gptscript v0.9.6-0.20250204133419-744b25b84a61 github.com/obot-platform/obot/logger v0.0.0-20241217130503-4004a5c69f32 ) @@ -19,7 +19,6 @@ require ( github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/stretchr/testify v1.9.0 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/apiclient/go.sum b/apiclient/go.sum index 717313f22..7ac96c4d1 100644 --- a/apiclient/go.sum +++ b/apiclient/go.sum @@ -10,8 +10,8 @@ github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicb github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/gptscript-ai/go-gptscript v0.9.4 h1:4PDn1NW7ErUsWJIuxyK7G3aXGxA33TZrrMuSfH0S09c= -github.com/gptscript-ai/go-gptscript v0.9.4/go.mod h1:Dh6vYRAiVcyC3ElZIGzTvNF1FxtYwA07BHfSiFKQY7s= +github.com/gptscript-ai/go-gptscript v0.9.6-0.20250204133419-744b25b84a61 h1:QxLjsLOYlsVLPwuRkP0Q8EcAoZT1s8vU2ZBSX0+R6CI= +github.com/gptscript-ai/go-gptscript v0.9.6-0.20250204133419-744b25b84a61/go.mod h1:/FVuLwhz+sIfsWUgUHWKi32qT0i6+IXlUlzs70KKt/Q= github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -37,13 +37,13 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apiclient/types/invoke.go b/apiclient/types/invoke.go index ba5136d75..ecc9c846d 100644 --- a/apiclient/types/invoke.go +++ b/apiclient/types/invoke.go @@ -1,5 +1,7 @@ package types +import "github.com/gptscript-ai/go-gptscript" + // +k8s:deepcopy-gen=false // +k8s:openapi-gen=false @@ -79,11 +81,32 @@ type Prompt struct { Description string `json:"description,omitempty"` Time *Time `json:"time,omitempty"` Message string `json:"message,omitempty"` - Fields []string `json:"fields,omitempty"` + Fields Fields `json:"fields,omitempty"` Sensitive bool `json:"sensitive,omitempty"` Metadata map[string]string `json:"metadata,omitempty"` } +// Field should match exactly what is in the GPTScript SDK +type Field struct { + Name string `json:"name,omitempty"` + Sensitive *bool `json:"sensitive,omitempty"` + Description string `json:"description,omitempty"` +} + +type Fields []Field + +func ToFields(fields gptscript.Fields) Fields { + f := make(Fields, len(fields)) + for i, field := range fields { + f[i] = Field{ + Name: field.Name, + Sensitive: field.Sensitive, + Description: field.Description, + } + } + return f +} + type ToolInput struct { Name string `json:"name,omitempty"` Description string `json:"description,omitempty"` diff --git a/apiclient/types/zz_generated.deepcopy.go b/apiclient/types/zz_generated.deepcopy.go index 98a6d3cc6..23311ab4b 100644 --- a/apiclient/types/zz_generated.deepcopy.go +++ b/apiclient/types/zz_generated.deepcopy.go @@ -671,6 +671,47 @@ func (in *ErrHTTP) DeepCopy() *ErrHTTP { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Field) DeepCopyInto(out *Field) { + *out = *in + if in.Sensitive != nil { + in, out := &in.Sensitive, &out.Sensitive + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Field. +func (in *Field) DeepCopy() *Field { + if in == nil { + return nil + } + out := new(Field) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Fields) DeepCopyInto(out *Fields) { + { + in := &in + *out = make(Fields, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Fields. +func (in Fields) DeepCopy() Fields { + if in == nil { + return nil + } + out := new(Fields) + in.DeepCopyInto(out) + return *out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *File) DeepCopyInto(out *File) { *out = *in @@ -1366,8 +1407,10 @@ func (in *Prompt) DeepCopyInto(out *Prompt) { } if in.Fields != nil { in, out := &in.Fields, &out.Fields - *out = make([]string, len(*in)) - copy(*out, *in) + *out = make(Fields, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.Metadata != nil { in, out := &in.Metadata, &out.Metadata diff --git a/go.mod b/go.mod index 3d3d0d170..c32117a0e 100644 --- a/go.mod +++ b/go.mod @@ -18,8 +18,8 @@ require ( github.com/gorilla/websocket v1.5.0 github.com/gptscript-ai/chat-completion-client v0.0.0-20250128181713-57857b74f9f1 github.com/gptscript-ai/cmd v0.0.0-20250122115124-a3d65e9d2432 - github.com/gptscript-ai/go-gptscript v0.9.6-0.20241216211344-79a66826cf82 - github.com/gptscript-ai/gptscript v0.9.6-0.20250128190959-7ee5c807d2b9 + github.com/gptscript-ai/go-gptscript v0.9.6-0.20250204133419-744b25b84a61 + github.com/gptscript-ai/gptscript v0.9.6-0.20250204193143-468c4f1a3cd9 github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de github.com/mhale/smtpd v0.8.3 github.com/obot-platform/kinm v0.0.0-20250116162656-270198b40c6d @@ -129,7 +129,7 @@ require ( github.com/gookit/color v1.5.4 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/gptscript-ai/broadcaster v0.0.0-20240625175512-c43682019b86 // indirect - github.com/gptscript-ai/tui v0.0.0-20240923192013-172e51ccf1d6 // indirect + github.com/gptscript-ai/tui v0.0.0-20250204145344-33cd15de4cee // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect diff --git a/go.sum b/go.sum index db49a65de..c2d7114d2 100644 --- a/go.sum +++ b/go.sum @@ -299,12 +299,12 @@ github.com/gptscript-ai/chat-completion-client v0.0.0-20250128181713-57857b74f9f github.com/gptscript-ai/chat-completion-client v0.0.0-20250128181713-57857b74f9f1/go.mod h1:7P/o6/IWa1KqsntVf68hSnLKuu3+xuqm6lYhch1w4jo= github.com/gptscript-ai/cmd v0.0.0-20250122115124-a3d65e9d2432 h1:cJh/Hl1HFd1qLpdkaZvsFTC2mXlIuiK7FgvSfaSOWmw= github.com/gptscript-ai/cmd v0.0.0-20250122115124-a3d65e9d2432/go.mod h1:DJAo1xTht1LDkNYFNydVjTHd576TC7MlpsVRl3oloVw= -github.com/gptscript-ai/go-gptscript v0.9.6-0.20241216211344-79a66826cf82 h1:BEN268Z92gqeDc51XVvWdJWdQ47BuuWH3MUysHzilfI= -github.com/gptscript-ai/go-gptscript v0.9.6-0.20241216211344-79a66826cf82/go.mod h1:/FVuLwhz+sIfsWUgUHWKi32qT0i6+IXlUlzs70KKt/Q= -github.com/gptscript-ai/gptscript v0.9.6-0.20250128190959-7ee5c807d2b9 h1:biFzueEkd6DO7YCO5lR4syFK2lDzLhpUlbGrHf7/B04= -github.com/gptscript-ai/gptscript v0.9.6-0.20250128190959-7ee5c807d2b9/go.mod h1:3Vm532vjbbtZk6tcHdKm7RuI5rOppCb3NLecOWhTStw= -github.com/gptscript-ai/tui v0.0.0-20240923192013-172e51ccf1d6 h1:vkgNZVWQgbE33VD3z9WKDwuu7B/eJVVMMPM62ixfCR8= -github.com/gptscript-ai/tui v0.0.0-20240923192013-172e51ccf1d6/go.mod h1:frrl/B+ZH3VSs3Tqk2qxEIIWTONExX3tuUa4JsVnqx4= +github.com/gptscript-ai/go-gptscript v0.9.6-0.20250204133419-744b25b84a61 h1:QxLjsLOYlsVLPwuRkP0Q8EcAoZT1s8vU2ZBSX0+R6CI= +github.com/gptscript-ai/go-gptscript v0.9.6-0.20250204133419-744b25b84a61/go.mod h1:/FVuLwhz+sIfsWUgUHWKi32qT0i6+IXlUlzs70KKt/Q= +github.com/gptscript-ai/gptscript v0.9.6-0.20250204193143-468c4f1a3cd9 h1:MdmM6ZcEXUc8mTHSAs8jrBQ6lSAQVog5HrNCptVCOZA= +github.com/gptscript-ai/gptscript v0.9.6-0.20250204193143-468c4f1a3cd9/go.mod h1:uvb92bYHRX9wFHSS1jkg5Y7GBQgTb8iHP+l/wPsWCx8= +github.com/gptscript-ai/tui v0.0.0-20250204145344-33cd15de4cee h1:70PHW6Xw70yNNZ5aX936XqcMLwNmfMZpCV3FCOGKpxE= +github.com/gptscript-ai/tui v0.0.0-20250204145344-33cd15de4cee/go.mod h1:iwHxuueg2paOak7zIg0ESBWx7A0wIHGopAratbgaPNY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= diff --git a/pkg/cli/events/printer.go b/pkg/cli/events/printer.go index a1fcec1ed..52b85573f 100644 --- a/pkg/cli/events/printer.go +++ b/pkg/cli/events/printer.go @@ -135,7 +135,7 @@ func handlePrompt(ctx context.Context, c *apiclient.Client, prompt *types.Prompt } for _, field := range prompt.Fields { - v, err := textio.Ask(field, "") + v, err := textio.Ask(field.Name, "") if err != nil { return err } @@ -147,7 +147,7 @@ func handlePrompt(ctx context.Context, c *apiclient.Client, prompt *types.Prompt v = string(data) } } - promptResponse.Responses[field] = v + promptResponse.Responses[field.Name] = v } if len(promptResponse.Responses) == 0 { diff --git a/pkg/controller/creds/creds.go b/pkg/controller/creds/creds.go index 932818a5b..793045858 100644 --- a/pkg/controller/creds/creds.go +++ b/pkg/controller/creds/creds.go @@ -63,11 +63,11 @@ func DetermineCredsAndCredNames(prg *gptscript.Program, tool gptscript.Tool, nam return credentials, credentialNames, nil } -func determineCredentialNames(prg *gptscript.Program, tool gptscript.Tool, toolName string, noAuth map[string]struct{}) ([]string, error) { +func determineCredentialNames(prg *gptscript.Program, tool gptscript.Tool, credToolName string, noAuth map[string]struct{}) ([]string, error) { var subTool string - parsedToolName, alias, args, err := gtypes.ParseCredentialArgs(toolName, "") + parsedToolName, alias, args, err := gtypes.ParseCredentialArgs(credToolName, "") if err != nil { - parsedToolName, subTool = gtypes.SplitToolRef(toolName) + parsedToolName, subTool = gtypes.SplitToolRef(credToolName) parsedToolName, alias, args, err = gtypes.ParseCredentialArgs(parsedToolName, "") if err != nil { return nil, err @@ -88,18 +88,21 @@ func determineCredentialNames(prg *gptscript.Program, tool gptscript.Tool, toolN } if args != nil { - return []string{toolName}, nil + if _, ok := noAuth[alias]; !ok { + return []string{credToolName}, nil + } + return nil, nil } // This is a tool and not the credential format. Parse the tool from the program to determine the alias toolNames := make([]string, 0, len(tool.Credentials)) if subTool == "" { - toolName = parsedToolName + credToolName = parsedToolName } for _, cred := range tool.Credentials { - if cred == toolName { + if cred == credToolName { if len(tool.ToolMapping[cred]) == 0 { - return nil, fmt.Errorf("cannot find credential name for tool %q", toolName) + return nil, fmt.Errorf("cannot find credential name for tool %q", credToolName) } for _, ref := range tool.ToolMapping[cred] { diff --git a/pkg/invoke/invoker.go b/pkg/invoke/invoker.go index cf0b61b5b..0f8bd42e4 100644 --- a/pkg/invoke/invoker.go +++ b/pkg/invoke/invoker.go @@ -979,7 +979,7 @@ func (i *Invoker) stream(ctx context.Context, c kclient.WithWatch, prevThreadNam Description: callingTool.Description, Time: types.NewTime(frame.Prompt.Time), Message: frame.Prompt.Message, - Fields: frame.Prompt.Fields, + Fields: types.ToFields(frame.Prompt.Fields), Sensitive: frame.Prompt.Sensitive, Metadata: metadata, } diff --git a/pkg/storage/openapi/generated/openapi_generated.go b/pkg/storage/openapi/generated/openapi_generated.go index dc4b13808..886921b4d 100644 --- a/pkg/storage/openapi/generated/openapi_generated.go +++ b/pkg/storage/openapi/generated/openapi_generated.go @@ -45,6 +45,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/obot-platform/obot/apiclient/types.EmailReceiverManifest": schema_obot_platform_obot_apiclient_types_EmailReceiverManifest(ref), "github.com/obot-platform/obot/apiclient/types.EnvVar": schema_obot_platform_obot_apiclient_types_EnvVar(ref), "github.com/obot-platform/obot/apiclient/types.ErrHTTP": schema_obot_platform_obot_apiclient_types_ErrHTTP(ref), + "github.com/obot-platform/obot/apiclient/types.Field": schema_obot_platform_obot_apiclient_types_Field(ref), "github.com/obot-platform/obot/apiclient/types.File": schema_obot_platform_obot_apiclient_types_File(ref), "github.com/obot-platform/obot/apiclient/types.FileList": schema_obot_platform_obot_apiclient_types_FileList(ref), "github.com/obot-platform/obot/apiclient/types.If": schema_obot_platform_obot_apiclient_types_If(ref), @@ -1561,6 +1562,37 @@ func schema_obot_platform_obot_apiclient_types_ErrHTTP(ref common.ReferenceCallb } } +func schema_obot_platform_obot_apiclient_types_Field(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Field should match exactly what is in the GPTScript SDK", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "sensitive": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_obot_platform_obot_apiclient_types_File(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2895,9 +2927,8 @@ func schema_obot_platform_obot_apiclient_types_Prompt(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Default: map[string]interface{}{}, + Ref: ref("github.com/obot-platform/obot/apiclient/types.Field"), }, }, }, @@ -2928,7 +2959,7 @@ func schema_obot_platform_obot_apiclient_types_Prompt(ref common.ReferenceCallba }, }, Dependencies: []string{ - "github.com/obot-platform/obot/apiclient/types.Time"}, + "github.com/obot-platform/obot/apiclient/types.Field", "github.com/obot-platform/obot/apiclient/types.Time"}, } } diff --git a/ui/admin/app/components/chat/Message.tsx b/ui/admin/app/components/chat/Message.tsx index 02736bf51..ea0ac8344 100644 --- a/ui/admin/app/components/chat/Message.tsx +++ b/ui/admin/app/components/chat/Message.tsx @@ -196,7 +196,7 @@ export function PromptMessage({ return (
>({ defaultValues: prompt.fields?.reduce( (acc, field) => { - acc[field] = ""; + acc[field.name] = ""; return acc; }, {} as Record @@ -327,11 +327,12 @@ export function PromptAuthForm({
{prompt.fields?.map((field) => ( ))} diff --git a/ui/admin/app/lib/model/chatEvents.ts b/ui/admin/app/lib/model/chatEvents.ts index 8499d3620..cb9089abc 100644 --- a/ui/admin/app/lib/model/chatEvents.ts +++ b/ui/admin/app/lib/model/chatEvents.ts @@ -28,11 +28,17 @@ export type AuthPrompt = { name: string; time?: Date; message: string; - fields?: string[]; + fields?: PromptField[]; sensitive?: boolean; metadata?: PromptAuthMeta; }; +export type PromptField = { + name: string; + description?: string; + sensitive?: boolean; +}; + // note(ryanhopperlowe) renaming this to ChatEvent to differentiate itself specifically for a chat with an agent // we should create a separate type for WorkflowEvents and leverage Unions to differentiate between them export type ChatEvent = { diff --git a/ui/user/src/lib/services/chat/types.ts b/ui/user/src/lib/services/chat/types.ts index 3bb2d1dc6..bcdb4c814 100644 --- a/ui/user/src/lib/services/chat/types.ts +++ b/ui/user/src/lib/services/chat/types.ts @@ -35,11 +35,17 @@ type Prompt = { description?: string; time: string; message?: string; - fields?: string[]; + fields?: PromptField[]; sensitive?: boolean; metadata?: { [key: string]: string }; }; +type PromptField = { + name: string; + description?: string; + sensitive?: boolean; +}; + type ToolInput = { name?: string; description?: string;