MCP Terminal Server

// Copyright 2024 Google LLC // SPDX-License-Identifier: Apache-2.0 package main import ( "context" "slices" "github.com/firebase/genkit/go/ai" "github.com/firebase/genkit/go/genkit" "github.com/firebase/genkit/go/plugins/dotprompt" ) type chatSessionInput struct { SessionID string `json:"sessionID"` Question string `json:"question"` } type chatSessionOutput struct { SessionID string `json:"sessionID"` History []*ai.Message `json:"history"` } // Very simple local storage for chat history. // Each conversation is identified by a sessionID generated by the application. // The history has a preamble of message, which serves as a system prompt. type chatHistory []*ai.Message type chatHistoryStore struct { preamble chatHistory sessions map[string]chatHistory } func (ch *chatHistoryStore) Store(sessionID string, history chatHistory) { ch.sessions[sessionID] = history } func (ch *chatHistoryStore) Retrieve(sessionID string) chatHistory { if h, ok := ch.sessions[sessionID]; ok { return h } return ch.preamble } func setup03(g *genkit.Genkit, m ai.Model) error { chatPreamblePrompt, err := dotprompt.Define(g, "s03_chatPreamble", ` {{ role "user" }} Hi. What's on the menu today? {{ role "model" }} I am Walt, a helpful AI assistant here at the restaurant. I can answer questions about the food on the menu or any other questions you have about food in general. I probably can't help you with anything else. Here is today's menu: {{#each menuData~}} - {{this.title}} \${{this.price}} {{this.description}} {{~/each}} Do you have any questions about the menu?`, dotprompt.WithDefaultModel(m), dotprompt.WithInputType(dataMenuQuestionInput{}), dotprompt.WithOutputFormat(ai.OutputFormatText), dotprompt.WithDefaultConfig(&ai.GenerationCommonConfig{ Temperature: 0.3, }), ) if err != nil { return err } menuData, err := menu(&ai.ToolContext{Context: context.Background()}, nil) if err != nil { return err } preamble, err := chatPreamblePrompt.RenderMessages(map[string]any{ "menuData": menuData, "question": "", }) if err != nil { return err } storedHistory := &chatHistoryStore{ preamble: chatHistory(preamble), sessions: make(map[string]chatHistory), } genkit.DefineFlow(g, "s03_multiTurnChat", func(ctx context.Context, input *chatSessionInput) (*chatSessionOutput, error) { history := storedHistory.Retrieve(input.SessionID) msg := &ai.Message{ Content: []*ai.Part{ ai.NewTextPart(input.Question), }, Role: ai.RoleUser, } messages := append(slices.Clip(history), msg) resp, err := genkit.Generate(ctx, g, ai.WithModel(m), ai.WithMessages(messages...)) if err != nil { return nil, err } messages = append(messages, resp.Message) storedHistory.Store(input.SessionID, messages) out := &chatSessionOutput{ SessionID: input.SessionID, History: messages, } return out, nil }, ) return nil }