← back to julianshen__rubichan

Function bodies 513 total

All specs Real LLM only Function bodies
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.Inpu
ollama.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{
				Ty
openai.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
}
‹ prevpage 2 / 11next ›