
Research
Using Trusted Protocols Against You: Gmail as a C2 Mechanism
Socket uncovers malicious packages on PyPI using Gmail's SMTP protocol for command and control (C2) to exfiltrate data and execute commands.
github.com/scottdavis/dsgo
This is mostly for my personal use, so support is not guaranteed.
A Go implementation of the Declarative Self-improving programming (DSPy) pattern.
I would like to express my sincere gratitude to Xiao Constantine (@XiaoConstantine), the original author of dspy-go. This project builds upon his excellent foundation and pioneering work in bringing the DSPy pattern to the Go ecosystem.
This fork includes several enhancements to the original project:
DSGo is a Go implementation of DSPy, bringing systematic prompt engineering and automated reasoning capabilities to Go applications. It provides a flexible framework for building reliable and effective Language Model (LLM) applications through composable modules and workflows.
go get github.com/scottdavis/dsgo
Here's a simple example to get you started with DSGo:
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/scottdavis/dsgo/pkg/core"
"github.com/scottdavis/dsgo/pkg/llms"
"github.com/scottdavis/dsgo/pkg/modules"
"github.com/scottdavis/dsgo/pkg/logging"
)
func main() {
// Setup DSP-GO logging
output := logging.NewConsoleOutput(true, logging.WithColor(true))
logger := logging.NewLogger(logging.Config{
Severity: logging.INFO,
Outputs: []logging.Output{output},
})
logging.SetLogger(logger)
// Create basic context
basicCtx := context.Background()
// Initialize LLM (example with Ollama)
ollamaConfig := llms.NewOllamaConfig("http://localhost:11434", "llama3")
llm, err := llms.NewLLM("", ollamaConfig)
if err != nil {
log.Fatalf("Failed to initialize LLM: %v", err)
os.Exit(1)
}
// Create DSP-GO context with execution state
ctx := core.WithExecutionState(basicCtx)
// Create a signature for question answering
signature := core.NewSignature(
[]core.InputField{{Field: core.Field{Name: "question"}}},
[]core.OutputField{{Field: core.Field{Name: "answer"}}},
)
// Create a DSPYConfig with the LLM
dspyConfig := core.NewDSPYConfig().WithDefaultLLM(llm)
// Create a ChainOfThought module with the config
cot := modules.NewChainOfThought(signature, dspyConfig)
// Create a program
program := core.NewProgram(
map[string]core.Module{"cot": cot},
func(ctx context.Context, inputs map[string]interface{}) (map[string]interface{}, error) {
return cot.Process(ctx, inputs)
},
dspyConfig,
)
// Execute the program
result, err := program.Execute(ctx, map[string]interface{}{
"question": "What is the capital of France?",
})
if err != nil {
log.Fatalf("Error executing program: %v", err)
}
fmt.Printf("Answer: %s\n", result["answer"])
}
Signatures define the input and output fields for modules. They help in creating type-safe and well-defined interfaces for your AI components.
Modules are the building blocks of DSGo programs. They encapsulate specific functionalities and can be composed to create complex pipelines. Some key modules include:
Optimizers help improve the performance of your DSGo programs by automatically tuning prompts and module parameters. Including:
Use dspy's core concepts as building blocks, impl Building Effective Agents
See agent examples
// Chain
workflow := workflows.NewChainWorkflow(store)
workflow.AddStep(&workflows.Step{
ID: "step1",
Module: modules.NewPredict(signature1),
})
workflow.AddStep(&workflows.Step{
ID: "step2",
Module: modules.NewPredict(signature2),
})
Each workflow step can be configured with:
step := &workflows.Step{
ID: "retry_example",
Module: myModule,
RetryConfig: &workflows.RetryConfig{
MaxAttempts: 3,
BackoffMultiplier: 2.0,
},
Condition: func(state map[string]interface{}) bool {
return someCondition(state)
},
}
// Enable detailed tracing
ctx = core.WithExecutionState(context.Background())
// Configure logging
logger := logging.NewLogger(logging.Config{
Severity: logging.DEBUG,
Outputs: []logging.Output{logging.NewConsoleOutput(true)},
})
logging.SetLogger(logger)
You can extend ReAct modules with custom tools:
func (t *CustomTool) CanHandle(action string) bool {
return strings.HasPrefix(action, "custom_")
}
func (t *CustomTool) Execute(ctx context.Context, action string) (string, error) {
// Implement tool logic
return "Tool result", nil
}
// Using Anthropic Claude
anthropicConfig := llms.NewAnthropicConfig(llms.AnthropicModelSonnet)
llm, _ := llms.NewLLM("api-key", anthropicConfig)
// Using Ollama (various options)
// Option 1: Using NewLLM with OllamaConfig
ollamaConfig := llms.NewOllamaConfig("http://localhost:11434", "llama2")
llm, _ := llms.NewLLM("", ollamaConfig)
// Option 2: Using OpenRouter
openRouterConfig := llms.NewOpenRouterConfig(llms.OpenRouterModelNeevaAI)
llm, _ := llms.NewLLM("api-key", openRouterConfig)
// Option 3: Using LlamaCPP
llm, _ := llms.NewLlamacppLLM("http://localhost:8080")
// Option 4: Using string format with custom host
llm, _ := llms.NewLLM("", "ollama:example.com:11434:llama2")
// or with protocol
llm, _ := llms.NewLLM("", "ollama:http://example.com:11434:llama2")
// Create DSPYConfig with the LLM
dspyConfig := core.NewDSPYConfig().WithDefaultLLM(llm)
Check the examples directory for complete implementations:
DSGo is released under the MIT License. See the LICENSE file for details.
This example demonstrates how to use Redis as a memory store for DSP-GO applications. The example shows a practical workflow where data is downloaded from an external source, stored in Redis, and then processed in subsequent steps.
If you don't have Redis running, you can quickly start it with Docker:
docker run -d --name redis-example -p 6379:6379 redis:latest
go run main.go
By default, it connects to Redis at localhost:6379
. You can specify a different Redis server:
go run main.go --redis-addr=your-redis-server:6379 --redis-password=yourpassword
You can also specify a different URL to download:
go run main.go --url=https://raw.githubusercontent.com/your-repo/your-file.txt
The example performs these steps:
main.go
: The main application code demonstrating Redis usagemain_test.go
: Tests for the Redis functionalityDSP-GO provides several memory store implementations including:
Redis is particularly useful for:
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious packages on PyPI using Gmail's SMTP protocol for command and control (C2) to exfiltrate data and execute commands.
Product
We redesigned Socket's first logged-in page to display rich and insightful visualizations about your repositories protected against supply chain threats.
Product
Automatically fix and test dependency updates with socket fix—a new CLI tool that turns CVE alerts into safe, automated upgrades.