diff --git a/go/ai/prompt.go b/go/ai/prompt.go index 3949327409..5fb25cfb8e 100644 --- a/go/ai/prompt.go +++ b/go/ai/prompt.go @@ -38,7 +38,6 @@ func DefinePrompt(provider, name string, metadata map[string]any, render func(co mm = make(map[string]any) } mm["type"] = "prompt" - mm["prompt"] = true // required by genkit ui return core.DefineActionWithInputSchema(provider, name, atype.Prompt, mm, render, inputSchema) } diff --git a/go/core/action.go b/go/core/action.go index 5a30c9467e..44a2f46044 100644 --- a/go/core/action.go +++ b/go/core/action.go @@ -73,8 +73,8 @@ func DefineAction[In, Out any](provider, name string, atype atype.ActionType, me } func defineAction[In, Out any](r *registry, provider, name string, atype atype.ActionType, metadata map[string]any, fn func(context.Context, In) (Out, error)) *Action[In, Out, struct{}] { - a := newAction(name, atype, metadata, fn) - r.registerAction(provider, a) + a := newAction(provider+"/"+name, atype, metadata, fn) + r.registerAction(a) return a } @@ -83,8 +83,8 @@ func DefineStreamingAction[In, Out, Stream any](provider, name string, atype aty } func defineStreamingAction[In, Out, Stream any](r *registry, provider, name string, atype atype.ActionType, metadata map[string]any, fn Func[In, Out, Stream]) *Action[In, Out, Stream] { - a := newStreamingAction(name, atype, metadata, fn) - r.registerAction(provider, a) + a := newStreamingAction(provider+"/"+name, atype, metadata, fn) + r.registerAction(a) return a } @@ -101,8 +101,8 @@ func DefineActionWithInputSchema[Out any](provider, name string, atype atype.Act } func defineActionWithInputSchema[Out any](r *registry, provider, name string, atype atype.ActionType, metadata map[string]any, fn func(context.Context, any) (Out, error), inputSchema *jsonschema.Schema) *Action[any, Out, struct{}] { - a := newActionWithInputSchema(name, atype, metadata, fn, inputSchema) - r.registerAction(provider, a) + a := newActionWithInputSchema(provider+"/"+name, atype, metadata, fn, inputSchema) + r.registerAction(a) return a } diff --git a/go/core/conformance_test.go b/go/core/conformance_test.go index 803fe04c24..9236682ab5 100644 --- a/go/core/conformance_test.go +++ b/go/core/conformance_test.go @@ -97,7 +97,7 @@ func TestFlowConformance(t *testing.T) { t.Fatal(err) } _ = defineFlow(r, test.Name, flowFunction(test.Commands)) - key := fmt.Sprintf("/flow/%s/%[1]s", test.Name) + key := fmt.Sprintf("/flow/%s", test.Name) resp, err := runAction(context.Background(), r, key, test.Input, nil) if err != nil { t.Fatal(err) diff --git a/go/core/flow.go b/go/core/flow.go index 63b0234cf9..73c9a4e7a9 100644 --- a/go/core/flow.go +++ b/go/core/flow.go @@ -119,7 +119,7 @@ func defineFlow[In, Out, Stream any](r *registry, name string, fn Func[In, Out, // TODO(jba): set stateStore? } a := f.action() - r.registerAction(name, a) + r.registerAction(a) // TODO(jba): this is a roundabout way to transmit the tracing state. Is there a cleaner way? f.tstate = a.tstate r.registerFlow(f) diff --git a/go/core/registry.go b/go/core/registry.go index de5b278643..55385bfa08 100644 --- a/go/core/registry.go +++ b/go/core/registry.go @@ -94,8 +94,8 @@ const ( // registerAction records the action in the registry. // It panics if an action with the same type, provider and name is already // registered. -func (r *registry) registerAction(provider string, a action) { - key := fmt.Sprintf("/%s/%s/%s", a.actionType(), provider, a.Name()) +func (r *registry) registerAction(a action) { + key := fmt.Sprintf("/%s/%s", a.actionType(), a.Name()) r.mu.Lock() defer r.mu.Unlock() if _, ok := r.actions[key]; ok { @@ -105,7 +105,6 @@ func (r *registry) registerAction(provider string, a action) { r.actions[key] = a slog.Info("RegisterAction", "type", a.actionType(), - "provider", provider, "name", a.Name()) } diff --git a/go/core/servers_test.go b/go/core/servers_test.go index 9ffa475819..3db86ca73a 100644 --- a/go/core/servers_test.go +++ b/go/core/servers_test.go @@ -39,10 +39,10 @@ func TestDevServer(t *testing.T) { if err != nil { t.Fatal(err) } - r.registerAction("devServer", newAction("inc", atype.Custom, map[string]any{ + r.registerAction(newAction("devServer/inc", atype.Custom, map[string]any{ "foo": "bar", }, inc)) - r.registerAction("devServer", newAction("dec", atype.Custom, map[string]any{ + r.registerAction(newAction("devServer/dec", atype.Custom, map[string]any{ "bar": "baz", }, dec)) srv := httptest.NewServer(newDevServeMux(r)) @@ -87,7 +87,7 @@ func TestDevServer(t *testing.T) { want := map[string]actionDesc{ "/custom/devServer/inc": { Key: "/custom/devServer/inc", - Name: "inc", + Name: "devServer/inc", InputSchema: &jsonschema.Schema{Type: "integer"}, OutputSchema: &jsonschema.Schema{Type: "integer"}, Metadata: map[string]any{"foo": "bar"}, @@ -96,7 +96,7 @@ func TestDevServer(t *testing.T) { Key: "/custom/devServer/dec", InputSchema: &jsonschema.Schema{Type: "integer"}, OutputSchema: &jsonschema.Schema{Type: "integer"}, - Name: "dec", + Name: "devServer/dec", Metadata: map[string]any{"bar": "baz"}, }, } diff --git a/go/plugins/dotprompt/dotprompt.go b/go/plugins/dotprompt/dotprompt.go index 457326342d..8c1b5385fc 100644 --- a/go/plugins/dotprompt/dotprompt.go +++ b/go/plugins/dotprompt/dotprompt.go @@ -63,9 +63,12 @@ type Prompt struct { Config - // The template for the prompt. + // The parsed prompt template. Template *raymond.Template + // The original prompt template text. + TemplateText string + // A hash of the prompt contents. hash string @@ -197,10 +200,11 @@ func newPrompt(name, templateText, hash string, config Config) (*Prompt, error) } template.RegisterHelpers(templateHelpers) return &Prompt{ - Name: name, - Config: config, - hash: hash, - Template: template, + Name: name, + Config: config, + hash: hash, + Template: template, + TemplateText: templateText, }, nil } diff --git a/go/plugins/dotprompt/genkit.go b/go/plugins/dotprompt/genkit.go index 814a1bbbe3..6d20c67c4c 100644 --- a/go/plugins/dotprompt/genkit.go +++ b/go/plugins/dotprompt/genkit.go @@ -52,8 +52,11 @@ func (p *Prompt) buildVariables(variables any) (map[string]any, error) { } v := reflect.Indirect(reflect.ValueOf(variables)) + if v.Kind() == reflect.Map { + return variables.(map[string]any), nil + } if v.Kind() != reflect.Struct { - return nil, errors.New("dotprompt: fields not a struct or pointer to a struct") + return nil, errors.New("dotprompt: fields not a struct or pointer to a struct or a map") } vt := v.Type() @@ -138,7 +141,18 @@ func (p *Prompt) Register() error { name += "." + p.Variant } - p.action = ai.DefinePrompt("dotprompt", name, nil, p.buildRequest, p.Config.InputSchema) + // TODO: Undo clearing of the Version once Monaco Editor supports newer than JSON schema draft-07. + p.InputSchema.Version = "" + + metadata := map[string]any{ + "prompt": map[string]any{ + "name": p.Name, + "input": map[string]any{"schema": p.InputSchema}, + "output": map[string]any{"format": p.OutputFormat}, + "template": p.TemplateText, + }, + } + p.action = ai.DefinePrompt("dotprompt", name, metadata, p.buildRequest, p.Config.InputSchema) return nil } diff --git a/go/plugins/localvec/localvec_test.go b/go/plugins/localvec/localvec_test.go index b888018a23..30774681e5 100644 --- a/go/plugins/localvec/localvec_test.go +++ b/go/plugins/localvec/localvec_test.go @@ -197,7 +197,7 @@ func TestInit(t *testing.T) { if err != nil { t.Fatal(err) } - want := []string{"a", "b"} + want := []string{"devLocalVectorStore/a", "devLocalVectorStore/b"} if got := names(is); !slices.Equal(got, want) { t.Errorf("got %v, want %v", got, want) diff --git a/go/samples/coffee-shop/main.go b/go/samples/coffee-shop/main.go index 92c857395e..9cfda041f1 100755 --- a/go/samples/coffee-shop/main.go +++ b/go/samples/coffee-shop/main.go @@ -109,11 +109,15 @@ func main() { log.Fatal(err) } + r := &jsonschema.Reflector{ + AllowAdditionalProperties: false, + DoNotReference: true, + } g := googleai.Model("gemini-1.5-pro") simpleGreetingPrompt, err := dotprompt.Define("simpleGreeting", simpleGreetingPromptTemplate, dotprompt.Config{ ModelAction: g, - InputSchema: jsonschema.Reflect(simpleGreetingInput{}), + InputSchema: r.Reflect(simpleGreetingInput{}), OutputFormat: ai.OutputFormatText, }, ) @@ -176,10 +180,6 @@ func main() { return text, nil }) - r := &jsonschema.Reflector{ - AllowAdditionalProperties: false, - DoNotReference: true, - } schema := r.Reflect(simpleGreetingOutput{}) jsonBytes, err := schema.MarshalJSON() if err != nil {