Skip to content

feat(energy): analyst context — JODI oil/gas + IEA oil stocks per-country data#2741

Merged
koala73 merged 2 commits intomainfrom
feat/energy-phase25-analyst-context
Apr 5, 2026
Merged

feat(energy): analyst context — JODI oil/gas + IEA oil stocks per-country data#2741
koala73 merged 2 commits intomainfrom
feat/energy-phase25-analyst-context

Conversation

@koala73
Copy link
Copy Markdown
Owner

@koala73 koala73 commented Apr 5, 2026

Summary

  • Adds productSupply, gasFlows, oilStocksCover optional fields to AnalystContext
  • Fetches per-country JODI oil (energy:jodi-oil:v1:{ISO2}), JODI gas (energy:jodi-gas:v1:{ISO2}), and IEA oil stocks (energy:iea-oil-stocks:v1:{ISO2}) data when a country ISO2 is in context
  • productSupply + gasFlows active for economic, geo, all domains; oilStocksCover for economic, all
  • All three fetches are concurrent via Promise.allSettled, fail-safe — missing Redis data returns undefined silently
  • Completes Energy Phase 2.5 (PR 4 of 4 seed PRs already merged)

Note

Depends on merged PRs: #2732 (JODI oil), #2733 (IEA stocks), #2735 (chokepoint baselines). PR #2736 (JODI gas) pending — gasFlows will be a no-op until that merges.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldmonitor Ready Ready Preview, Comment Apr 5, 2026 6:32pm

Request Review

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 5, 2026

Greptile Summary

This PR wires three new per-country energy data sources (JODI oil, JODI gas, IEA oil stocks) into AnalystContext — the assembly, caching, and activeSources tracking are all correct — but the corresponding fields are never emitted into the analyst system prompt in chat-analyst-prompt.ts, so the fetched data never reaches the LLM.

Confidence Score: 4/5

Hold for one fix: data is fetched and reported as active but silently dropped before the LLM sees it.

A P1 defect exists on the primary feature path — all three new fields are populated and tracked in activeSources, but chat-analyst-prompt.ts has no code to emit them into the prompt. The Redis calls incur real cost and activeSources misleads callers into thinking the analyst has this context when it does not.

chat-analyst-prompt.ts needs DOMAIN_SECTIONS entries and emit blocks for productSupply, gasFlows, and oilStocksCover before merging.

Important Files Changed

Filename Overview
server/worldmonitor/intelligence/v1/chat-analyst-context.ts Adds productSupply/gasFlows/oilStocksCover to AnalystContext with correct concurrent fetching, but prompt integration is missing — data is fetched and tracked but silently dropped before reaching the LLM

Sequence Diagram

sequenceDiagram
    participant C as Caller
    participant AC as assembleAnalystContext
    participant R as Redis
    participant PB as buildAnalystSystemPrompt
    participant LLM as LLM

    C->>AC: assembleAnalystContext(iso2, domain)
    par Concurrent fetches
        AC->>R: energy:jodi-oil:v1:{iso2}
        R-->>AC: productSupply data
        AC->>R: energy:jodi-gas:v1:{iso2}
        R-->>AC: gasFlows data
        AC->>R: energy:iea-oil-stocks:v1:{iso2}
        R-->>AC: oilStocksCover data
    end
    AC-->>C: AnalystContext (productSupply/gasFlows/oilStocksCover set, activeSources includes JODIOil/JODIGas/IEAStocks)
    C->>PB: buildAnalystSystemPrompt(ctx)
    Note over PB: ⚠ productSupply / gasFlows / oilStocksCover
    Note over PB: never read — not in DOMAIN_SECTIONS
    Note over PB: and no emit blocks added
    PB-->>C: system prompt (missing JODI/IEA sections)
    C->>LLM: prompt (LLM never sees energy data)
Loading

Reviews (1): Last reviewed commit: "feat(energy): extend analyst context wit..." | Re-trigger Greptile

Comment on lines +48 to +50
productSupply?: string;
gasFlows?: string;
oilStocksCover?: string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 New fields fetched but never injected into the analyst prompt

productSupply, gasFlows, and oilStocksCover are populated in AnalystContext and tracked in activeSources (surfacing as "JODIOil", "JODIGas", "IEAStocks"), but chat-analyst-prompt.ts never reads or emits them. DOMAIN_SECTIONS for geo and economic — and the catch-all null path — all omit these three fields, so the LLM analyst receives no JODI/IEA data despite the Redis lookups. The feature is a no-op end-to-end until the prompt builder is wired up.

Add emit blocks and register the fields in DOMAIN_SECTIONS in chat-analyst-prompt.ts:

// After the refineryUtil block:
if (ctx.productSupply && include('productSupply'))
  contextSections.push(`## Oil Product Supply\n${ctx.productSupply}`);
if (ctx.gasFlows && include('gasFlows'))
  contextSections.push(`## Gas Flows\n${ctx.gasFlows}`);
if (ctx.oilStocksCover && include('oilStocksCover'))
  contextSections.push(`## IEA Oil Stocks\n${ctx.oilStocksCover}`);

And add 'productSupply', 'gasFlows' to DOMAIN_SECTIONS['geo'] and DOMAIN_SECTIONS['economic'], and 'oilStocksCover' to DOMAIN_SECTIONS['economic'].

Comment on lines +409 to +410
const lngShare = typeof d.lngShareOfImports === 'number' ? Math.round((d.lngShareOfImports as number) * 100) : null;
const split = lngShare != null ? ` (LNG ${lngShare}%, pipeline ${100 - lngShare}%)` : '';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 lngShareOfImports scale assumption not yet verified

lngShareOfImports is multiplied by 100, assuming it is a fraction (0–1). If PR #2736 seeds it as a percentage (0–100), the output would be LNG 5000%, pipeline -4900%. Since the JODI-gas seed script hasn't merged yet, the contract should be confirmed before this code goes live.

Comment on lines +377 to +378
const data = await getCachedJson(`energy:jodi-oil:v1:${iso2}`, true);
if (!data || typeof data !== 'object') return undefined;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Cache key strings should be exported constants in cache-keys.ts

The three new key templates (energy:jodi-oil:v1:, energy:jodi-gas:v1:, energy:iea-oil-stocks:v1:) are inline string literals. Existing per-country prefixes like GAS_STORAGE_KEY_PREFIX live in cache-keys.ts; keeping the new ones there too makes global search-and-rename safe and keeps the key registry complete.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@koala73 koala73 merged commit dbac5fb into main Apr 5, 2026
10 checks passed
@koala73 koala73 deleted the feat/energy-phase25-analyst-context branch April 5, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant