Files
worldmonitor/todos/053-pending-p2-daily-market-brief-framework-no-api-equivalent.md
Elie Habib 110ab402c4 feat(intelligence): analytical framework selector for AI panels (#2380)
* feat(frameworks): add settings section and import modal

- Add Analysis Frameworks group to preferences-content.ts between Intelligence and Media sections
- Per-panel active framework display (read-only, 4 panels)
- Skill library list with built-in badge, Rename and Delete actions for imported frameworks
- Import modal with two tabs: From agentskills.io (fetch + preview) and Paste JSON
- All error cases handled inline: network, domain validation, missing instructions, invalid JSON, duplicate name, instructions too long, rate limit
- Add api/skills/fetch-agentskills.ts edge function (proxy to agentskills.io)
- Add analysis-framework-store.ts (loadFrameworkLibrary, saveImportedFramework, deleteImportedFramework, renameImportedFramework, getActiveFrameworkForPanel)
- Add fw-* CSS classes to main.css matching dark panel aesthetic

* feat(panels): wire analytical framework store into InsightsPanel, CountryDeepDive, DailyMarketBrief, DeductionPanel

- InsightsPanel: append active framework to geoContext in updateFromClient(); subscribe in constructor, unsubscribe in destroy()
- CountryIntelManager: pass framework as query param to fetchCountryIntelBrief(); subscribe to re-open brief on framework change; unsubscribe in destroy()
- DataLoaderManager: add dailyBriefGeneration counter for stale-result guard; pass frameworkAppend to buildDailyMarketBrief(); subscribe to framework changes to force refresh; unsubscribe in destroy()
- daily-market-brief service: add frameworkAppend? field to BuildDailyMarketBriefOptions; append to extendedContext before summarize call
- DeductionPanel: append active framework to geoContext in handleSubmit() before RPC call

* feat(frameworks): add FrameworkSelector UI component

- Create FrameworkSelector component with premium/locked states
- Premium: select dropdown with all framework options, change triggers setActiveFrameworkForPanel
- Locked: disabled select + PRO badge, click calls showGatedCta(FREE_TIER)
- InsightsPanel: adds asterisk note (client-generated analysis hint)
- Wire into InsightsPanel, DailyMarketBriefPanel, DeductionPanel (via this.header)
- Wire into CountryDeepDivePanel header right-side (no Panel base, panel=null)
- Add framework-selector CSS to main.css

* fix(frameworks): make new proto fields optional in generated types

* fix(frameworks): extract firstMsg to satisfy strict null checks in tsconfig.api.json

* fix(docs): add blank lines around lists/headings to pass markdownlint

* fix(frameworks): add required proto string fields to call sites after make generate

* chore(review): add code review todos 041-057 for PR #2380

7 review agents (TypeScript, Security, Architecture, Performance,
Simplicity, Agent-Native, Learnings) identified 17 findings across
5 P1, 8 P2, and 4 P3 categories.
2026-03-27 23:36:44 +04:00

2.6 KiB

status, priority, issue_id, tags, dependencies
status priority issue_id tags dependencies
pending p2 053
code-review
quality
agent-native
analytical-frameworks

DailyMarketBrief framework injection is client-only — no API equivalent, misleads API consumers

Problem Statement

The framework selector for DailyMarketBriefPanel is listed alongside CountryBrief, Deduction, and Insights as a first-class framework panel. However, the framework is injected entirely client-side: data-loader.ts calls buildDailyMarketBrief({ frameworkAppend: getActiveFrameworkForPanel('daily-market-brief')?.systemPromptAppend }) which runs in the browser. There is no server-side equivalent. An agent calling POST /api/news/v1/summarize-article with systemAppend gets framework-shaped base summaries but does NOT get the full DailyMarketBrief structure (items, stances, actionPlan, riskWatch). The PR description does not document this limitation.

Findings

  • src/app/data-loader.ts:1468frameworkAppend: getActiveFrameworkForPanel('daily-market-brief')?.systemPromptAppend — client-side only
  • src/services/daily-market-brief.ts:416buildDailyMarketBrief runs in browser; calls generateSummary via RPC but the full pipeline is client-side
  • PR body lists DailyMarketBrief as having framework support with no caveat (unlike InsightsPanel which has a * note)
  • Flagged by: agent-native-reviewer

Proposed Solutions

Add a UI note to the DailyMarketBrief FrameworkSelector (like InsightsPanel's * note) indicating "Applies to client-generated analysis only". Update PR description to match. Pros: Honest documentation, no server changes needed | Effort: Trivial | Risk: Low

Option B: Add server-side DailyMarketBrief endpoint accepting systemAppend

Create an RPC endpoint for buildDailyMarketBrief that accepts systemAppend and returns the full structured output. Pros: Full agent-native parity | Cons: Large architectural change, moves complex client logic to server | Effort: Large | Risk: High (scope creep)

Technical Details

  • Files: src/app/data-loader.ts, src/services/daily-market-brief.ts, src/components/DailyMarketBriefPanel.ts
  • PR: koala73/worldmonitor#2380

Acceptance Criteria

  • DailyMarketBrief FrameworkSelector has a * note indicating client-only scope (like InsightsPanel)
  • PR description updated to document the limitation
  • Or: server-side DailyMarketBrief endpoint added with systemAppend support

Work Log

  • 2026-03-27: Identified during PR #2380 review by agent-native-reviewer