feat(cmd): shared buildProcessor + wire immediate web summarization
Extract the engine wiring (YouTube source, AI-router summarizer, store sink) into buildProcessor, shared by cmdRun and cmdServe. It returns (nil, nil) — not an error — on incomplete config, which is the queue-only fallback for serve. engineProcessor adapts the engine to web.Processor: load the video row, run the engine, clear the manual queue flag on a produced summary (mirrors the runner). cmdServe wires it onto web.App.Processor; cmdRun reuses buildProcessor so the wiring is no longer duplicated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+24
-21
@@ -22,15 +22,11 @@ import (
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"gitea.d-ma.be/mathias/tapir/internal/adapters/llm"
|
||||
"gitea.d-ma.be/mathias/tapir/internal/adapters/secrets"
|
||||
"gitea.d-ma.be/mathias/tapir/internal/adapters/store"
|
||||
"gitea.d-ma.be/mathias/tapir/internal/adapters/summarizer"
|
||||
"gitea.d-ma.be/mathias/tapir/internal/adapters/youtube"
|
||||
"gitea.d-ma.be/mathias/tapir/internal/auth"
|
||||
"gitea.d-ma.be/mathias/tapir/internal/config"
|
||||
"gitea.d-ma.be/mathias/tapir/internal/runner"
|
||||
"gitea.d-ma.be/mathias/tapir/internal/usecase"
|
||||
"gitea.d-ma.be/mathias/tapir/internal/web"
|
||||
"gitea.d-ma.be/mathias/tapir/internal/web/oidc"
|
||||
)
|
||||
@@ -120,24 +116,16 @@ func cmdRun(ctx context.Context, log *slog.Logger) error {
|
||||
}
|
||||
defer st.Close()
|
||||
|
||||
secretStore := secrets.NewFileStore(cfg.SecretsFile)
|
||||
src := youtube.New(youtube.Config{
|
||||
ClientID: cfg.YTClientID,
|
||||
ClientSecret: cfg.YTClientSecret,
|
||||
TokenSecretRef: cfg.YTTokenRef,
|
||||
PreferredLanguages: []string{"en"},
|
||||
}, secretStore)
|
||||
|
||||
// Local Primary only; no BYO fallback for the demo (fallback nil).
|
||||
primary := summarizer.Endpoint{
|
||||
Client: llm.New(cfg.GatewayURL, cfg.GatewayKey, cfg.SummarizerModel, cfg.SummarizerTimeout),
|
||||
Provider: "local",
|
||||
Model: cfg.SummarizerModel,
|
||||
// Same wiring the web serve path uses (buildProcessor). ValidateForRun above
|
||||
// already required the engine's inputs, so a nil here is a genuine config gap.
|
||||
engine, err := buildProcessor(cfg, st)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sum := summarizer.New(primary, nil)
|
||||
|
||||
engine := usecase.NewEngine(src, sum, st)
|
||||
r := runner.New(src, st, engine, cfg.UserID, log)
|
||||
if engine == nil {
|
||||
return fmt.Errorf("run: incomplete summarization config (gateway, youtube credentials, secrets file)")
|
||||
}
|
||||
r := runner.New(engine.Source, st, engine, cfg.UserID, log)
|
||||
|
||||
log.Info("starting run", "user", cfg.UserID, "model", cfg.SummarizerModel,
|
||||
"gateway", cfg.GatewayURL, "poll_interval", cfg.PollInterval)
|
||||
@@ -204,6 +192,21 @@ func cmdServe(ctx context.Context, log *slog.Logger) error {
|
||||
log.Info("web youtube connect enabled", "redirect", cfg.YTConnectRedirectURL)
|
||||
}
|
||||
|
||||
// Immediate summarization for the web "Summarize" button. When the engine can
|
||||
// be built (gateway + YouTube credentials + secrets present), a click runs the
|
||||
// summary now in the background; otherwise the button stays queue-only and the
|
||||
// next `tapir run` does the work (buildProcessor returns nil — never an error).
|
||||
engine, err := buildProcessor(cfg, st)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if engine != nil {
|
||||
app.Processor = &engineProcessor{engine: engine, store: st}
|
||||
log.Info("web immediate summarization enabled", "model", cfg.SummarizerModel)
|
||||
} else {
|
||||
log.Info("web summarization is queue-only (incomplete engine config)")
|
||||
}
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: cfg.HTTPAddr,
|
||||
Handler: app.Router(),
|
||||
|
||||
Reference in New Issue
Block a user