Plumb ctx through classifier and Ollama HTTP path
OllamaClient.Generate/GenerateText/call now take ctx and build the HTTP request via NewRequestWithContext, so an in-flight LLM call is aborted when the parent context is cancelled (Ctrl-C). Classifier.Classify and its tier helpers take ctx too. ProcessFunc gets a ctx parameter so the poller can forward its cancellable context down to classification. Explainer.summarize manages its own 60s context since reaction-driven flow has no parent ctx to inherit.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package classifier
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
@@ -38,7 +39,8 @@ func NewClassifier(ollama *OllamaClient, matrixClient *matrix.Client) *Classifie
|
||||
}
|
||||
|
||||
// Classify runs the appropriate classification pipeline for a feed item.
|
||||
func (c *Classifier) Classify(item *ingestion.FeedItem) (*ClassifyResult, error) {
|
||||
// ctx is checked before any LLM call so shutdown aborts in-flight work.
|
||||
func (c *Classifier) Classify(ctx context.Context, item *ingestion.FeedItem) (*ClassifyResult, error) {
|
||||
// Direct routing — no LLM call needed
|
||||
if item.DirectRoute != nil {
|
||||
slog.Debug("direct route", "guid", item.GUID, "channel", *item.DirectRoute)
|
||||
@@ -60,16 +62,16 @@ func (c *Classifier) Classify(item *ingestion.FeedItem) (*ClassifyResult, error)
|
||||
}
|
||||
|
||||
if item.Tier == 2 {
|
||||
return c.classifyTier2(item, recent)
|
||||
return c.classifyTier2(ctx, item, recent)
|
||||
}
|
||||
|
||||
return c.classifyTier1(item, recent)
|
||||
return c.classifyTier1(ctx, item, recent)
|
||||
}
|
||||
|
||||
func (c *Classifier) classifyTier1(item *ingestion.FeedItem, recent []storage.RecentHeadline) (*ClassifyResult, error) {
|
||||
func (c *Classifier) classifyTier1(ctx context.Context, item *ingestion.FeedItem, recent []storage.RecentHeadline) (*ClassifyResult, error) {
|
||||
prompt := BuildTier1Prompt(item, recent)
|
||||
|
||||
raw, err := c.ollama.Generate(prompt)
|
||||
raw, err := c.ollama.Generate(ctx, prompt)
|
||||
if err != nil {
|
||||
c.handleOllamaFailure(err)
|
||||
return nil, fmt.Errorf("ollama generate: %w", err)
|
||||
@@ -94,7 +96,7 @@ func (c *Classifier) classifyTier1(item *ingestion.FeedItem, recent []storage.Re
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Classifier) classifyTier2(item *ingestion.FeedItem, recent []storage.RecentHeadline) (*ClassifyResult, error) {
|
||||
func (c *Classifier) classifyTier2(ctx context.Context, item *ingestion.FeedItem, recent []storage.RecentHeadline) (*ClassifyResult, error) {
|
||||
// Run keyword gating first
|
||||
gatingResult, reason := RunGating(item.Headline, item.Lede)
|
||||
|
||||
@@ -115,7 +117,7 @@ func (c *Classifier) classifyTier2(item *ingestion.FeedItem, recent []storage.Re
|
||||
// Stage 3 (ambiguous) or Stage 1 (definite post needing routing) — send to LLM
|
||||
prompt := BuildTier2Prompt(item, recent)
|
||||
|
||||
raw, err := c.ollama.Generate(prompt)
|
||||
raw, err := c.ollama.Generate(ctx, prompt)
|
||||
if err != nil {
|
||||
c.handleOllamaFailure(err)
|
||||
return nil, fmt.Errorf("ollama generate: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user