mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:21:09 +02:00
feat(events): Phase 3 — AI tools, Event-Scout template, feedback loop
- Add discover_events (auto) and suggest_event (propose) to shared-ai tool catalog. discover_events reads the discovery feed, suggest_event creates a proposal to save a discovered event to the user's calendar. - Add Event-Scout agent template with daily "Events der Woche" mission. Policy: discover_events=auto, suggest_event=propose, all else denied. - Add frontend tool implementations in events/tools.ts — discover_events calls the feed API, suggest_event delegates to discoveryStore.saveEvent. - Add feedback.ts — computes implicit user profile from save/dismiss history (category affinity + source quality as 0–2x weight multipliers). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2f226a93aa
commit
2c0d866287
5 changed files with 406 additions and 0 deletions
92
packages/shared-ai/src/agents/templates/event-scout.ts
Normal file
92
packages/shared-ai/src/agents/templates/event-scout.ts
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import { AI_PROPOSABLE_TOOL_NAMES } from '../../policy/proposable-tools';
|
||||
import type { AgentTemplate } from './types';
|
||||
import type { AiPolicy } from '../../policy/types';
|
||||
|
||||
/**
|
||||
* Event-Scout agent — discovers public events in the user's configured
|
||||
* regions and suggests the most relevant ones. Runs daily or on-demand.
|
||||
*
|
||||
* discover_events is auto (read-only, feeds context to the planner).
|
||||
* suggest_event is propose (creates a proposal the user must approve).
|
||||
*/
|
||||
|
||||
const EVENT_SCOUT_POLICY: AiPolicy = {
|
||||
tools: {
|
||||
...Object.fromEntries(AI_PROPOSABLE_TOOL_NAMES.map((n) => [n, 'deny' as const])),
|
||||
discover_events: 'auto',
|
||||
suggest_event: 'propose',
|
||||
},
|
||||
defaultsByModule: {
|
||||
events: 'propose',
|
||||
},
|
||||
defaultForAi: 'deny',
|
||||
};
|
||||
|
||||
export const eventScoutTemplate: AgentTemplate = {
|
||||
id: 'event-scout',
|
||||
version: '1',
|
||||
icon: '🎪',
|
||||
label: 'Event-Scout',
|
||||
tagline: 'Findet Events in deiner Region und schlaegt passende vor',
|
||||
description: `Der Event-Scout durchsucht deine konfigurierten Regionen nach oeffentlichen Veranstaltungen und schlaegt dir die relevantesten vor.
|
||||
|
||||
Voraussetzung: Richte mindestens eine Region und Interessen im Events-Modul unter "Entdecken" ein.
|
||||
|
||||
Der Agent:
|
||||
1. Liest deine Event-Discovery-Feeds (automatisch, ohne Nachfrage)
|
||||
2. Waehlt die 3-5 relevantesten Events aus
|
||||
3. Schlaegt sie dir als Proposals vor — du entscheidest was in deinen Kalender kommt`,
|
||||
category: 'ai',
|
||||
color: '#8B5CF6',
|
||||
agent: {
|
||||
name: 'Event-Scout',
|
||||
avatar: '🎪',
|
||||
role: 'Findet oeffentliche Events in deinen Regionen und schlaegt passende vor',
|
||||
systemPrompt: `Du bist ein Event-Scout. Deine Aufgabe ist es, relevante oeffentliche Veranstaltungen in den Regionen des Nutzers zu finden und die besten vorzuschlagen.
|
||||
|
||||
Vorgehen:
|
||||
1. Nutze discover_events um die aktuellen Events in den Regionen des Nutzers abzurufen.
|
||||
2. Bewerte die Events nach Relevanz: Passen sie zu den Interessen? Sind sie zeitlich nah? Besonders interessant?
|
||||
3. Waehle die 3-5 besten Events aus.
|
||||
4. Nutze suggest_event fuer jedes ausgewaehlte Event. Gib eine kurze Begruendung warum es relevant ist.
|
||||
|
||||
Qualitaetskriterien:
|
||||
- Bevorzuge Events die zeitlich nah sind (naechste 7 Tage > naechste 14 Tage)
|
||||
- Bevorzuge Events die zu den Interessen des Nutzers passen
|
||||
- Variiere die Kategorien — nicht 5x das gleiche Genre
|
||||
- Schreib die Begruendung auf Deutsch, kurz und konkret`,
|
||||
memory: `# Event-Scout Einstellungen
|
||||
|
||||
(Hier kannst du festhalten welche Art von Events dich besonders interessiert,
|
||||
welche du lieber nicht vorgeschlagen bekommst, bevorzugte Wochentage etc.)
|
||||
`,
|
||||
policy: EVENT_SCOUT_POLICY,
|
||||
maxConcurrentMissions: 1,
|
||||
},
|
||||
scene: {
|
||||
name: 'Event-Entdeckung',
|
||||
description: 'Events finden und vorschlagen',
|
||||
openApps: [
|
||||
{ appId: 'events', widthPx: 540 },
|
||||
{ appId: 'ai-missions', widthPx: 440 },
|
||||
{ appId: 'calendar', widthPx: 440 },
|
||||
],
|
||||
},
|
||||
missions: [
|
||||
{
|
||||
title: 'Events der Woche',
|
||||
objective:
|
||||
'Pruefe neue Events in meinen Regionen. Schlage die 3-5 relevantesten vor, die ich noch nicht gesehen habe. Begruende warum jedes Event fuer mich interessant sein koennte.',
|
||||
conceptMarkdown: `# Woechentlicher Event-Check
|
||||
|
||||
Der Event-Scout prueft die konfigurierten Regionen auf neue Veranstaltungen
|
||||
und schlaegt die relevantesten vor. Jeder Vorschlag erscheint als Proposal —
|
||||
du entscheidest was in deinen Kalender kommt.
|
||||
|
||||
**Voraussetzung:** Mindestens eine Region und Interessen muessen im Events-Modul
|
||||
unter dem Tab "Entdecken" eingerichtet sein.`,
|
||||
cadence: { kind: 'daily' },
|
||||
startPaused: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -13,6 +13,7 @@ import { todayTemplate } from './today';
|
|||
import { calmnessTemplate } from './calmness';
|
||||
import { fitnessTemplate } from './fitness';
|
||||
import { deepWorkTemplate } from './deep-work';
|
||||
import { eventScoutTemplate } from './event-scout';
|
||||
|
||||
export type {
|
||||
// Generalised names (T1 of workbench-templates plan):
|
||||
|
|
@ -38,6 +39,7 @@ export const ALL_TEMPLATES = [
|
|||
calmnessTemplate,
|
||||
fitnessTemplate,
|
||||
deepWorkTemplate,
|
||||
eventScoutTemplate,
|
||||
] as const;
|
||||
|
||||
export {
|
||||
|
|
@ -47,6 +49,7 @@ export {
|
|||
calmnessTemplate,
|
||||
fitnessTemplate,
|
||||
deepWorkTemplate,
|
||||
eventScoutTemplate,
|
||||
};
|
||||
|
||||
/** Lookup helper — returns the template matching the given id, or
|
||||
|
|
|
|||
|
|
@ -886,6 +886,71 @@ export const AI_TOOL_CATALOG: readonly ToolSchema[] = [
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ── Event Discovery ─────────────────────────────────────────
|
||||
{
|
||||
name: 'discover_events',
|
||||
module: 'events',
|
||||
description:
|
||||
'Sucht oeffentliche Veranstaltungen in den konfigurierten Regionen des Nutzers. Gibt Events mit Titel, Datum, Ort, Kategorie und Quelle zurueck.',
|
||||
defaultPolicy: 'auto',
|
||||
parameters: [
|
||||
{
|
||||
name: 'query',
|
||||
type: 'string',
|
||||
description: 'Optionaler Suchtext (z.B. "Jazz Konzerte")',
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
name: 'category',
|
||||
type: 'string',
|
||||
description: 'Kategorie-Filter',
|
||||
required: false,
|
||||
enum: [
|
||||
'music',
|
||||
'theater',
|
||||
'art',
|
||||
'tech',
|
||||
'sport',
|
||||
'food',
|
||||
'family',
|
||||
'nature',
|
||||
'education',
|
||||
'community',
|
||||
'nightlife',
|
||||
'market',
|
||||
'other',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'days_ahead',
|
||||
type: 'number',
|
||||
description: 'Wie viele Tage voraus suchen (Standard: 14)',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'suggest_event',
|
||||
module: 'events',
|
||||
description:
|
||||
'Schlaegt dem Nutzer ein entdecktes Event vor. Erstellt ein Proposal das der Nutzer bestaetigen muss, um das Event in seinen Kalender zu uebernehmen.',
|
||||
defaultPolicy: 'propose',
|
||||
parameters: [
|
||||
{
|
||||
name: 'discovered_event_id',
|
||||
type: 'string',
|
||||
description: 'ID des entdeckten Events',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'reason',
|
||||
type: 'string',
|
||||
description: 'Begruendung warum dieses Event relevant ist',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue