Function bodies 513 total
config.MCPServerConfig.Validate method · go · L88-L107 (20 LOC)internal/config/config.go
func (c MCPServerConfig) Validate() error {
if c.Name == "" {
return fmt.Errorf("mcp server: name is required")
}
switch c.Transport {
case "stdio":
if c.Command == "" {
return fmt.Errorf("mcp server %q: command is required for stdio transport", c.Name)
}
case "sse":
if c.URL == "" {
return fmt.Errorf("mcp server %q: url is required for sse transport", c.Name)
}
case "":
return fmt.Errorf("mcp server %q: transport is required (stdio or sse)", c.Name)
default:
return fmt.Errorf("mcp server %q: unknown transport %q (must be stdio or sse)", c.Name, c.Transport)
}
return nil
}config.Load function · go · L112-L133 (22 LOC)internal/config/config.go
func Load(path string) (*Config, error) {
cfg := DefaultConfig()
data, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return cfg, nil
}
return nil, fmt.Errorf("reading config file: %w", err)
}
if err := toml.Unmarshal(data, cfg); err != nil {
return nil, fmt.Errorf("parsing config file: %w", err)
}
// Validate MCP server configs.
for _, srv := range cfg.MCP.Servers {
if err := srv.Validate(); err != nil {
return nil, err
}
}
return cfg, nil
}integrations.GitRunner.Log method · go · L42-L67 (26 LOC)internal/integrations/git_runner.go
func (g *GitRunner) Log(ctx context.Context, args ...string) ([]GitCommit, error) {
const sep = "\x1e"
cmdArgs := append([]string{"log", "--format=%H%x1e%an%x1e%s"}, args...)
out, err := g.run(ctx, cmdArgs...)
if err != nil {
return nil, err
}
var commits []GitCommit
for _, line := range strings.Split(strings.TrimSpace(out), "\n") {
if line == "" {
continue
}
parts := strings.SplitN(line, sep, 3)
if len(parts) < 3 {
continue
}
commits = append(commits, GitCommit{
Hash: parts[0],
Author: parts[1],
Message: parts[2],
})
}
return commits, nil
}integrations.GitRunner.Status method · go · L70-L101 (32 LOC)internal/integrations/git_runner.go
func (g *GitRunner) Status(ctx context.Context) ([]GitFileStatus, error) {
out, err := g.run(ctx, "status", "--porcelain")
if err != nil {
return nil, err
}
var statuses []GitFileStatus
for _, line := range strings.Split(strings.TrimSpace(out), "\n") {
if line == "" {
continue
}
if len(line) < 4 {
continue
}
status := strings.TrimSpace(line[:2])
path := strings.TrimSpace(line[3:])
// Handle renames: "R old.go -> new.go" — use the new path.
if strings.HasPrefix(status, "R") {
if idx := strings.Index(path, " -> "); idx >= 0 {
path = path[idx+4:]
}
}
statuses = append(statuses, GitFileStatus{
Path: path,
Status: status,
})
}
return statuses, nil
}integrations.GitRunner.run method · go · L103-L117 (15 LOC)internal/integrations/git_runner.go
func (g *GitRunner) run(ctx context.Context, args ...string) (string, error) {
if len(args) == 0 {
return "", fmt.Errorf("git: no subcommand provided")
}
cmd := exec.CommandContext(ctx, "git", args...)
cmd.Dir = g.workDir
out, err := cmd.Output()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
return "", fmt.Errorf("git %s: %s", args[0], string(exitErr.Stderr))
}
return "", fmt.Errorf("git %s: %w", args[0], err)
}
return string(out), nil
}integrations.HTTPFetcher.Fetch method · go · L26-L48 (23 LOC)internal/integrations/http_fetcher.go
func (f *HTTPFetcher) Fetch(ctx context.Context, url string) (string, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return "", fmt.Errorf("create request: %w", err)
}
resp, err := f.client.Do(req)
if err != nil {
return "", fmt.Errorf("fetch %q: %w", url, err)
}
defer resp.Body.Close()
if resp.StatusCode >= 400 {
return "", fmt.Errorf("fetch %q: HTTP %d", url, resp.StatusCode)
}
body, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseSize))
if err != nil {
return "", fmt.Errorf("read response: %w", err)
}
return string(body), nil
}integrations.LLMCompleter.Complete method · go · L23-L62 (40 LOC)internal/integrations/llm_completer.go
func (c *LLMCompleter) Complete(ctx context.Context, prompt string) (string, error) {
req := provider.CompletionRequest{
Model: c.model,
Messages: []provider.Message{provider.NewUserMessage(prompt)},
MaxTokens: 4096,
}
ch, err := c.provider.Stream(ctx, req)
if err != nil {
return "", fmt.Errorf("llm complete: %w", err)
}
var parts []string
for {
select {
case evt, ok := <-ch:
if !ok {
return strings.Join(parts, ""), nil
}
switch evt.Type {
case "text_delta":
parts = append(parts, evt.Text)
case "error":
// Drain remaining events so the provider goroutine isn't
// blocked on a send and can exit cleanly.
go func() {
for range ch {
}
}()
return "", fmt.Errorf("llm stream error: %w", evt.Error)
}
case <-ctx.Done():
go func() {
for range ch {
}
}()
return "", fmt.Errorf("llm complete: %w", ctx.Err())
}
}
}Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
integrations.SkillInvoker.Invoke method · go · L37-L46 (10 LOC)internal/integrations/skill_invoker.go
func (s *SkillInvoker) Invoke(ctx context.Context, name string, input map[string]any) (map[string]any, error) {
s.mu.RLock()
inv := s.invoker
s.mu.RUnlock()
if inv == nil {
return nil, fmt.Errorf("skill invoker not configured")
}
return inv.InvokeWorkflow(ctx, name, input)
}output.JSONFormatter.Format method · go · L15-L21 (7 LOC)internal/output/json.go
func (f *JSONFormatter) Format(result *RunResult) ([]byte, error) {
b, err := json.MarshalIndent(result, "", " ")
if err != nil {
return nil, err
}
return append(b, '\n'), nil
}output.MarkdownFormatter.Format method · go · L18-L77 (60 LOC)internal/output/markdown.go
func (f *MarkdownFormatter) Format(result *RunResult) ([]byte, error) {
var b strings.Builder
if result.Error != "" {
b.WriteString("## Error\n\n")
b.WriteString(result.Error)
b.WriteString("\n")
return []byte(b.String()), nil
}
b.WriteString(result.Response)
b.WriteString("\n")
if len(result.ToolCalls) > 0 {
b.WriteString("\n## Tool Calls\n\n")
for i, tc := range result.ToolCalls {
status := "ok"
if tc.IsError {
status = "error"
}
b.WriteString(fmt.Sprintf("%d. **%s** (%s)\n", i+1, tc.Name, status))
}
}
if len(result.SecurityFindings) > 0 {
b.WriteString("\n## Security Findings\n\n")
for i, finding := range result.SecurityFindings {
location := finding.File
if finding.Line > 0 {
location = fmt.Sprintf("%s:%d", finding.File, finding.Line)
}
b.WriteString(fmt.Sprintf("%d. **[%s]** %s", i+1, finding.Severity, finding.Title))
if location != "" {
b.WriteString(fmt.Sprintf(" — `%s`", location))
}
b.WriteString("\n")
parser.Parser.Parse method · go · L145-L167 (23 LOC)internal/parser/parser.go
func (p *Parser) Parse(filename string, source []byte) (*Tree, error) {
ext := filepath.Ext(filename)
info, ok := registry[ext]
if !ok {
return nil, fmt.Errorf("unsupported file extension %q: language not in registry", ext)
}
// Create a fresh sitter.Parser per call to avoid data races — tree-sitter
// parsers are single-threaded and SetLanguage mutates internal state.
inner := sitter.NewParser()
defer inner.Close()
inner.SetLanguage(info.lang)
sitterTree, err := inner.ParseCtx(context.Background(), nil, source)
if err != nil {
return nil, fmt.Errorf("parse %s: %w", filename, err)
}
return &Tree{
tree: sitterTree,
source: source,
info: info,
}, nil
}parser.Tree.Functions method · go · L191-L214 (24 LOC)internal/parser/parser.go
func (t *Tree) Functions() []FunctionDef {
var funcs []FunctionDef
funcTypes := make(map[string]bool, len(t.info.funcNodeTypes))
for _, ft := range t.info.funcNodeTypes {
funcTypes[ft] = true
}
walk(t.RootNode(), func(node *sitter.Node) {
if !funcTypes[node.Type()] {
return
}
name := extractFuncName(node, t.source)
if name == "" {
return
}
funcs = append(funcs, FunctionDef{
Name: name,
StartLine: int(node.StartPoint().Row) + 1, // 0-indexed to 1-indexed
EndLine: int(node.EndPoint().Row) + 1,
})
})
return funcs
}parser.Tree.Imports method · go · L217-L234 (18 LOC)internal/parser/parser.go
func (t *Tree) Imports() []string {
var imports []string
importTypes := make(map[string]bool, len(t.info.importNodeType))
for _, it := range t.info.importNodeType {
importTypes[it] = true
}
walk(t.RootNode(), func(node *sitter.Node) {
if !importTypes[node.Type()] {
return
}
text := node.Content(t.source)
paths := extractImportPaths(text, node, t.source)
imports = append(imports, paths...)
})
return imports
}parser.Tree.Query method · go · L245-L272 (28 LOC)internal/parser/parser.go
func (t *Tree) Query(pattern string) ([]Match, error) {
q, err := sitter.NewQuery([]byte(pattern), t.info.lang)
if err != nil {
return nil, fmt.Errorf("compile query: %w", err)
}
defer q.Close()
cursor := sitter.NewQueryCursor()
defer cursor.Close()
cursor.Exec(q, t.tree.RootNode())
var matches []Match
for {
m, ok := cursor.NextMatch()
if !ok {
break
}
for _, capture := range m.Captures {
matches = append(matches, Match{
Text: capture.Node.Content(t.source),
StartLine: int(capture.Node.StartPoint().Row) + 1,
EndLine: int(capture.Node.EndPoint().Row) + 1,
})
}
}
return matches, nil
}parser.walk function · go · L275-L286 (12 LOC)internal/parser/parser.go
func walk(node *sitter.Node, fn func(*sitter.Node)) {
if node == nil {
return
}
fn(node)
for i := 0; i < int(node.ChildCount()); i++ {
child := node.Child(i)
if child != nil {
walk(child, fn)
}
}
}About: code-quality intelligence by Repobility · https://repobility.com
parser.extractFuncName function · go · L292-L317 (26 LOC)internal/parser/parser.go
func extractFuncName(node *sitter.Node, source []byte) string {
// Try the "name" field first — works for Go, Python, JS, TS, Java, Rust, Ruby
nameNode := node.ChildByFieldName("name")
if nameNode != nil {
return nameNode.Content(source)
}
// C/C++: function_definition -> declarator (function_declarator) -> declarator (identifier)
declNode := node.ChildByFieldName("declarator")
if declNode != nil {
innerName := declNode.ChildByFieldName("declarator")
if innerName != nil {
return innerName.Content(source)
}
}
// arrow_function / function_expression: name comes from the enclosing
// variable_declarator (e.g. const foo = () => {}).
if parent := node.Parent(); parent != nil && parent.Type() == "variable_declarator" {
if nameNode := parent.ChildByFieldName("name"); nameNode != nil {
return nameNode.Content(source)
}
}
return ""
}parser.extractImportPaths function · go · L320-L347 (28 LOC)internal/parser/parser.go
func extractImportPaths(text string, node *sitter.Node, source []byte) []string {
nodeType := node.Type()
switch nodeType {
case "import_declaration":
// Go: import "fmt" or import ( "fmt"\n"os" )
// Java: import java.util.List;
return extractImportDeclaration(node, source)
case "import_statement":
// Python: import os, sys
// JS/TS: import { foo } from 'bar'
return extractGenericImport(text)
case "import_from_statement":
// Python: from pathlib import Path
return extractPythonFromImport(text)
case "use_declaration":
// Rust: use std::io;
return extractRustUse(text)
case "preproc_include":
// C/C++: #include <stdio.h> or #include "myheader.h"
return extractCInclude(text)
case "call":
// Ruby: require 'foo' or require_relative 'bar'
return extractRubyRequire(text)
default:
return []string{extractImportPath(text)}
}
}parser.extractImportDeclaration function · go · L352-L381 (30 LOC)internal/parser/parser.go
func extractImportDeclaration(node *sitter.Node, source []byte) []string {
var paths []string
seen := make(map[string]bool)
walk(node, func(n *sitter.Node) {
var content string
switch n.Type() {
case "import_spec":
// Go: import spec wrapping a string literal
content = extractImportPath(n.Content(source))
case "interpreted_string_literal":
// Go: the actual string literal "fmt"
content = extractImportPath(n.Content(source))
case "scoped_identifier":
// Java: java.util.List — only take the top-level scoped_identifier
// (avoid duplicates from nested scoped_identifiers)
if n.Parent() != nil && n.Parent().Type() == "scoped_identifier" {
return
}
content = n.Content(source)
default:
return
}
if content != "" && !seen[content] {
seen[content] = true
paths = append(paths, content)
}
})
return paths
}parser.extractGenericImport function · go · L384-L413 (30 LOC)internal/parser/parser.go
func extractGenericImport(text string) []string {
// JS/TS: import { foo } from 'bar'
if strings.Contains(text, " from ") {
parts := strings.SplitN(text, " from ", 2)
if len(parts) == 2 {
return []string{extractImportPath(parts[1])}
}
}
// Python: import os, sys
// Also handles JS side-effect imports like import 'module'
text = strings.TrimPrefix(text, "import ")
text = strings.TrimSpace(text)
parts := strings.Split(text, ",")
var result []string
for _, p := range parts {
p = strings.TrimSpace(p)
// Handle "import os as operating_system"
if idx := strings.Index(p, " as "); idx >= 0 {
p = p[:idx]
}
p = strings.TrimSpace(p)
// Strip quotes for JS side-effect imports like import 'x'
p = extractImportPath(p)
if p != "" {
result = append(result, p)
}
}
return result
}parser.extractPythonFromImport function · go · L416-L427 (12 LOC)internal/parser/parser.go
func extractPythonFromImport(text string) []string {
// from pathlib import Path -> extract "pathlib"
text = strings.TrimPrefix(text, "from ")
parts := strings.SplitN(text, " import ", 2)
if len(parts) >= 1 {
module := strings.TrimSpace(parts[0])
if module != "" {
return []string{module}
}
}
return nil
}parser.extractRustUse function · go · L430-L438 (9 LOC)internal/parser/parser.go
func extractRustUse(text string) []string {
text = strings.TrimPrefix(text, "use ")
text = strings.TrimSuffix(text, ";")
text = strings.TrimSpace(text)
if text != "" {
return []string{text}
}
return nil
}parser.extractCInclude function · go · L441-L450 (10 LOC)internal/parser/parser.go
func extractCInclude(text string) []string {
text = strings.TrimPrefix(text, "#include")
text = strings.TrimSpace(text)
text = strings.Trim(text, "<>\"")
text = strings.TrimSpace(text)
if text != "" {
return []string{text}
}
return nil
}parser.extractRubyRequire function · go · L453-L468 (16 LOC)internal/parser/parser.go
func extractRubyRequire(text string) []string {
if !strings.HasPrefix(text, "require") {
return nil
}
// require 'foo' or require_relative 'bar'
for _, prefix := range []string{"require_relative ", "require "} {
if strings.HasPrefix(text, prefix) {
rest := strings.TrimPrefix(text, prefix)
cleaned := extractImportPath(rest)
if cleaned != "" {
return []string{cleaned}
}
}
}
return nil
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
parser.extractImportPath function · go · L472-L477 (6 LOC)internal/parser/parser.go
func extractImportPath(text string) string {
text = strings.TrimSpace(text)
text = strings.Trim(text, "\"'`();")
text = strings.TrimSpace(text)
return text
}pipeline.BuildReviewPrompt function · go · L6-L21 (16 LOC)internal/pipeline/codereview.go
func BuildReviewPrompt(diff string) string {
if diff == "" {
return "There are no changes to review (no diff found, no changes detected)."
}
return fmt.Sprintf(`You are reviewing the following code changes. Analyze the diff and provide:
1. A brief summary of what changed
2. Issues found (bugs, security, performance, style) with severity (high/medium/low)
3. Suggestions for improvement
If there are no issues, say so.
<diff>
%s
</diff>`, diff)
}pipeline.ExtractDiff function · go · L12-L30 (19 LOC)internal/pipeline/diff.go
func ExtractDiff(ctx context.Context, dir, diffRange string) (string, error) {
if diffRange == "" {
diffRange = "HEAD~1..HEAD"
}
cmd := exec.CommandContext(ctx, "git", "diff", diffRange)
cmd.Dir = dir
out, err := cmd.Output()
if err != nil {
stderr := ""
if ee, ok := err.(*exec.ExitError); ok {
stderr = strings.TrimSpace(string(ee.Stderr))
}
return "", fmt.Errorf("git diff failed: %s: %w", stderr, err)
}
return string(out), nil
}anthropic.New function · go · L29-L35 (7 LOC)internal/provider/anthropic/provider.go
func New(baseURL, apiKey string) *Provider {
return &Provider{
baseURL: baseURL,
apiKey: apiKey,
client: &http.Client{},
}
}anthropic.Provider.Stream method · go · L74-L104 (31 LOC)internal/provider/anthropic/provider.go
func (p *Provider) Stream(ctx context.Context, req provider.CompletionRequest) (<-chan provider.StreamEvent, error) {
body, err := p.buildRequestBody(req)
if err != nil {
return nil, fmt.Errorf("building request body: %w", err)
}
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, p.baseURL+"/v1/messages", bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("creating request: %w", err)
}
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("x-api-key", p.apiKey)
httpReq.Header.Set("anthropic-version", "2023-06-01")
resp, err := p.client.Do(httpReq)
if err != nil {
return nil, fmt.Errorf("sending request: %w", err)
}
if resp.StatusCode != http.StatusOK {
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("API error %d: %s", resp.StatusCode, string(respBody))
}
ch := make(chan provider.StreamEvent)
go p.processStream(ctx, resp.Body, ch)
return ch, nil
}anthropic.Provider.buildRequestBody method · go · L106-L137 (32 LOC)internal/provider/anthropic/provider.go
func (p *Provider) buildRequestBody(req provider.CompletionRequest) ([]byte, error) {
apiReq := apiRequest{
Model: req.Model,
MaxTokens: req.MaxTokens,
Stream: true,
System: req.System,
}
if req.Temperature != nil {
temp := *req.Temperature
apiReq.Temperature = &temp
}
// Convert messages, remapping fields for the Anthropic API
for _, msg := range req.Messages {
apiReq.Messages = append(apiReq.Messages, apiMessage{
Role: msg.Role,
Content: convertContentBlocks(msg.Content),
})
}
// Convert tools
for _, tool := range req.Tools {
apiReq.Tools = append(apiReq.Tools, apiTool{
Name: tool.Name,
Description: tool.Description,
InputSchema: tool.InputSchema,
})
}
return json.Marshal(apiReq)
}anthropic.convertContentBlocks function · go · L142-L160 (19 LOC)internal/provider/anthropic/provider.go
func convertContentBlocks(blocks []provider.ContentBlock) []apiContentBlock {
out := make([]apiContentBlock, len(blocks))
for i, b := range blocks {
out[i] = apiContentBlock{
Type: b.Type,
ID: b.ID,
Name: b.Name,
Input: b.Input,
ToolUseID: b.ToolUseID,
IsError: b.IsError,
}
if b.Type == "tool_result" {
out[i].Content = b.Text
} else {
out[i].Text = b.Text
}
}
return out
}anthropic.Provider.processStream method · go · L164-L200 (37 LOC)internal/provider/anthropic/provider.go
func (p *Provider) processStream(ctx context.Context, body io.ReadCloser, ch chan<- provider.StreamEvent) {
defer close(ch)
defer body.Close()
scanner := newSSEScanner(body)
for scanner.Next() {
if ctx.Err() != nil {
select {
case ch <- provider.StreamEvent{Type: "error", Error: ctx.Err()}:
default:
}
return
}
streamEvt := p.convertSSEEvent(scanner.Event())
if streamEvt == nil {
continue
}
select {
case ch <- *streamEvt:
case <-ctx.Done():
select {
case ch <- provider.StreamEvent{Type: "error", Error: ctx.Err()}:
default:
}
return
}
}
if err := scanner.Err(); err != nil {
select {
case ch <- provider.StreamEvent{Type: "error", Error: err}:
case <-ctx.Done():
}
}
}Want this analysis on your repo? https://repobility.com/scan/
anthropic.Provider.convertSSEEvent method · go · L203-L214 (12 LOC)internal/provider/anthropic/provider.go
func (p *Provider) convertSSEEvent(evt sseEvent) *provider.StreamEvent {
switch evt.Event {
case "content_block_start":
return p.handleContentBlockStart(evt.Data)
case "content_block_delta":
return p.handleContentBlockDelta(evt.Data)
case "message_stop":
return &provider.StreamEvent{Type: "stop"}
default:
return nil
}
}anthropic.Provider.handleContentBlockStart method · go · L216-L240 (25 LOC)internal/provider/anthropic/provider.go
func (p *Provider) handleContentBlockStart(data string) *provider.StreamEvent {
var parsed struct {
ContentBlock struct {
Type string `json:"type"`
ID string `json:"id"`
Name string `json:"name"`
} `json:"content_block"`
}
if err := json.NewDecoder(strings.NewReader(data)).Decode(&parsed); err != nil {
return &provider.StreamEvent{Type: "error", Error: fmt.Errorf("parsing content_block_start: %w", err)}
}
if parsed.ContentBlock.Type == "tool_use" {
return &provider.StreamEvent{
Type: "tool_use",
ToolUse: &provider.ToolUseBlock{
ID: parsed.ContentBlock.ID,
Name: parsed.ContentBlock.Name,
},
}
}
return nil
}anthropic.Provider.handleContentBlockDelta method · go · L242-L270 (29 LOC)internal/provider/anthropic/provider.go
func (p *Provider) handleContentBlockDelta(data string) *provider.StreamEvent {
var parsed struct {
Delta struct {
Type string `json:"type"`
Text string `json:"text"`
PartialJSON string `json:"partial_json"`
} `json:"delta"`
}
if err := json.NewDecoder(strings.NewReader(data)).Decode(&parsed); err != nil {
return &provider.StreamEvent{Type: "error", Error: fmt.Errorf("parsing content_block_delta: %w", err)}
}
switch parsed.Delta.Type {
case "text_delta":
return &provider.StreamEvent{
Type: "text_delta",
Text: parsed.Delta.Text,
}
case "input_json_delta":
// Emit JSON input deltas as text_delta - the agent layer accumulates the JSON
return &provider.StreamEvent{
Type: "text_delta",
Text: parsed.Delta.PartialJSON,
}
default:
return nil
}
}anthropic.sseScanner.Next method · go · L40-L88 (49 LOC)internal/provider/anthropic/sse.go
func (s *sseScanner) Next() bool {
if s.done {
return false
}
var current sseEvent
hasData := false
for s.scanner.Scan() {
line := s.scanner.Text()
// Empty line signals end of current event
if line == "" {
if hasData || current.Event != "" {
s.event = current
return true
}
continue
}
// Skip SSE comments
if strings.HasPrefix(line, ":") {
continue
}
if strings.HasPrefix(line, "event:") {
current.Event = strings.TrimSpace(strings.TrimPrefix(line, "event:"))
} else if strings.HasPrefix(line, "data:") {
data := strings.TrimSpace(strings.TrimPrefix(line, "data:"))
if hasData {
current.Data += "\n" + data
} else {
current.Data = data
hasData = true
}
}
}
s.err = s.scanner.Err()
s.done = true
// Handle stream ending without trailing empty line
if hasData || current.Event != "" {
s.event = current
return true
}
return false
}provider.NewProvider function · go · L27-L36 (10 LOC)internal/provider/factory.go
func NewProvider(cfg *config.Config) (LLMProvider, error) {
switch cfg.Provider.Default {
case "anthropic":
return newAnthropicProvider(cfg)
case "ollama":
return newOllamaProvider(cfg)
default:
return newOpenAIProvider(cfg)
}
}provider.newAnthropicProvider function · go · L38-L54 (17 LOC)internal/provider/factory.go
func newAnthropicProvider(cfg *config.Config) (LLMProvider, error) {
constructor, ok := registry["anthropic"]
if !ok {
return nil, fmt.Errorf("anthropic provider not registered")
}
apiKey, err := config.ResolveAPIKey(
cfg.Provider.Anthropic.APIKeySource,
cfg.Provider.Anthropic.APIKey,
"ANTHROPIC_API_KEY",
)
if err != nil {
return nil, fmt.Errorf("resolving Anthropic API key: %w", err)
}
return constructor(anthropicBaseURL, apiKey, nil), nil
}provider.newOpenAIProvider function · go · L70-L91 (22 LOC)internal/provider/factory.go
func newOpenAIProvider(cfg *config.Config) (LLMProvider, error) {
name := cfg.Provider.Default
constructor, ok := registry["openai"]
if !ok {
return nil, fmt.Errorf("openai provider not registered")
}
for _, oc := range cfg.Provider.OpenAI {
if oc.Name == name {
envVar := strings.ToUpper(name) + "_API_KEY"
apiKey, err := config.ResolveAPIKey(oc.APIKeySource, oc.APIKey, envVar)
if err != nil {
return nil, fmt.Errorf("resolving %s API key: %w", name, err)
}
return constructor(oc.BaseURL, apiKey, oc.ExtraHeaders), nil
}
}
return nil, fmt.Errorf("unknown provider: %q", name)
}ollama.New function · go · L31-L36 (6 LOC)internal/provider/ollama/provider.go
func New(baseURL string) *Provider {
return &Provider{
baseURL: baseURL,
client: &http.Client{},
}
}Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
ollama.Provider.Stream method · go · L103-L131 (29 LOC)internal/provider/ollama/provider.go
func (p *Provider) Stream(ctx context.Context, req provider.CompletionRequest) (<-chan provider.StreamEvent, error) {
body, err := p.buildRequestBody(req)
if err != nil {
return nil, fmt.Errorf("building request body: %w", err)
}
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, p.baseURL+"/api/chat", bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("creating request: %w", err)
}
httpReq.Header.Set("Content-Type", "application/json")
resp, err := p.client.Do(httpReq)
if err != nil {
return nil, fmt.Errorf("sending request: %w", err)
}
if resp.StatusCode != http.StatusOK {
defer resp.Body.Close()
respBody, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
return nil, fmt.Errorf("API error %d: %s", resp.StatusCode, string(respBody))
}
ch := make(chan provider.StreamEvent)
go p.processStream(ctx, resp.Body, ch)
return ch, nil
}ollama.Provider.buildRequestBody method · go · L133-L178 (46 LOC)internal/provider/ollama/provider.go
func (p *Provider) buildRequestBody(req provider.CompletionRequest) ([]byte, error) {
apiReq := apiRequest{
Model: req.Model,
Stream: true,
}
// Set options if max tokens or temperature are specified
if req.MaxTokens > 0 || req.Temperature != nil {
opts := &apiOptions{}
if req.MaxTokens > 0 {
opts.NumPredict = req.MaxTokens
}
if req.Temperature != nil {
temp := *req.Temperature
opts.Temperature = &temp
}
apiReq.Options = opts
}
// Add system message if present
if req.System != "" {
apiReq.Messages = append(apiReq.Messages, apiMessage{
Role: "system",
Content: req.System,
})
}
// Convert messages
for _, msg := range req.Messages {
apiReq.Messages = append(apiReq.Messages, p.convertMessages(msg)...)
}
// Convert tools
for _, tool := range req.Tools {
apiReq.Tools = append(apiReq.Tools, apiTool{
Type: "function",
Function: apiFunction{
Name: tool.Name,
Description: tool.Description,
Parameters: tool.Inpuollama.Provider.convertMessages method · go · L181-L199 (19 LOC)internal/provider/ollama/provider.go
func (p *Provider) convertMessages(msg provider.Message) []apiMessage {
switch msg.Role {
case "assistant":
return []apiMessage{p.convertAssistantMessage(msg)}
case "user":
return p.convertUserMessages(msg)
default:
var texts []string
for _, block := range msg.Content {
if block.Type == "text" {
texts = append(texts, block.Text)
}
}
return []apiMessage{{
Role: msg.Role,
Content: strings.Join(texts, ""),
}}
}
}ollama.Provider.convertAssistantMessage method · go · L201-L228 (28 LOC)internal/provider/ollama/provider.go
func (p *Provider) convertAssistantMessage(msg provider.Message) apiMessage {
var text string
var toolCalls []apiToolCall
for _, block := range msg.Content {
switch block.Type {
case "text":
text += block.Text
case "tool_use":
toolCalls = append(toolCalls, apiToolCall{
Function: apiCallFunc{
Name: block.Name,
Arguments: block.Input,
},
})
}
}
apiMsg := apiMessage{
Role: "assistant",
Content: text,
}
if len(toolCalls) > 0 {
apiMsg.ToolCalls = toolCalls
}
return apiMsg
}ollama.Provider.convertUserMessages method · go · L231-L266 (36 LOC)internal/provider/ollama/provider.go
func (p *Provider) convertUserMessages(msg provider.Message) []apiMessage {
var toolResults []apiMessage
var texts []string
for _, block := range msg.Content {
switch block.Type {
case "tool_result":
toolResults = append(toolResults, apiMessage{
Role: "tool",
Content: block.Text,
ToolCallID: block.ToolUseID,
})
case "text":
texts = append(texts, block.Text)
}
}
if len(toolResults) > 0 {
// Preserve any text blocks alongside tool results.
if len(texts) > 0 {
msgs := make([]apiMessage, 0, len(toolResults)+1)
msgs = append(msgs, toolResults...)
msgs = append(msgs, apiMessage{
Role: "user",
Content: strings.Join(texts, ""),
})
return msgs
}
return toolResults
}
return []apiMessage{{
Role: "user",
Content: strings.Join(texts, ""),
}}
}ollama.Provider.processStream method · go · L269-L358 (90 LOC)internal/provider/ollama/provider.go
func (p *Provider) processStream(ctx context.Context, body io.ReadCloser, ch chan<- provider.StreamEvent) {
defer close(ch)
defer body.Close()
gotDone := false
scanner := bufio.NewScanner(body)
scanner.Buffer(make([]byte, 0, 1024*1024), 1024*1024)
for scanner.Scan() {
if ctx.Err() != nil {
select {
case ch <- provider.StreamEvent{Type: "error", Error: ctx.Err()}:
default:
}
return
}
line := scanner.Text()
// Skip empty lines
if strings.TrimSpace(line) == "" {
continue
}
var chunk streamChunk
if err := json.Unmarshal([]byte(line), &chunk); err != nil {
select {
case ch <- provider.StreamEvent{Type: "error", Error: fmt.Errorf("parsing chunk: %w", err)}:
case <-ctx.Done():
}
continue
}
// Handle tool calls
for _, tc := range chunk.Message.ToolCalls {
argsJSON := json.RawMessage(tc.Function.Arguments)
if argsJSON == nil {
argsJSON = json.RawMessage(`{}`)
}
select {
case ch <- provider.StreamEvent{
Tyopenai.New function · go · L31-L41 (11 LOC)internal/provider/openai/provider.go
func New(baseURL, apiKey string, extraHeaders map[string]string) *Provider {
if extraHeaders == nil {
extraHeaders = make(map[string]string)
}
return &Provider{
baseURL: baseURL,
apiKey: apiKey,
extraHeaders: extraHeaders,
client: &http.Client{},
}
}openai.Provider.Stream method · go · L111-L144 (34 LOC)internal/provider/openai/provider.go
func (p *Provider) Stream(ctx context.Context, req provider.CompletionRequest) (<-chan provider.StreamEvent, error) {
body, err := p.buildRequestBody(req)
if err != nil {
return nil, fmt.Errorf("building request body: %w", err)
}
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, p.baseURL+"/chat/completions", bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("creating request: %w", err)
}
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("Authorization", "Bearer "+p.apiKey)
for k, v := range p.extraHeaders {
httpReq.Header.Set(k, v)
}
resp, err := p.client.Do(httpReq)
if err != nil {
return nil, fmt.Errorf("sending request: %w", err)
}
if resp.StatusCode != http.StatusOK {
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("API error %d: %s", resp.StatusCode, string(respBody))
}
ch := make(chan provider.StreamEvent)
go p.processStream(ctx, resp.Body, ch)
return ch,About: code-quality intelligence by Repobility · https://repobility.com
openai.Provider.buildRequestBody method · go · L146-L184 (39 LOC)internal/provider/openai/provider.go
func (p *Provider) buildRequestBody(req provider.CompletionRequest) ([]byte, error) {
apiReq := apiRequest{
Model: req.Model,
MaxTokens: req.MaxTokens,
Stream: true,
}
if req.Temperature != nil {
temp := *req.Temperature
apiReq.Temperature = &temp
}
// Add system message if present
if req.System != "" {
apiReq.Messages = append(apiReq.Messages, apiMessage{
Role: "system",
Content: req.System,
})
}
// Convert messages
for _, msg := range req.Messages {
apiReq.Messages = append(apiReq.Messages, p.convertMessages(msg)...)
}
// Convert tools
for _, tool := range req.Tools {
apiReq.Tools = append(apiReq.Tools, apiTool{
Type: "function",
Function: apiFunction{
Name: tool.Name,
Description: tool.Description,
Parameters: tool.InputSchema,
},
})
}
return json.Marshal(apiReq)
}openai.Provider.convertMessages method · go · L188-L207 (20 LOC)internal/provider/openai/provider.go
func (p *Provider) convertMessages(msg provider.Message) []apiMessage {
switch msg.Role {
case "assistant":
return []apiMessage{p.convertAssistantMessage(msg)}
case "user":
return p.convertUserMessages(msg)
default:
// Fallback: concatenate text blocks
var texts []string
for _, block := range msg.Content {
if block.Type == "text" {
texts = append(texts, block.Text)
}
}
return []apiMessage{{
Role: msg.Role,
Content: strings.Join(texts, ""),
}}
}
}openai.Provider.convertAssistantMessage method · go · L209-L240 (32 LOC)internal/provider/openai/provider.go
func (p *Provider) convertAssistantMessage(msg provider.Message) apiMessage {
var text string
var toolCalls []apiToolCall
for _, block := range msg.Content {
switch block.Type {
case "text":
text += block.Text
case "tool_use":
toolCalls = append(toolCalls, apiToolCall{
ID: block.ID,
Type: "function",
Function: apiCallFunc{
Name: block.Name,
Arguments: string(block.Input),
},
})
}
}
apiMsg := apiMessage{
Role: "assistant",
}
if text != "" {
apiMsg.Content = text
}
if len(toolCalls) > 0 {
apiMsg.ToolCalls = toolCalls
}
return apiMsg
}