feat: done vibing
This commit is contained in:
27 files changed
+1922
-13
No files matched your search
@@ -0,0 +1,40 @@
|
||||
// Package analyze turns fetched market data + news into an investment-advice
|
||||
// report via Claude, using one of two interchangeable modes: "subscription"
|
||||
// (shells out to the `claude` CLI, billed against a Claude Pro/Max
|
||||
// subscription) or "api" (calls the Messages API directly, billed per token).
|
||||
package analyze
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/ytshih/stonks/internal/config"
|
||||
)
|
||||
|
||||
// Analyzer sends a prompt to Claude and returns the response text.
|
||||
type Analyzer interface {
|
||||
Analyze(ctx context.Context, prompt string) (string, error)
|
||||
}
|
||||
|
||||
// Constructor builds an Analyzer from the analyzer config block.
|
||||
type Constructor func(cfg config.AnalyzerConfig) (Analyzer, error)
|
||||
|
||||
var registry = map[string]Constructor{}
|
||||
|
||||
// Register makes an analyzer constructor available under mode. Called from
|
||||
// each mode implementation's init().
|
||||
func Register(mode string, ctor Constructor) {
|
||||
if _, exists := registry[mode]; exists {
|
||||
panic(fmt.Sprintf("analyze: constructor already registered for mode %q", mode))
|
||||
}
|
||||
registry[mode] = ctor
|
||||
}
|
||||
|
||||
// Build looks up the constructor for cfg.Mode and invokes it.
|
||||
func Build(cfg config.AnalyzerConfig) (Analyzer, error) {
|
||||
ctor, ok := registry[cfg.Mode]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("analyze: no analyzer registered for mode %q", cfg.Mode)
|
||||
}
|
||||
return ctor(cfg)
|
||||
}
|
||||
Reference in new issue
Block a user