package main import ( "bufio" "context" "encoding/json" "fmt" "os" "time" "github.com/matst80/go-openapi-compat/pkg/openapi" ) func main() { baseURL := os.Getenv("OPENAI_BASE_URL") if baseURL == "" { baseURL = "http://10.10.11.33:8082/v1/" } apiKey := os.Getenv("OPENAI_API_KEY") client := openapi.NewClient(baseURL, apiKey) model := "Jackrong/Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF" session := openapi.NewSession(client, model) session.DefaultRequestOptions.Seed = 42 session.SetSystemPrompt("You are an expert software architect. You have access to shell and file tools to explore, analyze, and modify the codebase. Use them to provide deep insights and implement changes. blocks with git diffs will be applied") // Setup composite registry with standard tools composite := &openapi.CompositeRegistry{} // Base registry for custom tools baseRegistry := openapi.NewMapRegistry() composite.Add(baseRegistry) // Add standard shell and file tools composite.Add(openapi.NewShellRegistry()) composite.Add(openapi.NewFileRegistry(".")) // Use current directory as base session.SetRegistry(composite) // Tools for reasoning about abstractions baseRegistry.Register("analyze_abstraction", "Analyze a specific code abstraction", map[string]any{ "type": "object", "properties": map[string]any{ "name": map[string]any{"type": "string"}, "description": map[string]any{"type": "string"}, }, }, func(ctx context.Context, s *openapi.Session, args json.RawMessage) (any, error) { var params struct{ Name, Description string } json.Unmarshal(args, ¶ms) return map[string]string{ "analysis": fmt.Sprintf("The abstraction '%s' (%s) follows the 'Decorator' and 'Strategy' patterns by using hooks for extensibility.", params.Name, params.Description), "score": "9/10", }, nil }) baseRegistry.Register("update_instructions", "Update the architect's system instructions", map[string]any{ "type": "object", "properties": map[string]any{ "new_instructions": map[string]any{"type": "string"}, }, }, func(ctx context.Context, s *openapi.Session, args json.RawMessage) (any, error) { var params struct{ NewInstructions string } json.Unmarshal(args, ¶ms) s.SetSystemPrompt(params.NewInstructions) return "Instructions updated successfully.", nil }) // Setup hooks for UI updates session.SetHooks(openapi.SessionHooks{ BeforeToolCall: func(ctx context.Context, s *openapi.Session, tc *openapi.ToolCall) error { fmt.Printf("\n[Tool] Executing: %s(%s)...\n", tc.Function.Name, tc.Function.Arguments) return nil }, OnReasoning: func(ctx context.Context, s *openapi.Session, reasoning string) error { fmt.Printf("\n[Thinking] %s", reasoning) return nil }, OnDone: func(ctx context.Context, s *openapi.Session) error { fmt.Printf("\nDone.\n") return nil }, OnError: func(ctx context.Context, s *openapi.Session, err error) { fmt.Printf("\n[Error] %v\n", err) }, }) fmt.Printf("Interactive Architect Session (BaseURL: %s)\n", baseURL) fmt.Println("Type your message and press Enter. Type 'exit' to quit.") scanner := bufio.NewScanner(os.Stdin) for { fmt.Print("\nUser > ") if !scanner.Scan() { break } input := scanner.Text() if input == "exit" || input == "quit" { break } ctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute) chunks, errs := session.Chat(ctx, input) fmt.Print("Assistant > ") done := make(chan struct{}) go func() { defer close(done) for chunk := range chunks { if len(chunk.Choices) > 0 { fmt.Print(chunk.Choices[0].Delta.Content) } } }() select { case <-done: fmt.Print("\nDone.\n") // Stream completed case err := <-errs: if err != nil { fmt.Printf("\nError: %v\n", err) } case <-ctx.Done(): fmt.Println("\nTimeout reached.") } cancel() fmt.Println() } }