docs(agenten): Fallakte Livia und Agenten-Briefing sichern
`LIVIA_PROFIL_UND_PROMPT.md` hält Livia als Exposé Master fest, wie sie vor Runde 8 war: Personalblatt, Aufgabenkatalog, Kanäle und Systeme, das Exposé-Dossier mit elf Bereichen und neun Pflichtfeldern, die `missingFacts`-Regel der Textmaschine — dazu ein System-Prompt, mit dem sich diese Fassung ausserhalb des Repositories rekonstruieren lässt. `archive/livia/` ergänzt die Beschreibung um die Wiederherstellung: die 23 Dateien der Exposé-Funktion als wörtliche Kopie im Original-Pfadlayout sowie ein Manifest jeder Stelle, an der Livia in geteilten Dateien verdrahtet war. Beides ist mit Runde 8 nicht überholt, sondern der Referenzstand: die Exposé-Funktion wurde nicht entfernt, sondern nachgeordnet. Das Manifest beschreibt allerdings den Rückbau eines vollständigen Entfernens und damit ein Szenario, das so nicht eingetreten ist. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
ba8dc39483
commit
2037e5a463
33 files changed
+4431
No files matched your search
@@ -0,0 +1,11 @@
|
||||
{
|
||||
id: 'livia',
|
||||
name: 'Livia',
|
||||
role: 'Exposé Master',
|
||||
email: 'livia@property-on.ch',
|
||||
level: AgentLevel.CORE,
|
||||
department: AgentDepartment.CENTRAL_SERVICES,
|
||||
rollout: AgentRollout.IN_PROGRESS,
|
||||
isCore: true,
|
||||
},
|
||||
{
|
||||
@@ -0,0 +1,141 @@
|
||||
// ── agentProtocol.ts Zeilen 369,449 ──────────────────────────────
|
||||
{
|
||||
id: 'proto-009',
|
||||
agentId: AGENT_IDS.LIVIA,
|
||||
timestamp: '2026-05-20T09:10:00.000Z',
|
||||
eventType: AgentProtocolEventType.TASK_RUN,
|
||||
title: 'Lagebeschrieb Neuhegistrasse 12 in Kurz- und Langfassung erstellt',
|
||||
description:
|
||||
'Mikrolage im Radius von 800 Metern, Makrolage Winterthur Neuhegi, Erreichbarkeit und geplante Umfeldentwicklung ausgewertet. Kurztext 574 Zeichen, Langtext 2 280 Zeichen, jede Aussage mit Quelle und Abrufdatum.',
|
||||
status: AgentProtocolStatus.SUCCESS,
|
||||
objectId: 'OBJ-2503',
|
||||
channel: AgentChannelType.WORKSPACE_CHAT,
|
||||
triggeredBy: AgentTriggerSource.SYSTEM,
|
||||
input: [
|
||||
{ label: 'Objektadresse', value: 'Neuhegistrasse 12, 8404 Winterthur' },
|
||||
{ label: 'Quartier', value: 'Winterthur Neuhegi' },
|
||||
{ label: 'Analyseradius', value: '800 Meter' },
|
||||
{ label: 'Tonalität', value: 'sachlich' },
|
||||
],
|
||||
processingSteps: [
|
||||
{
|
||||
id: 'proto-009-ps-1',
|
||||
label: 'Adresse gegen die amtlichen Adressdaten geprüft und dem Quartier zugeordnet',
|
||||
},
|
||||
{
|
||||
id: 'proto-009-ps-2',
|
||||
label: 'Mikrolage abgegangen',
|
||||
detail: 'Nachbarschaft, Erdgeschossnutzungen, Immissionslage, Publikumsfrequenz, Parkierung',
|
||||
},
|
||||
{
|
||||
id: 'proto-009-ps-3',
|
||||
label: 'Makrolage eingeordnet',
|
||||
detail: 'Beschäftigtenentwicklung, Branchenmix und Bedeutung im Wirtschaftsraum Winterthur',
|
||||
},
|
||||
{
|
||||
id: 'proto-009-ps-4',
|
||||
label: 'Erreichbarkeit und Nahversorgung mit Distanz und Wegzeit erfasst',
|
||||
},
|
||||
{ id: 'proto-009-ps-5', label: 'Amtliche Publikationen im Umfeld gesichtet' },
|
||||
{ id: 'proto-009-ps-6', label: 'Kurztext und Langtext geschrieben, Quellen angehängt' },
|
||||
],
|
||||
output: [
|
||||
{
|
||||
label: 'Kurztext für Inserat',
|
||||
value:
|
||||
'Die Fläche liegt in Winterthur Neuhegi, einem in den vergangenen zehn Jahren umgebauten Arbeitsplatzquartier mit Wohn-, Büro- und Produktionsnutzung. Die Haltestelle Neuhegi ist in vier Gehminuten erreichbar, der Bahnhof Winterthur Grüze in neun Minuten mit dem Bus. Einkaufen, Verpflegung und Kinderbetreuung befinden sich innerhalb von 400 Metern.',
|
||||
},
|
||||
{
|
||||
label: 'Abschnitte des Langtexts',
|
||||
value: [
|
||||
'Mikrolage — Nachbarschaft und Erdgeschossnutzungen',
|
||||
'Makrolage — Wirtschaftsraum Winterthur',
|
||||
'Erreichbarkeit — öffentlicher Verkehr, Autobahn A1, Velowege',
|
||||
'Nahversorgung — Einkaufen, Verpflegung, Betreuung, Gesundheit',
|
||||
'Umfeldentwicklung — Arealentwicklung nördlich der Neuhegistrasse',
|
||||
],
|
||||
},
|
||||
{ label: 'Belegte Aussagen', value: '31 von 31 Aussagen mit Quelle und Abrufdatum' },
|
||||
],
|
||||
sourceReferences: [
|
||||
{
|
||||
id: 'proto-009-src-1',
|
||||
label: 'Amtliche Publikation zur Arealentwicklung',
|
||||
documentName: 'Amtliche Meldung — Gestaltungsplan Neuhegi Nord',
|
||||
locator: 'Publikation vom 24.04.2026',
|
||||
quote:
|
||||
'«Der Gestaltungsplan für das Areal nördlich der Neuhegistrasse wurde bewilligt; die Bauarbeiten beginnen im ersten Quartal 2027.»',
|
||||
},
|
||||
{
|
||||
id: 'proto-009-src-2',
|
||||
label: 'Fahrplandaten Haltestelle Neuhegi',
|
||||
documentName: 'Öffentliche Verkehrsdaten Winterthur',
|
||||
locator: 'Abruf 20.05.2026',
|
||||
},
|
||||
{
|
||||
id: 'proto-009-src-3',
|
||||
label: 'Objektstammdaten OBJ-2503',
|
||||
documentName: 'Bewirtschaftungssystem — Objektblatt OBJ-2503',
|
||||
locator: 'Adresse und Nutzungsart',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ── agentProtocol.ts Zeilen 691,703 ──────────────────────────────
|
||||
{
|
||||
id: 'proto-019',
|
||||
agentId: AGENT_IDS.LIVIA,
|
||||
timestamp: '2026-05-18T10:05:00.000Z',
|
||||
eventType: AgentProtocolEventType.MESSAGE_PROCESSED,
|
||||
title: 'Auftrag für den Lagebeschrieb Wankdorffeldstrasse 8 entgegengenommen',
|
||||
description:
|
||||
'Die Adresse wurde gegen die amtlichen Adressdaten geprüft und dem Entwicklungsgebiet Bern Wankdorf zugeordnet. Der Arbeitsauftrag ist eingereiht; die Umfeldanalyse läuft im Radius von 800 Metern.',
|
||||
status: AgentProtocolStatus.INFO,
|
||||
objectId: 'OBJ-2559',
|
||||
channel: AgentChannelType.WORKSPACE_CHAT,
|
||||
triggeredBy: AgentTriggerSource.SYSTEM,
|
||||
},
|
||||
|
||||
// ── agentProtocol.ts Zeilen 836,848 ──────────────────────────────
|
||||
{
|
||||
id: 'proto-028',
|
||||
agentId: AGENT_IDS.LIVIA,
|
||||
timestamp: '2026-05-07T10:15:00.000Z',
|
||||
eventType: AgentProtocolEventType.TASK_RUN,
|
||||
title: 'Umfeldänderung Winterthur Neuhegi gemeldet',
|
||||
description:
|
||||
'Die bewilligte Arealentwicklung nördlich der Neuhegistrasse verändert den Abschnitt «Umfeldentwicklung» in vier Lagebeschrieben. Die betroffenen Textabschnitte sind markiert, die Quelle mit Publikationsdatum hinterlegt.',
|
||||
status: AgentProtocolStatus.SUCCESS,
|
||||
objectId: 'OBJ-2503',
|
||||
channel: AgentChannelType.WORKSPACE_CHAT,
|
||||
triggeredBy: AgentTriggerSource.SYSTEM,
|
||||
},
|
||||
|
||||
// ── agentProtocol.ts Zeilen 945,956 ──────────────────────────────
|
||||
{
|
||||
id: 'proto-034',
|
||||
agentId: AGENT_IDS.LIVIA,
|
||||
timestamp: '2026-04-01T05:30:00.000Z',
|
||||
eventType: AgentProtocolEventType.TASK_RUN,
|
||||
title: 'Quartalslauf: 184 Lagebeschriebe gegen die Quellen geprüft',
|
||||
description:
|
||||
'162 Lagebausteine wurden bestätigt, 14 Abschnitte als veraltet markiert und erneuert, 9 Objekte für den nächsten Lauf vorgemerkt. Jede Prüfung ist je Objekt nachvollziehbar protokolliert.',
|
||||
status: AgentProtocolStatus.SUCCESS,
|
||||
channel: AgentChannelType.WORKSPACE_CHAT,
|
||||
triggeredBy: AgentTriggerSource.SYSTEM,
|
||||
},
|
||||
|
||||
// ── agentProtocol.ts Zeilen 972,983 ──────────────────────────────
|
||||
{
|
||||
id: 'proto-036',
|
||||
agentId: AGENT_IDS.LIVIA,
|
||||
timestamp: '2026-03-05T08:50:00.000Z',
|
||||
eventType: AgentProtocolEventType.SETTINGS_SAVED,
|
||||
title: 'Analyseradius und Quellentypen gespeichert',
|
||||
description:
|
||||
'Der Radius der Umfeldanalyse wurde von 500 auf 800 Meter erhöht und «Medienberichte» als Quellentyp abgewählt. Bestehende Lagebeschriebe werden im nächsten Quartalslauf nachgeführt.',
|
||||
status: AgentProtocolStatus.SUCCESS,
|
||||
triggeredBy: AgentTriggerSource.USER,
|
||||
triggeredByName: OPERATOR,
|
||||
},
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
// ── Livia — erledigt ───────────────────────────────────────────────────────
|
||||
{
|
||||
id: 'awi-livia-01',
|
||||
agentId: AGENT_IDS.LIVIA,
|
||||
kind: AgentWorkItemKind.LOCATION_MODULE,
|
||||
area: AgentDomainArea.LOCATION,
|
||||
title: 'Lagebeschrieb erstellt — Hardturmstrasse 118, Zürich Kreis 5',
|
||||
summary:
|
||||
'Zum neuen Vermarktungsauftrag entstanden ein Kurztext für Inserat und Portal sowie ein Langtext für das Exposé, jeweils mit Quellenverzeichnis und Abrufdatum zu jeder Aussage.',
|
||||
objectId: 'OBJ-2365',
|
||||
objectLabel: 'Hardturmstrasse 118, 8005 Zürich — Bürofläche 640 m², Zürich Kreis 5',
|
||||
sourceChannel: AgentChannelType.WORKSPACE_CHAT,
|
||||
targetChannel: AgentChannelType.EMAIL,
|
||||
createdAt: '2026-04-09T09:15:00.000Z',
|
||||
completedAt: '2026-04-09T11:40:00.000Z',
|
||||
priority: AgentWorkItemPriority.LOW,
|
||||
status: AgentWorkItemStatus.COMPLETED,
|
||||
requiresDecision: false,
|
||||
inputs: [
|
||||
{ label: 'Objektadresse aus dem Vermarktungsauftrag', value: 'Hardturmstrasse 118, 8005 Zürich' },
|
||||
{ label: 'Quartierzuordnung', value: 'Zürich Kreis 5 (Escher Wyss), geprüft gegen die amtlichen Adressdaten' },
|
||||
{ label: 'Untersuchungsradius Mikrolage', value: '500 Meter Umkreis, Erdgeschossnutzungen und Erreichbarkeit' },
|
||||
{ label: 'Auftraggebende Person', value: 'Nadine Brunner, Vermarktung Zürich' },
|
||||
],
|
||||
result: [
|
||||
{
|
||||
label: 'Kurztext für Inserat und Portal',
|
||||
value:
|
||||
'Die Fläche liegt im Kreis 5 zwischen Escher-Wyss-Platz und Hardbrücke, in einem Quartier mit hohem Anteil an Dienstleistung, Gastronomie und Kreativwirtschaft. Die Haltestelle Escher-Wyss-Platz ist in vier Gehminuten erreichbar, der Bahnhof Hardbrücke in acht Minuten.',
|
||||
},
|
||||
{
|
||||
label: 'Langtext für das Exposé',
|
||||
value:
|
||||
'Dreiteiliger Text mit Mikrolage (Nachbarschaft, Erdgeschossnutzungen, Publikumsfrequenz, Parkierung), Makrolage (Wirtschaftsstruktur Stadt Zürich, Beschäftigtenentwicklung Kreis 5, Steuerlage) und Umfeldentwicklung — insgesamt 3 940 Zeichen.',
|
||||
},
|
||||
{
|
||||
label: 'Erreichbarkeit',
|
||||
value: [
|
||||
'Tram- und Bushaltestelle Escher-Wyss-Platz: 300 Meter, 4 Gehminuten',
|
||||
'Bahnhof Zürich Hardbrücke: 650 Meter, 8 Gehminuten',
|
||||
'Autobahnanschluss Zürich-Hardturm: 1,4 Kilometer',
|
||||
'Veloweg entlang der Hardturmstrasse, durchgehend abgetrennt',
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Nahversorgung',
|
||||
value: [
|
||||
'Einkaufen: zwei Supermärkte innerhalb von 400 Metern',
|
||||
'Verpflegung: 14 Gastronomiebetriebe im Umkreis von 300 Metern',
|
||||
'Kinderbetreuung: zwei Kindertagesstätten innerhalb von 600 Metern',
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Umfeldentwicklung',
|
||||
value:
|
||||
'Arealentwicklung Hardturm-Areal in Etappen bis 2029; Zonenänderung rechtskräftig seit 2024 (Quelle: amtliche Publikation, abgerufen 09.04.2026).',
|
||||
},
|
||||
{ label: 'Quellenverzeichnis', value: '11 Quellen mit Abrufdatum, je Aussage zugeordnet' },
|
||||
],
|
||||
processingSteps: [
|
||||
{
|
||||
id: 'awi-livia-01-step-1',
|
||||
label: 'Adresse aufgenommen und dem Quartier zugeordnet',
|
||||
detail: 'Schreibweise gegen die amtlichen Adressdaten geprüft, Zuordnung Zürich Kreis 5.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-01-step-2',
|
||||
label: 'Mikrolage im Umkreis von 500 Metern abgegangen',
|
||||
detail: 'Nachbarschaft, Erdgeschossnutzungen, Immissionslage, Publikumsfrequenz und Parkierung erfasst.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-01-step-3',
|
||||
label: 'Makrolage eingeordnet',
|
||||
detail: 'Wirtschaftsstruktur, Beschäftigtenentwicklung und Steuerlage der Stadt Zürich ausgewertet.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-01-step-4',
|
||||
label: 'Amtliche Publikationen zum Umfeld gesichtet',
|
||||
detail: 'Arealentwicklung und Zonenänderung als für das Objekt relevant eingestuft.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-01-step-5',
|
||||
label: 'Kurz- und Langtext geschrieben, Quellen angehängt',
|
||||
detail: 'Je Aussage Quelle und Abrufdatum hinterlegt, Ergebnis am Objekt abgelegt.',
|
||||
},
|
||||
],
|
||||
sourceReferences: [
|
||||
{
|
||||
id: 'awi-livia-01-src-1',
|
||||
label: 'Amtliche Publikation zur Zonenänderung Hardturm',
|
||||
documentName: 'Amtliche-Publikation_Zonenaenderung-Hardturm_2024-11-08.pdf',
|
||||
locator: 'Seite 3, abgerufen 09.04.2026',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-01-src-2',
|
||||
label: 'Fahrplanauskunft öffentlicher Verkehr',
|
||||
documentName: 'Erreichbarkeitsauswertung_OBJ-2365_2026-04-09.pdf',
|
||||
locator: 'Tabelle «Haltestellen im Umkreis», abgerufen 09.04.2026',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-01-src-3',
|
||||
label: 'Quellenverzeichnis zum Lagebeschrieb',
|
||||
documentName: 'Lagebeschrieb_OBJ-2365_Quellen_2026-04-09.pdf',
|
||||
locator: 'Seiten 1–2, 11 Einträge',
|
||||
},
|
||||
],
|
||||
availableActions: [AgentWorkItemAction.OPEN_SOURCE, AgentWorkItemAction.MARK_DONE],
|
||||
history: [
|
||||
{
|
||||
id: 'awi-livia-01-hist-1',
|
||||
at: '2026-04-09T09:15:00.000Z',
|
||||
actor: 'Livia',
|
||||
action: 'Vermarktungsauftrag übernommen',
|
||||
note: 'Adresse geprüft und dem Quartier Zürich Kreis 5 zugeordnet.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-01-hist-2',
|
||||
at: '2026-04-09T11:40:00.000Z',
|
||||
actor: 'Livia',
|
||||
action: 'Lagebeschrieb abgelegt und zugestellt',
|
||||
note: 'Kurz- und Langtext mit 11 Quellen an die Vermarktung Zürich.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-01-hist-3',
|
||||
at: '2026-04-14T08:05:00.000Z',
|
||||
actor: 'Nadine Brunner',
|
||||
action: 'Text für das Inserat übernommen',
|
||||
note: 'Kurztext unverändert im Portalauftritt veröffentlicht.',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ── Livia — pendent: Review eines unsicheren Ergebnisses ───────────────────
|
||||
{
|
||||
id: 'awi-livia-02',
|
||||
agentId: AGENT_IDS.LIVIA,
|
||||
kind: AgentWorkItemKind.LOCATION_MODULE,
|
||||
area: AgentDomainArea.LOCATION,
|
||||
title: 'Unsichere Aussage zum Entwicklungsgebiet Wankdorf — Review erbeten',
|
||||
summary:
|
||||
'Für den Langtext zum Objekt in Bern liegen zwei Quellen mit unterschiedlichen Angaben zur Inbetriebnahme der neuen Haltestelle vor. Die Aussage bleibt aus dem Text ausgeklammert, bis entschieden ist, welche Angabe gilt.',
|
||||
objectId: 'OBJ-2733',
|
||||
objectLabel: 'Wankdorffeldstrasse 12, 3014 Bern — Bürofläche 1. bis 3. Obergeschoss, 1 150 m²',
|
||||
sourceChannel: AgentChannelType.WORKSPACE_CHAT,
|
||||
targetChannel: AgentChannelType.EMAIL,
|
||||
createdAt: '2026-05-07T07:45:00.000Z',
|
||||
priority: AgentWorkItemPriority.MEDIUM,
|
||||
status: AgentWorkItemStatus.PENDING,
|
||||
requiresDecision: true,
|
||||
escalationReason:
|
||||
'Review eines unsicheren Ergebnisses: Zwei belegte Quellen nennen unterschiedliche Zeitpunkte für die Inbetriebnahme der Haltestelle Wankdorffeld. Eine Aussage ohne eindeutigen Beleg geht nicht in den Exposétext.',
|
||||
decisionQuestion:
|
||||
'Welche Angabe soll in den Langtext übernommen werden — «ab Dezember 2027» gemäss amtlicher Publikation oder «ab Sommer 2028» gemäss Mitteilung der Standortförderung — oder soll der Absatz zur Haltestelle vorerst entfallen?',
|
||||
inputs: [
|
||||
{ label: 'Objektadresse aus dem Vermarktungsauftrag', value: 'Wankdorffeldstrasse 12, 3014 Bern' },
|
||||
{ label: 'Quartierzuordnung', value: 'Bern Wankdorf, Entwicklungsgebiet Wankdorf-Nord' },
|
||||
{
|
||||
label: 'Widersprüchliche Quellen',
|
||||
value: [
|
||||
'Amtliche Publikation vom 12.03.2026 — Inbetriebnahme Dezember 2027',
|
||||
'Mitteilung der Standortförderung vom 28.04.2026 — Inbetriebnahme Sommer 2028',
|
||||
],
|
||||
},
|
||||
{ label: 'Auftraggebende Person', value: 'Nadine Brunner, Vermarktung Zürich (Mandat Bern)' },
|
||||
],
|
||||
result: [
|
||||
{ label: 'Stand', value: 'Kurztext fertig, Langtext zu 90 Prozent — ein Absatz ist ausgeklammert' },
|
||||
{
|
||||
label: 'Fertiger Kurztext',
|
||||
value:
|
||||
'Das Objekt liegt im Entwicklungsgebiet Wankdorf, unmittelbar an der Achse zwischen Bahnhof Wankdorf und Autobahnanschluss Bern-Wankdorf. Das Umfeld ist geprägt von Dienstleistung, öffentlichen Institutionen und Verkaufsflächen.',
|
||||
},
|
||||
{
|
||||
label: 'Ausgeklammerter Absatz',
|
||||
value:
|
||||
'Die geplante Haltestelle Wankdorffeld liegt rund 200 Meter vom Objekt entfernt. Die Inbetriebnahme ist für [Zeitpunkt offen] vorgesehen.',
|
||||
},
|
||||
{
|
||||
label: 'Warum die Angabe zählt',
|
||||
value:
|
||||
'Die Wegzeit zum öffentlichen Verkehr sinkt mit der neuen Haltestelle von 11 auf 3 Gehminuten — die Aussage ist für Interessenten mit Publikumsverkehr entscheidend.',
|
||||
},
|
||||
{ label: 'Übrige Quellen', value: '9 Quellen mit Abrufdatum, alle eindeutig und im Text belegt' },
|
||||
],
|
||||
processingSteps: [
|
||||
{
|
||||
id: 'awi-livia-02-step-1',
|
||||
label: 'Adresse aufgenommen und dem Quartier zugeordnet',
|
||||
detail: 'Zuordnung Bern Wankdorf, Entwicklungsgebiet Wankdorf-Nord.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-02-step-2',
|
||||
label: 'Mikro- und Makrolage beschrieben',
|
||||
detail: 'Nachbarschaft, Erreichbarkeit, Nahversorgung und Wirtschaftsraum Bern erfasst.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-02-step-3',
|
||||
label: 'Amtliche Publikationen zum Umfeld gesichtet',
|
||||
detail: 'Beim Verkehrsvorhaben zwei Quellen mit unterschiedlichen Zeitangaben gefunden.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-02-step-4',
|
||||
label: 'Aussage ausgeklammert statt gemittelt',
|
||||
detail: 'Der Absatz bleibt offen, bis die massgebende Quelle bestimmt ist.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-02-step-5',
|
||||
label: 'Review vorgelegt',
|
||||
detail: 'Beide Belege mit Fundstelle und Abrufdatum zur Entscheidung beigelegt.',
|
||||
},
|
||||
],
|
||||
sourceReferences: [
|
||||
{
|
||||
id: 'awi-livia-02-src-1',
|
||||
label: 'Amtliche Publikation Verkehrsvorhaben Wankdorffeld',
|
||||
documentName: 'Amtliche-Publikation_Haltestelle-Wankdorffeld_2026-03-12.pdf',
|
||||
locator: 'Seite 2, Abschnitt «Terminprogramm»',
|
||||
quote:
|
||||
'«Die Inbetriebnahme der Haltestelle Wankdorffeld ist auf den Fahrplanwechsel im Dezember 2027 vorgesehen.»',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-02-src-2',
|
||||
label: 'Mitteilung der Standortförderung Bern',
|
||||
documentName: 'Standortfoerderung-Bern_Mitteilung_2026-04-28.pdf',
|
||||
locator: 'Seite 1, abgerufen 07.05.2026',
|
||||
quote:
|
||||
'«Wegen der Anpassung der Gleisgeometrie verschiebt sich die Eröffnung der Haltestelle Wankdorffeld auf Sommer 2028.»',
|
||||
},
|
||||
],
|
||||
availableActions: [
|
||||
AgentWorkItemAction.DECIDE,
|
||||
AgentWorkItemAction.EDIT,
|
||||
AgentWorkItemAction.APPROVE,
|
||||
AgentWorkItemAction.OPEN_SOURCE,
|
||||
],
|
||||
editableFields: [
|
||||
{
|
||||
id: 'awi-livia-02-field-date',
|
||||
label: 'Zu verwendender Zeitpunkt',
|
||||
value: 'Dezember 2027',
|
||||
helperText: 'Alternativ «Sommer 2028» oder leer lassen, damit der Absatz entfällt.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-02-field-paragraph',
|
||||
label: 'Absatz zur Haltestelle',
|
||||
value:
|
||||
'Die geplante Haltestelle Wankdorffeld liegt rund 200 Meter vom Objekt entfernt. Die Inbetriebnahme ist auf Dezember 2027 vorgesehen; die Wegzeit zum öffentlichen Verkehr verkürzt sich damit von 11 auf 3 Gehminuten.',
|
||||
multiline: true,
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-02-field-source',
|
||||
label: 'Anzugebende Quelle',
|
||||
value: 'Amtliche Publikation Verkehrsvorhaben Wankdorffeld, 12.03.2026, abgerufen 07.05.2026',
|
||||
helperText: 'Erscheint im Quellenverzeichnis des Exposés.',
|
||||
},
|
||||
],
|
||||
history: [
|
||||
{
|
||||
id: 'awi-livia-02-hist-1',
|
||||
at: '2026-05-07T07:45:00.000Z',
|
||||
actor: 'Livia',
|
||||
action: 'Widerspruch erkannt und Review vorgelegt',
|
||||
note: 'Zwei belegte Quellen mit unterschiedlichen Zeitangaben zur Haltestelle.',
|
||||
},
|
||||
{
|
||||
id: 'awi-livia-02-hist-2',
|
||||
at: '2026-05-15T09:20:00.000Z',
|
||||
actor: 'Livia',
|
||||
action: 'Quellen erneut geprüft',
|
||||
note: 'Quartalsprüfung: keine neuere amtliche Publikation vorhanden, Widerspruch besteht weiter.',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -0,0 +1,76 @@
|
||||
// ══ src/services/ai/IAIService.ts — Typen (aktuell Zeilen 200–232) ══
|
||||
// ── Exposé texts (Livia) ──────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Die Textabschnitte eines Exposés. Jeder lässt sich einzeln erzeugen —
|
||||
* gesamthaft heisst schlicht: alle nacheinander (Runde 4, §8.5.2).
|
||||
*/
|
||||
export const ExposeTextSection = {
|
||||
TITLE: 'TITLE',
|
||||
TEASER: 'TEASER',
|
||||
OBJECT: 'OBJECT',
|
||||
LOCATION: 'LOCATION',
|
||||
MUNICIPALITY: 'MUNICIPALITY',
|
||||
FEATURES: 'FEATURES',
|
||||
HIGHLIGHTS: 'HIGHLIGHTS',
|
||||
} as const
|
||||
export type ExposeTextSection = typeof ExposeTextSection[keyof typeof ExposeTextSection]
|
||||
|
||||
export type ExposeTonality = 'SACHLICH' | 'HOCHWERTIG' | 'EINLADEND'
|
||||
|
||||
export interface ExposeTextInput {
|
||||
section: ExposeTextSection
|
||||
tonality: ExposeTonality
|
||||
/** Ausschliesslich belegte Angaben aus «Meine Objekte» — nichts Erfundenes. */
|
||||
facts: Record<string, string | number | undefined>
|
||||
}
|
||||
|
||||
export interface ExposeTextResult {
|
||||
section: ExposeTextSection
|
||||
text: string
|
||||
/** Angaben, die für einen vollständigen Text fehlen — statt sie zu erfinden. */
|
||||
missingFacts: string[]
|
||||
}
|
||||
|
||||
|
||||
// ══ src/services/ai/IAIService.ts — Methode im Interface (Zeile 281) ══
|
||||
recommendPreMarketRent(input: PreMarketRentInput): Promise<AIResponse<PreMarketRentRecommendation>>
|
||||
|
||||
// Exposé-Texte (Livia) — pro Abschnitt auslösbar
|
||||
generateExposeText(input: ExposeTextInput): Promise<AIResponse<ExposeTextResult>>
|
||||
|
||||
// Legacy methods
|
||||
|
||||
// ══ src/services/ai/mock/MockAIService.ts — Importe (17-18, 25) ══
|
||||
ExposeTextInput,
|
||||
ExposeTextResult,
|
||||
import { buildExposeText } from './exposeTextBuilder'
|
||||
|
||||
// ══ src/services/ai/mock/MockAIService.ts — Implementierung (303-310) ══
|
||||
}),
|
||||
|
||||
generateExposeText: (input: ExposeTextInput) =>
|
||||
traceMock<ExposeTextResult>('generateExposeText', async () => {
|
||||
await delay(SIMULATED_DELAY.medium)
|
||||
return { data: buildExposeText(input), provenance: mockProvenance() }
|
||||
}),
|
||||
|
||||
|
||||
// ══ src/services/ai/backend/BackendAIService.ts — Importe (62-63) ══
|
||||
ExposeTextInput,
|
||||
ExposeTextResult,
|
||||
|
||||
// ══ src/services/ai/backend/BackendAIService.ts — Delegation (678-690) ══
|
||||
},
|
||||
|
||||
// ── generateExposeText ──────────────────────────────────────────────────────
|
||||
//
|
||||
// Bewusst ohne eigenen LLM-Aufruf: der Text darf ausschliesslich auf erfassten
|
||||
// Objektdaten beruhen (Runde 4, §8.5.2). Ein freies Sprachmodell würde genau
|
||||
// die fehlenden Angaben plausibel ergänzen, die hier rot markiert gehören.
|
||||
// Deshalb erzeugt auch im Backend-Betrieb der deterministische Builder den
|
||||
// Entwurf; er nennt Lücken, statt sie zu füllen.
|
||||
generateExposeText(input: ExposeTextInput): Promise<AIResponse<ExposeTextResult>> {
|
||||
return MockAIService.generateExposeText(input)
|
||||
},
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
export const STALE_AGENT_CONNECTIONS = 60 * 1000
|
||||
export const STALE_CALENDAR = 60 * 1000
|
||||
export const STALE_EXPOSE_LEADS = 30 * 1000 // aggressive — Weiterleitungen sollen sofort erscheinen
|
||||
export const STALE_VISIT_ASSIGNMENTS = 60 * 1000
|
||||
/** CRM-Leads ändern sich im Quellsystem, nicht hier — eine Minute genügt. */
|
||||
|
||||
// ── Livia — Leads und Exposé (Runde 4, §8) ───────────────────────────────────
|
||||
|
||||
export const EXPOSE_LEAD_TABS = {
|
||||
ACTIVE: 'aktive-leads',
|
||||
ARCHIVED: 'archivierte-leads',
|
||||
} as const
|
||||
export type ExposeLeadTab = typeof EXPOSE_LEAD_TABS[keyof typeof EXPOSE_LEAD_TABS]
|
||||
|
||||
export const EXPOSE_LEAD_TAB_LABELS: Record<ExposeLeadTab, string> = {
|
||||
[EXPOSE_LEAD_TABS.ACTIVE]: 'Aktive Leads',
|
||||
[EXPOSE_LEAD_TABS.ARCHIVED]: 'Archivierte Leads',
|
||||
}
|
||||
|
||||
/** Die drei Schritte des Exposé-Prozesses (§8.5). */
|
||||
export const EXPOSE_STEPS = ['Hochladen', 'Exposé', 'Export'] as const
|
||||
|
||||
export const EXPOSE_IMAGE_CATEGORY_LABELS: Record<string, string> = {
|
||||
EXTERIOR: 'Aussenansicht',
|
||||
INTERIOR: 'Innenansicht',
|
||||
FLOORPLAN: 'Grundriss',
|
||||
SURROUNDINGS: 'Umgebung',
|
||||
OTHER: 'Sonstiges',
|
||||
}
|
||||
|
||||
export const EXPOSE_DOCUMENT_TYPE_LABELS: Record<string, string> = {
|
||||
FLOORPLAN: 'Grundriss',
|
||||
LEASE_CONTRACT: 'Mietvertrag',
|
||||
ENERGY_CERTIFICATE: 'Energieausweis (GEAK)',
|
||||
SITE_PLAN: 'Situationsplan',
|
||||
OTHER: 'Sonstiges',
|
||||
}
|
||||
|
||||
export const EXPOSE_TONALITY_LABELS: Record<string, string> = {
|
||||
SACHLICH: 'Sachlich',
|
||||
HOCHWERTIG: 'Hochwertig',
|
||||
EINLADEND: 'Einladend',
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// ══ src/components/market-leads/LeadDetail.tsx — Import + Hook (Z. 5, 42) ══
|
||||
import { useCreateExposeLead } from '../../hooks/useExposeLeads'
|
||||
const forwardLead = useCreateExposeLead()
|
||||
|
||||
// ══ handleForward (Z. 61-77) ══
|
||||
function handleForward() {
|
||||
const count = selectedIds.length
|
||||
forwardLead.mutate(
|
||||
{
|
||||
prospect: companyName,
|
||||
contacts: contacts.map(c => c.value),
|
||||
locationHint: signal.locationHint,
|
||||
propertyIds: selectedIds,
|
||||
sourceSignalId: signal.id,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
setSelectedIds([])
|
||||
showToast(`An Livia weitergeleitet — ${count} Objekt(e) für ${companyName}.`, 'success')
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
// ══ Knopf «An Livia weiterleiten» (Z. 193-205) ══
|
||||
))}
|
||||
<Button
|
||||
variant="contained"
|
||||
startIcon={<Forward size={15} />}
|
||||
disabled={selectedIds.length === 0 || forwardLead.isPending}
|
||||
onClick={handleForward}
|
||||
sx={{ mt: 1, textTransform: 'none', bgcolor: DS_BRAND.main, '&:hover': { bgcolor: DS_BRAND.hoverAlt } }}
|
||||
>
|
||||
An Livia zur Exposé-Erstellung weiterleiten
|
||||
{selectedIds.length > 0 && ` (${selectedIds.length})`}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
@@ -0,0 +1,48 @@
|
||||
// ══ src/services/agentWorkloadService.ts — Importe (Z. 3-4) ══
|
||||
import { ExposeLeadStatus } from '../domain/exposeLead'
|
||||
import type { ExposeLead } from '../domain/exposeLead'
|
||||
|
||||
// ══ URGENT_FROM (Z. 33-40) ══
|
||||
const URGENT_FROM = {
|
||||
reminders: 5,
|
||||
visits: 4,
|
||||
expose: 5,
|
||||
dataGaps: 10,
|
||||
} as const
|
||||
|
||||
/** Zeitfenster der Auswertung. */
|
||||
|
||||
// ══ Eingabefeld (Z. 48-55) ══
|
||||
export interface AgentWorkloadInput {
|
||||
reminders: Reminder[]
|
||||
visits: VisitAssignment[]
|
||||
exposeLeads: ExposeLead[]
|
||||
leads: UnifiedLead[]
|
||||
properties: Property[]
|
||||
}
|
||||
|
||||
|
||||
// ══ Livias Auslastungsbahn (Z. 117-129) ══
|
||||
// ── Livia: weitergeleitete Leads ────────────────────────────────────────────
|
||||
const openExpose = input.exposeLeads.filter(l => l.status === ExposeLeadStatus.ACTIVE).length
|
||||
const livia: AgentWorkload = {
|
||||
agentId: 'livia',
|
||||
count: openExpose,
|
||||
label: `${openExpose} ${plural(openExpose, 'Exposé offen', 'Exposés offen')}`,
|
||||
tone: tone(openExpose, URGENT_FROM.expose),
|
||||
voice: openExpose === 0
|
||||
? 'Kein Exposé offen. Leite mir einen Lead weiter, dann lege ich los.'
|
||||
: `${openExpose} ${plural(openExpose, 'Lead wartet', 'Leads warten')} auf ein Exposé von mir.`,
|
||||
}
|
||||
|
||||
// ── Nora: Marktchancen ──────────────────────────────────────────────────────
|
||||
|
||||
// ══ src/hooks/useAgentWorkload.ts — alle Livia-Stellen ══
|
||||
import { useExposeLeads } from './useExposeLeads'
|
||||
const { data: exposeLeads = [], isLoading: exposeLoading } = useExposeLeads()
|
||||
const data = useMemo(
|
||||
() => computeAgentWorkload({ reminders, visits, exposeLeads, leads, properties }),
|
||||
[reminders, visits, exposeLeads, leads, properties],
|
||||
remindersLoading || visitsLoading || exposeLoading ||
|
||||
leadsLoading || propertiesLoading,
|
||||
}
|
||||
Reference in new issue
Block a user