Curation v2 step 2: Claude Opus 5 editor, the Brief, per-provider budgets
- AnthropicBackend (Messages API, cached system block, output_config.effort,
server-side fallbacks, refusal surfaced as an error); Llms { bulk, editor }
with editor_or_bulk(); PriceTable-based UsageMeter per provider.
- [anthropic], [editorial], deepseek.max_concurrent_requests and
curation.max_article_count config; startup logs resolved providers.
- Budget day is the UTC date of started_at, preloaded from
runs.provider_costs_json; finish_run writes provider_costs_json and
config_json. Stage A batches run concurrently with per-batch budget checks.
- Editor prompt with one-line "why" per pick; no minimum lineup size;
--max-articles is a ceiling; top-up branch deleted; why stored on picks and
issue_articles.why and rendered in chapters and In this issue.
- Summaries on the editor client (3k-token input, concurrency 4, bulk then
excerpt fallback); "The Brief" replaces From the Editor; section intros gone.
- Colophon carries per-provider costs and models.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A1rCLQeKBgnBo3oTgHuTMe
This commit is contained in:
+11
-4
@@ -86,6 +86,7 @@ pub fn issue() -> Issue {
|
||||
section: "Top Stories".into(),
|
||||
position: 0,
|
||||
is_lead: true,
|
||||
why: Some("The systems story with enough operational detail to matter".into()),
|
||||
summary: Some("What it argues, and why it is worth the time.".into()),
|
||||
llm: None,
|
||||
discussion: Some(discussion(1, 1001)),
|
||||
@@ -95,12 +96,11 @@ pub fn issue() -> Issue {
|
||||
section: "Niche Corner".into(),
|
||||
position: 0,
|
||||
is_lead: false,
|
||||
why: Some("A small-scene delight outside the usual technical orbit".into()),
|
||||
summary: None,
|
||||
llm: None,
|
||||
discussion: None,
|
||||
};
|
||||
let mut section_intros = BTreeMap::new();
|
||||
section_intros.insert("Top Stories".to_string(), "The day in brief.".to_string());
|
||||
let mut summaries = BTreeMap::new();
|
||||
summaries.insert(2, "A short abstract for the second piece.".to_string());
|
||||
|
||||
@@ -122,7 +122,6 @@ pub fn issue() -> Issue {
|
||||
},
|
||||
editorial: Editorial {
|
||||
front_page_html: "<p>Two stories today, both worth your coffee.</p>".into(),
|
||||
section_intros,
|
||||
summaries,
|
||||
},
|
||||
world_briefing: Some(WorldBriefing {
|
||||
@@ -141,7 +140,15 @@ pub fn issue() -> Issue {
|
||||
}],
|
||||
}),
|
||||
colophon: Colophon {
|
||||
model: "deepseek-v4-flash".into(),
|
||||
provider_costs: BTreeMap::from([
|
||||
("deepseek".into(), 0.0231),
|
||||
("anthropic".into(), 0.05),
|
||||
]),
|
||||
models: Models {
|
||||
bulk: "deepseek-v4-flash".into(),
|
||||
editor: "claude-opus-5".into(),
|
||||
summaries: "claude-opus-5".into(),
|
||||
},
|
||||
entries_fetched: 431,
|
||||
feeds_seen: 92,
|
||||
candidates: 120,
|
||||
|
||||
Reference in New Issue
Block a user