Search, chat and research over parliamentary speeches and documents
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

191 lines
8.4 KiB

# Everything specific to one parliament, in one file. Nothing secret belongs here.
#
# This is the Swedish Riksdag configuration, shipped as the worked example. To
# target a different parliament, copy this file, change the values, and write an
# ingest adapter — see docs/PORTING.md.
#
# Override the path with PARLIAMENT_CONFIG=/etc/plenum/parliament.yaml so a
# deployment's own values live outside the repository and never appear in a diff.
schema_version: 1
parliament:
id: se-riksdagen
name: Sveriges riksdag # in the language set below
name_en: Swedish Parliament
country: SE
chamber: unicameral # unicameral | lower | upper
open_data_url: https://data.riksdagen.se
data_start_year: 1993
language:
# Postgres text-search configuration. Must match the database's app.fts_config
# setting — the application refuses to start on a mismatch, because a silent
# mismatch returns near-zero rows with no error.
# See: SELECT cfgname FROM pg_ts_config;
fts_config: swedish
prompt_language: sv # selects prompts/<lang>/
name: svenska # the language's own name, for prompts
name_en: Swedish # its English name, for English-language prompts
locale: sv-SE
# Characters that must survive verbatim into search queries. Transliterating
# these silently breaks matching on most Swedish terms.
preserve_characters: "åäö"
months:
januari: "01"
februari: "02"
mars: "03"
april: "04"
maj: "05"
juni: "06"
juli: "07"
augusti: "08"
september: "09"
oktober: "10"
november: "11"
december: "12"
# Domain words injected into prompts, written in `prompt_language`. These exist
# because "motion", "yrkande" and "riksmöte" have no stable English equivalents;
# the database columns are neutral and the country's own word lives here.
vocabulary:
member: riksdagsledamot
member_plural: riksdagsledamöter
chamber: kammaren
speech: anförande
speech_plural: anföranden
document: motion
document_plural: motioner
proposal: yrkande
proposal_plural: yrkanden
committee: utskott
constituency: valkrets
session: riksmöte
# Display order is list order. `active: false` keeps historical parties
# renderable without offering them as a filter.
parties:
- {code: S, name: Socialdemokraterna, color: "#E8112d", active: true}
- {code: M, name: Moderaterna, color: "#52BDEC", active: true}
- {code: SD, name: Sverigedemokraterna, color: "#DDDD00", active: true}
- {code: C, name: Centerpartiet, color: "#009933", active: true}
- {code: V, name: Vänsterpartiet, color: "#b51a0e", active: true}
- {code: KD, name: Kristdemokraterna, color: "#000077", active: true}
- {code: MP, name: Miljöpartiet de gröna, color: "#83CF39", active: true}
- {code: L, name: Liberalerna, color: "#006AB3", active: true}
- {code: NYD, name: Ny demokrati, color: "#ffff2b", active: false}
party_defaults:
# Independents and unknowns.
unknown_color: "#9aa5b8"
# How a party code appears in rendered text, e.g. "Anna Andersson (MP)".
# Used to detect and verify attributions in generated answers.
code_pattern: "[A-ZÅÄÖ]{1,3}"
# Keys are the values stored in talks.kammaraktivitet. Titles and descriptions
# are shown in the UI and are in `prompt_language`.
activity_types:
kam-vo: {title: Beslut, description: "Riksdagen fattar det formella beslutet i ärendet."}
bet: {title: Debatt om beslut, description: "Ledamöterna debatterar ett förslag innan beslut fattas."}
kam-fs: {title: Frågestund, description: "Ministrar svarar direkt på frågor från ledamöter."}
kam-ar: {title: Information från regeringen, description: "Regeringen informerar riksdagen i en aktuell fråga."}
ip: {title: Interpellationsdebatt, description: "Debatt om en skriftlig fråga till en minister."}
kam-sf: {title: Statsministerns frågestund, description: "Statsministern svarar på frågor från ledamöter."}
sam-ou: {title: Öppen utfrågning, description: "Utskottet frågar ut experter eller ansvariga personer offentligt."}
kam-ad: {title: Aktuell debatt, description: "Snabb debatt om en aktuell politisk fråga."}
kam-al: {title: Allmänpolitisk debatt, description: "Ledamöterna debatterar valfria politiska ämnen."}
kam-bu: {title: Budgetdebatt, description: "Debatt om regeringens budgetförslag."}
kam-bp: {title: Bordläggning, description: "Ett ärende anmäls i kammaren inför fortsatt behandling."}
kam-pd: {title: Partiledardebatt, description: "Partiledarna debatterar politikens stora frågor."}
kam-dv: {title: Debatt med anledning av vårpropositionen, description: "Debatt om regeringens ekonomiska vårproposition."}
sam-se: {title: Öppet seminarium, description: "Öppet seminarium eller samtal om ett särskilt tema."}
kam-ud: {title: Utrikespolitisk debatt, description: "Debatt om Sveriges utrikespolitik."}
# Glosses for values stored in the data. The values themselves are never
# translated — only explained, so prompts can reason about them.
document_subtypes:
Enskild motion: "Motion från en eller ett fåtal ledamöter"
Kommittémotion: "Motion från ett partis utskottsgrupp"
Partimotion: "Motion från ett helt parti, ofta undertecknad av partiledaren"
decisions:
Bifall: {label: Bifall, meaning: approved}
Avslag: {label: Avslag, meaning: rejected}
# Annual parliamentary session. Deliberately not called "term": the European
# Parliament uses that for its five-year cycle, so it would be ambiguous.
sessions:
label_format: "{start}/{end_short}" # 2022 -> "2022/23"
starts_month: 9
first_year: 1990
# Identifier shapes, templated into prompts and tool descriptions so the model
# can recognise and construct them without them being hardcoded in Python.
ids:
person_id:
example: "0448485371626"
pattern: "^[0-9]{10,13}$"
description: "Riksdagen intressent-id, a numeric string"
speech_id:
example: "GH09116-16"
pattern: "^[A-ZÅÄÖ0-9]+-[0-9]+$"
description: "{source_doc_id}-{sequence}"
doc_id:
example: "HD02846"
pattern: "^[A-ZÅÄÖ0-9]+$"
description: "Document id from the open-data portal"
debate_id:
example: "2021-06-17:42"
pattern: '^\d{4}-\d{2}-\d{2}:\d+$'
description: "{date}:{index within that day}"
urls:
person_photo: "https://data.riksdagen.se/filarkiv/bilder/ledamot/{person_id}_192.jpg"
person_page: "https://www.riksdagen.se/sv/ledamoter-partier/ledamot/_{person_id}"
document_page: "https://www.riksdagen.se/sv/dokument-och-lagar/dokument/_{doc_id}"
# Consumed by the ingest CLI. `adapter` names the module that knows this
# source's JSON shape; everything else is data.
sources:
adapter: ingest.adapters.riksdagen
speeches:
kind: zip-dataset
url_template: "https://data.riksdagen.se/dataset/anforande/anforande-{range}.json.zip"
dest_dir: talks
documents:
kind: zip-dataset
url_template: "https://data.riksdagen.se/dataset/dokument/mot-{range}.json.zip"
ranges: ["1990-1997", "1998-2001", "2002-2005", "2006-2009",
"2010-2013", "2014-2017", "2018-2021", "2022-2025"]
dest_dir: motioner
people:
kind: json
url: "https://data.riksdagen.se/personlista/?utformat=json"
dest_dir: personer
embeddings:
model: qwen3-embedding # LLM_MODEL_EMBEDDING overrides
# Must equal the vector(N) width of the embedding columns. Checked at startup
# against the actual column type, because a mismatch fails deep inside pgvector
# with an error that says nothing about configuration.
dimension: 384
base_url_env: EMBEDDING_BASE_URL
chunk_chars: 500
# Served to the frontend via GET /api/meta.
site:
# Deployment identity, not country data. Upstream ships neutral values; a
# deployment overrides them in its own PARLIAMENT_CONFIG file so its branding
# never appears in a diff against upstream.
title: plenum
tagline: "Sök i riksdagens anföranden och motioner"
# Markdown, so a deployment can rewrite its own copy without touching source.
# Paths are relative to CONTENT_DIR (default: ./content).
explainer_file: sv/explainer.md
limit_warning_file: sv/limit_warning.md
# Upstream ships these empty. A deployment fills them in via its own
# PARLIAMENT_CONFIG file, which keeps personal contact details out of the repo.
guide_file: sv/user-guide.md
contact:
email: null
url: null