Documentation
¶
Index ¶
- Variables
- type Client
- func (c *Client) AnalyseVideo(ctx context.Context, url string, meta *domain.VideoMetadata) (*domain.Report, error)
- func (c *Client) Ask(ctx context.Context, question string, cached *domain.CachedAnalysis, ...) (string, error)
- func (c *Client) AskDeep(ctx context.Context, question string, videoURL string, ...) (string, error)
- func (c *Client) EnrichSignal(ctx context.Context, sig *domain.Signal, userContext string) (*domain.SignalEnrichment, error)
- func (c *Client) ParseSignalFromPrompt(ctx context.Context, prompt string) (*domain.Signal, error)
- func (c *Client) ResearchSynthesize(ctx context.Context, topic string, hits []*domain.CachedAnalysis, ...) (*domain.ResearchReport, error)
- func (c *Client) Synthesise(ctx context.Context, entries []*domain.CachedAnalysis, userContext string) (*domain.DigestReport, error)
- type LensContext
Constants ¶
This section is empty.
Variables ¶
var ErrQuotaExhausted = fmt.Errorf("Gemini quota limit persists after retry — likely daily RPD exhausted (resets at midnight PT)\n run 'vger quota' to see today's usage; check https://aistudio.google.com for details")
ErrQuotaExhausted is returned by AnalyseVideo when the Gemini quota cannot be recovered after a 65s retry. The original 429 (no RetryInfo) could be either TPM throttle or daily RPD exhaustion — if a 65s wait didn't help, treat it as RPD. The quota resets at midnight Pacific Time.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
APIKey string
Model string
LogFn func(string) // optional; called with status messages (e.g. model fallback warnings)
QuotaFn func() // optional; called once per GenerateContent dispatch (successful or not)
TokenFn func(int64) // optional; called with TotalTokenCount after each successful response
// contains filtered or unexported fields
}
Client implements domain.VideoAnalyser using the Gemini API.
func NewWithTools ¶ added in v0.5.0
NewWithTools creates a Client that registers CNCF lookup and URL validation as Gemini function-calling tools, enabling a multi-turn ReAct analysis loop.
func (*Client) AnalyseVideo ¶
func (c *Client) AnalyseVideo(ctx context.Context, url string, meta *domain.VideoMetadata) (*domain.Report, error)
AnalyseVideo passes the video URL directly to the Gemini multimodal API and returns a structured report. No video download is performed.
When a cncfClient was provided via NewWithTools, the analysis runs as a multi-turn function-calling loop where Gemini invokes tools to verify CNCF stages and validate URLs before producing its final answer.
Error handling for oversized videos and quota:
- Token overflow (400 INVALID_ARGUMENT): all gemini-2.5 models share the same 1M token limit, so no fallback helps. Returns a clear user-facing error.
- Connection reset: Gemini dropped the TCP connection server-side. The Pro model uses a different processing pipeline that may handle this better; retried once.
- Daily quota exhausted (429 with no RetryInfo): returns ErrQuotaExhausted so callers can stop dispatching further requests immediately.
func (*Client) Ask ¶
func (c *Client) Ask(ctx context.Context, question string, cached *domain.CachedAnalysis, userContext string) (string, error)
Ask answers a follow-up question about a previously analysed video. It uses the cached report as text context — no video re-upload is performed. userContext is an optional description of the user's tech stack/environment; when non-empty it is prepended to the prompt to tailor the answer.
func (*Client) AskDeep ¶
func (c *Client) AskDeep(ctx context.Context, question string, videoURL string, cached *domain.CachedAnalysis, userContext string) (string, error)
AskDeep answers a question about a video by re-submitting the YouTube URL to Gemini as a FileData part, giving the model direct access to the full video content. This is more expensive than Ask but can answer anything. userContext is injected into the prompt when non-empty.
func (*Client) EnrichSignal ¶ added in v0.6.0
func (c *Client) EnrichSignal(ctx context.Context, sig *domain.Signal, userContext string) (*domain.SignalEnrichment, error)
EnrichSignal calls Gemini to generate AI context for an existing signal. It fills WhatItIs, Maturity, Alternatives, StackFit, and NextSteps. userContext is injected into the prompt when non-empty so that StackFit and NextSteps are tailored to the user's actual environment.
func (*Client) ParseSignalFromPrompt ¶ added in v0.6.0
ParseSignalFromPrompt extracts a Signal from a free-text description using Gemini. The caller is responsible for assigning ID, Status, Date, CreatedAt, and UpdatedAt.
func (*Client) ResearchSynthesize ¶ added in v0.7.0
func (c *Client) ResearchSynthesize( ctx context.Context, topic string, hits []*domain.CachedAnalysis, projects []cncf.ProjectInfo, signals []*domain.Signal, talks []domain.VideoListing, lens *LensContext, maxDepth int, cacheSearcher domain.CacheSearcher, userContext string, ) (*domain.ResearchReport, error)
ResearchSynthesize sends all gathered research context to Gemini and returns a structured ResearchReport.
When maxDepth is 0, a single GenerateContent call is made (Phase 1 behaviour). When maxDepth > 0, an investigation phase runs first: Gemini uses ask_video, search_cache, and lookup_cncf_project tools to deepen its understanding, producing a text transcript that is appended to the synthesis prompt (Phase 2 / Option B).
cacheSearcher is required when maxDepth > 0 and may be nil otherwise.
func (*Client) Synthesise ¶
func (c *Client) Synthesise(ctx context.Context, entries []*domain.CachedAnalysis, userContext string) (*domain.DigestReport, error)
Synthesise takes a slice of cached analyses and asks Gemini to produce a cross-playlist digest: overarching theme, recommended learning path, and priority talks to watch first. userContext is injected when non-empty.
type LensContext ¶ added in v0.7.0
type LensContext struct {
RoleContext string
}
lensContext carries the role context from an analytical lens for research synthesis. Exported so the CLI can pass it in without importing lenses.go internals.