Skip to content

feat: add AI integration with Ollama and LangChain#2

Merged
themusicman merged 6 commits intomainfrom
langchain-ollama
Jul 22, 2025
Merged

feat: add AI integration with Ollama and LangChain#2
themusicman merged 6 commits intomainfrom
langchain-ollama

Conversation

@themusicman
Copy link
Copy Markdown
Contributor

Overview

This PR adds AI integration capabilities to the workie project by integrating Ollama and LangChain for local LLM interactions.

Changes

  • Enhanced Configuration Management: Integrated Viper for more robust configuration handling
  • AI Configuration Structure: Added comprehensive AI configuration with model settings, temperature, context size, etc.
  • New 'ask' Command: Implemented a new command to query Ollama models directly from the CLI
  • LangChain Integration: Added LangChain Go dependency for seamless LLM interactions
  • Example Configuration: Created a detailed config.yaml with extensive AI settings

Files Changed

  • cmd/ask.go - New command for AI interactions
  • config.yaml - Comprehensive configuration template
  • config/config.go - Enhanced configuration management with Viper
  • go.mod & go.sum - Added dependencies for Ollama and LangChain

Features

  • Query local Ollama models through the CLI
  • Configurable AI settings (model, temperature, context size, etc.)
  • Flexible configuration management with YAML support
  • Integration with LangChain for advanced LLM capabilities

Usage

After installing Ollama locally, users can:

  1. Configure their AI settings in config.yaml
  2. Use the new workie ask "your question here" command
  3. Interact with local LLMs seamlessly

This enhancement makes workie more powerful by adding AI-assisted functionality while maintaining privacy through local model execution.

- integrate Viper for enhanced configuration management
- add comprehensive AI configuration structure with model settings
- implement 'ask' command for querying Ollama models
- add LangChain Go dependency for LLM interactions
- create example config.yaml with extensive AI settings
Copilot AI review requested due to automatic review settings July 22, 2025 20:59
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds AI integration capabilities to the workie project by incorporating Ollama and LangChain for local LLM interactions. The implementation provides a new CLI command for querying AI models while enhancing the configuration system with Viper.

Key changes include:

  • Enhanced configuration management with Viper library for robust settings handling
  • New AI configuration structure supporting comprehensive model and provider settings
  • Implementation of an 'ask' command for direct CLI interaction with Ollama models

Reviewed Changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 6 comments.

File Description
go.mod Updated Go version and added dependencies for LangChain, Viper, and related packages
config/config.go Enhanced configuration management with new AI config structures and Viper integration
config.yaml Comprehensive AI configuration template with extensive model, task, and integration settings
cmd/ask.go New command implementation for querying Ollama models through CLI

Comment thread config/config.go
Comment on lines +264 to +271
viper.SetConfigType("yaml")
viper.SetConfigFile(configFile)

// Basic check if content looks like YAML (should contain colons or hyphens)
if !strings.Contains(content, ":") && !strings.Contains(content, "-") {
return nil, fmt.Errorf("config file does not appear to contain valid YAML: %s", configFile)
}
if err := viper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("error reading config file: %w", err)
}

if err := yaml.Unmarshal(data, config); err != nil {
// Provide more helpful YAML error messages
errorStr := err.Error()
if strings.Contains(errorStr, "line") && strings.Contains(errorStr, "column") {
return nil, fmt.Errorf("failed to parse YAML config file %s: %s\n\nCommon YAML issues:\n • Check indentation (use spaces, not tabs)\n • Ensure colons are followed by spaces\n • Quote strings containing special characters\n • Verify bracket/brace matching", configFile, errorStr)
}
return nil, fmt.Errorf("failed to parse YAML config file %s: %w\n\nThis usually means the YAML syntax is invalid. Please check:\n • File uses proper YAML format\n • Indentation is consistent (use spaces)\n • All keys and values are properly quoted if needed", configFile, err)
}
if err := viper.Unmarshal(config); err != nil {
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line appears to be incorrectly placed in the middle of the LoadConfig function and uses a global viper instance instead of the local config variable. This could cause runtime errors and configuration conflicts.

Copilot uses AI. Check for mistakes.
Comment thread config/config.go
Comment on lines +264 to +271
viper.SetConfigType("yaml")
viper.SetConfigFile(configFile)

// Basic check if content looks like YAML (should contain colons or hyphens)
if !strings.Contains(content, ":") && !strings.Contains(content, "-") {
return nil, fmt.Errorf("config file does not appear to contain valid YAML: %s", configFile)
}
if err := viper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("error reading config file: %w", err)
}

if err := yaml.Unmarshal(data, config); err != nil {
// Provide more helpful YAML error messages
errorStr := err.Error()
if strings.Contains(errorStr, "line") && strings.Contains(errorStr, "column") {
return nil, fmt.Errorf("failed to parse YAML config file %s: %s\n\nCommon YAML issues:\n • Check indentation (use spaces, not tabs)\n • Ensure colons are followed by spaces\n • Quote strings containing special characters\n • Verify bracket/brace matching", configFile, errorStr)
}
return nil, fmt.Errorf("failed to parse YAML config file %s: %w\n\nThis usually means the YAML syntax is invalid. Please check:\n • File uses proper YAML format\n • Indentation is consistent (use spaces)\n • All keys and values are properly quoted if needed", configFile, err)
}
if err := viper.Unmarshal(config); err != nil {
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line uses the global viper instance instead of a local instance, which could cause conflicts with other parts of the application using viper.

Copilot uses AI. Check for mistakes.
Comment thread config/config.go
Comment on lines +264 to +271
viper.SetConfigType("yaml")
viper.SetConfigFile(configFile)

// Basic check if content looks like YAML (should contain colons or hyphens)
if !strings.Contains(content, ":") && !strings.Contains(content, "-") {
return nil, fmt.Errorf("config file does not appear to contain valid YAML: %s", configFile)
}
if err := viper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("error reading config file: %w", err)
}

if err := yaml.Unmarshal(data, config); err != nil {
// Provide more helpful YAML error messages
errorStr := err.Error()
if strings.Contains(errorStr, "line") && strings.Contains(errorStr, "column") {
return nil, fmt.Errorf("failed to parse YAML config file %s: %s\n\nCommon YAML issues:\n • Check indentation (use spaces, not tabs)\n • Ensure colons are followed by spaces\n • Quote strings containing special characters\n • Verify bracket/brace matching", configFile, errorStr)
}
return nil, fmt.Errorf("failed to parse YAML config file %s: %w\n\nThis usually means the YAML syntax is invalid. Please check:\n • File uses proper YAML format\n • Indentation is consistent (use spaces)\n • All keys and values are properly quoted if needed", configFile, err)
}
if err := viper.Unmarshal(config); err != nil {
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line uses the global viper instance and appears to be replacing the original YAML parsing logic incorrectly, potentially breaking the LoadConfig function.

Copilot uses AI. Check for mistakes.
Comment thread config/config.go
Comment on lines +264 to +271
viper.SetConfigType("yaml")
viper.SetConfigFile(configFile)

// Basic check if content looks like YAML (should contain colons or hyphens)
if !strings.Contains(content, ":") && !strings.Contains(content, "-") {
return nil, fmt.Errorf("config file does not appear to contain valid YAML: %s", configFile)
}
if err := viper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("error reading config file: %w", err)
}

if err := yaml.Unmarshal(data, config); err != nil {
// Provide more helpful YAML error messages
errorStr := err.Error()
if strings.Contains(errorStr, "line") && strings.Contains(errorStr, "column") {
return nil, fmt.Errorf("failed to parse YAML config file %s: %s\n\nCommon YAML issues:\n • Check indentation (use spaces, not tabs)\n • Ensure colons are followed by spaces\n • Quote strings containing special characters\n • Verify bracket/brace matching", configFile, errorStr)
}
return nil, fmt.Errorf("failed to parse YAML config file %s: %w\n\nThis usually means the YAML syntax is invalid. Please check:\n • File uses proper YAML format\n • Indentation is consistent (use spaces)\n • All keys and values are properly quoted if needed", configFile, err)
}
if err := viper.Unmarshal(config); err != nil {
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line uses the global viper instance instead of a local instance, which could cause configuration conflicts and inconsistent behavior.

Copilot uses AI. Check for mistakes.
Comment thread cmd/ask.go
Comment on lines +25 to +26
// Load configuration using Viper
config, err := config.LoadConfigWithViper("./", "config.yaml")
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded config path "config.yaml" reduces flexibility. Consider making this configurable through a flag or environment variable to allow users to specify different config locations.

Suggested change
// Load configuration using Viper
config, err := config.LoadConfigWithViper("./", "config.yaml")
// Resolve configuration path
configPath, _ := cmd.Flags().GetString("config")
if configPath == "" {
configPath = os.Getenv("CONFIG_PATH")
if configPath == "" {
configPath = "config.yaml"
}
}
// Load configuration using Viper
config, err := config.LoadConfigWithViper("./", configPath)

Copilot uses AI. Check for mistakes.
Comment thread cmd/ask.go
os.Exit(1)
}

fmt.Println("AI Response:", response)
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The output format hardcodes "AI Response:" prefix. Consider making the output format configurable or removing the prefix for cleaner integration with scripts and pipes.

Suggested change
fmt.Println("AI Response:", response)
noPrefix, _ := cmd.Flags().GetBool("no-prefix")
if noPrefix {
fmt.Println(response)
} else {
fmt.Println("AI Response:", response)
}

Copilot uses AI. Check for mistakes.
- fixes deprecated action version error in GitHub Actions
- v3 is deprecated as of April 16, 2024
- handle error returns from rootCmd.MarkFlagFilename
- handle error returns from cmd.Help()
- handle error returns from cmd.Process.Kill()
- fix nil pointer dereferences in config tests by using t.Fatal
- fix undefined variable reference in manager.go
- remove invalid go version format (1.22.0 -> 1.21)
- remove unsupported toolchain directive
- fixes go mod download error in CI
- fix gosec action from securecodewarrior to securego
- update Go versions to match go.mod (remove 1.22, use 1.21)
- update actions/cache from v3 to v4
- change build path from ./cmd/workie to . (root directory)
- main.go is in the root directory, not in cmd/workie
@themusicman themusicman merged commit 31031a3 into main Jul 22, 2025
1 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants