Files
ai-code-assistant/cmd/main.go
Michael Powers 4b8b8132fd First Working Prototype
This application is a simple proof of concept demonstrating an agent capable of taking a prompt and generating a patch implementing code satisfying the prompt along with an accompanying unit test.
2025-04-20 07:47:41 -04:00

111 lines
2.4 KiB
Go

package main
import (
"ai-code-assistant/cmd/autopatch"
"ai-code-assistant/cmd/chunks"
"ai-code-assistant/cmd/indexer"
"ai-code-assistant/pkg/config"
"ai-code-assistant/pkg/database"
"ai-code-assistant/pkg/llm"
"context"
"fmt"
_ "github.com/lib/pq"
"github.com/urfave/cli/v3"
"gopkg.in/yaml.v3"
"log/slog"
"os"
)
func main() {
app := &cli.Command{
Name: "ai-coding-assistant",
Usage: "an AI-powered autonomous code assistant that can help software engineers by performing tasks on their behalf",
Commands: []*cli.Command{
indexer.Command(),
chunks.Command(),
autopatch.Command(),
},
Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
initPhases := []cli.BeforeFunc{
readConfig,
initLogging,
initDatabase,
initLLM,
}
for _, phase := range initPhases {
var err error
ctx, err = phase(ctx, cmd)
if err != nil {
return nil, err
}
}
return ctx, nil
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "config",
Usage: "path to config file",
Value: "config.yaml",
},
},
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
if err := app.Run(ctx, os.Args); err != nil {
slog.Error("problem running command", "error", err)
}
}
func readConfig(ctx context.Context, cmd *cli.Command) (context.Context, error) {
cfgFile := cmd.String("config")
cfgHandle, err := os.Open(cfgFile)
if err != nil {
return nil, fmt.Errorf("problem opening config: %s: %w", cfgFile, err)
}
cfg := &config.Configuration{}
if err := yaml.NewDecoder(cfgHandle).Decode(cfg); err != nil {
return nil, fmt.Errorf("problem parsing config: %w", err)
}
return config.WrapContext(ctx, cfg), nil
}
func initLogging(ctx context.Context, _ *cli.Command) (context.Context, error) {
cfg := config.FromContext(ctx)
var lvl slog.Level
if err := lvl.UnmarshalText([]byte(cfg.Logging.Level)); err != nil {
return nil, err
}
slog.SetLogLoggerLevel(lvl)
return ctx, nil
}
func initDatabase(ctx context.Context, _ *cli.Command) (context.Context, error) {
cfg := config.FromContext(ctx)
db, err := database.FromConfig(ctx, cfg)
if err != nil {
return nil, err
}
return database.WrapContext(ctx, db), nil
}
func initLLM(ctx context.Context, _ *cli.Command) (context.Context, error) {
cfg := config.FromContext(ctx)
llmRef, err := llm.FromConfig(cfg)
if err != nil {
return nil, err
}
return llm.WrapContext(ctx, llmRef), nil
}