Consolidated a bunch of reused code to agents
This commit is contained in:
		
							
								
								
									
										151
									
								
								cmd/console/cmd.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								cmd/console/cmd.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"log/slog" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"gitea.stevedudenhoeffer.com/steve/answer/pkg/agents" | ||||
|  | ||||
| 	"gitea.stevedudenhoeffer.com/steve/answer/pkg/agents/console" | ||||
|  | ||||
| 	gollm "gitea.stevedudenhoeffer.com/steve/go-llm" | ||||
|  | ||||
| 	"github.com/joho/godotenv" | ||||
| 	"github.com/urfave/cli" | ||||
| ) | ||||
|  | ||||
| func getKey(key string, env string) string { | ||||
| 	if key != "" { | ||||
| 		return key | ||||
| 	} | ||||
|  | ||||
| 	return os.Getenv(env) | ||||
| } | ||||
|  | ||||
| func main() { | ||||
| 	// Usage: go run cmd/answer.go question... | ||||
| 	// - flags: | ||||
| 	//   --model=[model string such as openai/gpt-4o, anthropic/claude..., google/gemini-1.5.  Default: openai/gpt-4o] | ||||
| 	//   --search-provider=[search provider string such as google, duckduckgo.  Default: google] | ||||
| 	//	 --cache-provider=[cache provider string such as memory, redis, file.  Default: memory] | ||||
|  | ||||
| 	var app = cli.App{ | ||||
| 		Name:        "console", | ||||
| 		Usage:       "has an llm control a console for you", | ||||
| 		Version:     "0.1", | ||||
| 		Description: "", | ||||
|  | ||||
| 		Flags: []cli.Flag{ | ||||
| 			&cli.StringFlag{ | ||||
| 				Name:  "env-file", | ||||
| 				Value: ".env", | ||||
| 				Usage: "file to read environment variables from", | ||||
| 			}, | ||||
|  | ||||
| 			&cli.StringFlag{ | ||||
| 				Name:  "model", | ||||
| 				Value: "openai/gpt-4o-mini", | ||||
| 				Usage: "model to use for answering the question, syntax: provider/model such as openai/gpt-4o", | ||||
| 			}, | ||||
|  | ||||
| 			&cli.StringFlag{ | ||||
| 				Name:  "llm-key", | ||||
| 				Value: "", | ||||
| 				Usage: "key for the llm model (if empty, will use env var of PROVIDER_API_KEY, such as OPENAI_API_KEY)", | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Action: func(ctx *cli.Context) error { | ||||
| 			// if there is no question to answer, print usage | ||||
| 			if ctx.NArg() == 0 { | ||||
| 				return cli.ShowAppHelp(ctx) | ||||
| 			} | ||||
|  | ||||
| 			if ctx.String("env-file") != "" { | ||||
| 				_ = godotenv.Load(ctx.String("env-file")) | ||||
| 			} | ||||
|  | ||||
| 			var llm gollm.LLM | ||||
|  | ||||
| 			model := ctx.String("model") | ||||
|  | ||||
| 			a := strings.Split(model, "/") | ||||
|  | ||||
| 			if len(a) != 2 { | ||||
| 				panic("invalid model, expected: provider/model (such as openai/gpt-4o)") | ||||
| 			} | ||||
|  | ||||
| 			switch a[0] { | ||||
| 			case "openai": | ||||
| 				llm = gollm.OpenAI(getKey(ctx.String("llm-key"), "OPENAI_API_KEY")) | ||||
|  | ||||
| 			case "anthropic": | ||||
| 				llm = gollm.Anthropic(getKey(ctx.String("llm-key"), "ANTHROPI_API_KEY")) | ||||
|  | ||||
| 			case "google": | ||||
| 				llm = gollm.Google(getKey(ctx.String("llm-key"), "GOOGLE_API_KEY")) | ||||
|  | ||||
| 			default: | ||||
| 				panic("unknown model provider") | ||||
| 			} | ||||
|  | ||||
| 			m, err := llm.ModelVersion(a[1]) | ||||
|  | ||||
| 			if err != nil { | ||||
| 				panic(err) | ||||
| 			} | ||||
| 			question := strings.Join(ctx.Args(), " ") | ||||
|  | ||||
| 			c := console.Agent{ | ||||
| 				Model:  m, | ||||
| 				OnDone: func(ctx context.Context, knowledge agents.Knowledge) error { return nil }, | ||||
| 				OnCommandStart: func(ctx context.Context, command string) error { | ||||
| 					slog.Info("command", "command", command) | ||||
| 					return nil | ||||
| 				}, | ||||
| 				OnCommandDone: func(ctx context.Context, command string, output string, err error) error { | ||||
| 					slog.Info("command done", "command", command, "output", output, "err", err) | ||||
| 					return nil | ||||
| 				}, | ||||
| 				ContextualInformation: []string{ | ||||
| 					fmt.Sprintf("The current time is %s", time.Now().Format(time.RFC3339)), | ||||
| 				}, | ||||
| 				MaxCommands: 0, | ||||
| 			} | ||||
|  | ||||
| 			res, err := c.Answer(context.Background(), []string{question}) | ||||
|  | ||||
| 			if res.Directory != "" { | ||||
| 				defer func() { | ||||
| 					_ = os.RemoveAll(res.Directory) | ||||
| 				}() | ||||
| 			} | ||||
| 			if err != nil { | ||||
| 				panic(err) | ||||
| 			} | ||||
|  | ||||
| 			fmt.Println("Results: ", fmt.Sprintf("%+v", res)) | ||||
|  | ||||
| 			answer, err := agents.AnswerQuestionWithKnowledge(context.Background(), res.Knowledge, m, []string{ | ||||
| 				fmt.Sprintf("The current time is %s", time.Now().Format(time.RFC3339)), | ||||
| 			}) | ||||
|  | ||||
| 			if err != nil { | ||||
| 				panic(err) | ||||
| 			} | ||||
|  | ||||
| 			fmt.Println("Answer: ", answer) | ||||
| 			return nil | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	err := app.Run(os.Args) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		slog.Error("Error: ", err) | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user