Files
documente/SKILL.md
Luca Sacchi Ricciardi 4b7a419a98 feat(api): implement notebook management CRUD endpoints
Implement Sprint 1: Notebook Management CRUD

- Add NotebookService with full CRUD operations
- Add POST /api/v1/notebooks (create notebook)
- Add GET /api/v1/notebooks (list with pagination)
- Add GET /api/v1/notebooks/{id} (get by ID)
- Add PATCH /api/v1/notebooks/{id} (partial update)
- Add DELETE /api/v1/notebooks/{id} (delete)
- Add Pydantic models for requests/responses
- Add custom exceptions (ValidationError, NotFoundError, NotebookLMError)
- Add comprehensive unit tests (31 tests, 97% coverage)
- Add API integration tests (26 tests)
- Fix router prefix duplication
- Fix JSON serialization in error responses

BREAKING CHANGE: None
2026-04-06 01:13:13 +02:00

561 lines
15 KiB
Markdown

---
name: notebooklm-agent
description: API and webhook interface for Google NotebookLM automation. Full programmatic access including audio generation, video creation, quizzes, flashcards, and all NotebookLM Studio features. Integrates with other AI agents via REST API and webhooks.
triggers:
- /notebooklm-agent
- /notebooklm
- "create.*podcast"
- "generate.*audio"
- "create.*video"
- "generate.*quiz"
- "create.*flashcard"
- "research.*notebook"
- "webhook.*notebook"
---
# NotebookLM Agent API Skill
Interfaccia agentica per Google NotebookLM tramite API REST e webhook. Automatizza la creazione di notebook, gestione fonti, generazione contenuti multi-formato (audio, video, slide, quiz, flashcard) e integrazione con altri agenti AI.
---
## Capabilities
### Operazioni Supportate
| Categoria | Operazioni |
|-----------|------------|
| **Notebook** | Creare, listare, ottenere, aggiornare, eliminare |
| **Fonti** | Aggiungere URL, PDF, YouTube, Drive, ricerca web |
| **Chat** | Interrogare fonti, storico conversazioni |
| **Generazione** | Audio (podcast), Video, Slide, Infografiche, Quiz, Flashcard, Report, Mappe mentali, Tabelle |
| **Artifacts** | Monitorare stato, scaricare in vari formati |
| **Webhook** | Registrare endpoint, ricevere notifiche eventi |
---
## Prerequisiti
### 1. Autenticazione NotebookLM
Prima di qualsiasi operazione, autenticarsi con NotebookLM:
```bash
# Login browser (prima volta)
notebooklm login
# Verifica autenticazione
notebooklm auth check
notebooklm list
```
### 2. Avvio API Server
```bash
# Avvia server API
uv run fastapi dev src/notebooklm_agent/api/main.py
# Verifica salute
http://localhost:8000/health
```
---
## Autonomy Rules
### ✅ Esegui Automaticamente (senza conferma)
| Operazione | Motivo |
|------------|--------|
| `GET /api/v1/notebooks` | Read-only |
| `GET /api/v1/notebooks/{id}` | Read-only |
| `GET /api/v1/notebooks/{id}/sources` | Read-only |
| `GET /api/v1/notebooks/{id}/chat/history` | Read-only |
| `GET /api/v1/notebooks/{id}/artifacts` | Read-only |
| `GET /api/v1/notebooks/{id}/artifacts/{id}/status` | Read-only |
| `GET /health` | Health check |
| `POST /api/v1/webhooks/{id}/test` | Test non distruttivo |
### ⚠️ Chiedi Conferma Prima
| Operazione | Motivo |
|------------|--------|
| `POST /api/v1/notebooks` | Crea risorsa |
| `DELETE /api/v1/notebooks/{id}` | Distruttivo |
| `POST /api/v1/notebooks/{id}/sources` | Aggiunge dati |
| `POST /api/v1/notebooks/{id}/generate/*` | Lungo, può fallire |
| `GET /api/v1/notebooks/{id}/artifacts/{id}/download` | Scrive filesystem |
| `POST /api/v1/webhooks` | Configura endpoint |
---
## Quick Reference API
### Notebook Operations
```bash
# Creare notebook
curl -X POST http://localhost:8000/api/v1/notebooks \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"title": "Ricerca AI", "description": "Studio sull\'intelligenza artificiale"}'
# Listare notebook
curl http://localhost:8000/api/v1/notebooks \
-H "X-API-Key: your-key"
# Ottenere notebook specifico
curl http://localhost:8000/api/v1/notebooks/{notebook_id} \
-H "X-API-Key: your-key"
```
### Source Operations
```bash
# Aggiungere URL
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/sources \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"type": "url", "url": "https://example.com/article"}'
# Aggiungere PDF
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/sources \
-H "X-API-Key: your-key" \
-H "Content-Type: multipart/form-data" \
-F "type=file" \
-F "file=@/path/to/document.pdf"
# Ricerca web
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/sources/research \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"query": "intelligenza artificiale 2026", "mode": "deep", "auto_import": true}'
```
### Chat Operations
```bash
# Inviare messaggio
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/chat \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"message": "Quali sono i punti chiave?", "include_references": true}'
# Ottenere storico
curl http://localhost:8000/api/v1/notebooks/{id}/chat/history \
-H "X-API-Key: your-key"
```
### Content Generation
```bash
# Generare podcast audio
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/generate/audio \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"instructions": "Rendi il podcast coinvolgente e accessibile",
"format": "deep-dive",
"length": "long",
"language": "it"
}'
# Generare video
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/generate/video \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"instructions": "Video esplicativo professionale",
"style": "whiteboard",
"language": "it"
}'
# Generare quiz
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/generate/quiz \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"difficulty": "medium",
"quantity": "standard"
}'
# Generare flashcards
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/generate/flashcards \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"difficulty": "hard",
"quantity": "more"
}'
# Generare slide deck
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/generate/slide-deck \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"format": "detailed",
"length": "default"
}'
# Generare infografica
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/generate/infographic \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"orientation": "portrait",
"detail": "detailed"
}'
# Generare mappa mentale (instant)
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/generate/mind-map \
-H "X-API-Key: your-key"
# Generare tabella dati
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/generate/data-table \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"description": "Confronta i diversi approcci di machine learning"
}'
```
### Artifact Management
```bash
# Listare artifacts
curl http://localhost:8000/api/v1/notebooks/{id}/artifacts \
-H "X-API-Key: your-key"
# Controllare stato
curl http://localhost:8000/api/v1/notebooks/{id}/artifacts/{artifact_id}/status \
-H "X-API-Key: your-key"
# Attendere completamento
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/artifacts/{artifact_id}/wait \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"timeout": 1200}'
# Scaricare artifact
curl http://localhost:8000/api/v1/notebooks/{id}/artifacts/{artifact_id}/download \
-H "X-API-Key: your-key" \
-o artifact.mp3
```
### Webhook Management
```bash
# Registrare webhook
curl -X POST http://localhost:8000/api/v1/webhooks \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-agent.com/webhook",
"events": ["artifact.completed", "source.ready"],
"secret": "your-webhook-secret"
}'
# Listare webhook
curl http://localhost:8000/api/v1/webhooks \
-H "X-API-Key: your-key"
# Testare webhook
curl -X POST http://localhost:8000/api/v1/webhooks/{webhook_id}/test \
-H "X-API-Key: your-key"
# Rimuovere webhook
curl -X DELETE http://localhost:8000/api/v1/webhooks/{webhook_id} \
-H "X-API-Key: your-key"
```
---
## Content Generation Options
### Audio (Podcast)
| Parametro | Valori | Default |
|-----------|--------|---------|
| `format` | `deep-dive`, `brief`, `critique`, `debate` | `deep-dive` |
| `length` | `short`, `default`, `long` | `default` |
| `language` | `en`, `it`, `es`, `fr`, `de`, ... | `en` |
### Video
| Parametro | Valori | Default |
|-----------|--------|---------|
| `format` | `explainer`, `brief` | `explainer` |
| `style` | `auto`, `classic`, `whiteboard`, `kawaii`, `anime`, `watercolor`, `retro-print`, `heritage`, `paper-craft` | `auto` |
| `language` | Codice lingua | `en` |
### Slide Deck
| Parametro | Valori | Default |
|-----------|--------|---------|
| `format` | `detailed`, `presenter` | `detailed` |
| `length` | `default`, `short` | `default` |
### Infographic
| Parametro | Valori | Default |
|-----------|--------|---------|
| `orientation` | `landscape`, `portrait`, `square` | `landscape` |
| `detail` | `concise`, `standard`, `detailed` | `standard` |
| `style` | `auto`, `sketch-note`, `professional`, `bento-grid`, `editorial`, `instructional`, `bricks`, `clay`, `anime`, `kawaii`, `scientific` | `auto` |
### Quiz / Flashcards
| Parametro | Valori | Default |
|-----------|--------|---------|
| `difficulty` | `easy`, `medium`, `hard` | `medium` |
| `quantity` | `fewer`, `standard`, `more` | `standard` |
---
## Workflow Comuni
### Workflow 1: Research to Podcast
```bash
# 1. Creare notebook
NOTEBOOK=$(curl -s -X POST http://localhost:8000/api/v1/notebooks \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"title": "AI Research"}' | jq -r '.data.id')
# 2. Aggiungere fonti
curl -X POST http://localhost:8000/api/v1/notebooks/$NOTEBOOK/sources \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"type": "url", "url": "https://example.com/ai-article"}'
# 3. Ricerca web (opzionale)
curl -X POST http://localhost:8000/api/v1/notebooks/$NOTEBOOK/sources/research \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"query": "latest AI trends 2026", "mode": "deep", "auto_import": true}'
# 4. Generare podcast
ARTIFACT=$(curl -s -X POST http://localhost:8000/api/v1/notebooks/$NOTEBOOK/generate/audio \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"instructions": "Make it engaging", "format": "deep-dive", "length": "long"}' | jq -r '.data.artifact_id')
# 5. Attendere completamento
curl -X POST http://localhost:8000/api/v1/notebooks/$NOTEBOOK/artifacts/$ARTIFACT/wait \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"timeout": 1200}'
# 6. Scaricare
curl http://localhost:8000/api/v1/notebooks/$NOTEBOOK/artifacts/$ARTIFACT/download \
-H "X-API-Key: your-key" \
-o podcast.mp3
```
### Workflow 2: Document Analysis
```bash
# Creare notebook e caricare PDF
NOTEBOOK=$(curl -s -X POST http://localhost:8000/api/v1/notebooks \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"title": "Document Analysis"}' | jq -r '.data.id')
curl -X POST http://localhost:8000/api/v1/notebooks/$NOTEBOOK/sources \
-H "X-API-Key: your-key" \
-F "type=file" \
-F "file=@document.pdf"
# Interrogare contenuto
curl -X POST http://localhost:8000/api/v1/notebooks/$NOTEBOOK/chat \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"message": "Summarize the key points"}'
# Generare quiz
curl -X POST http://localhost:8000/api/v1/notebooks/$NOTEBOOK/generate/quiz \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"difficulty": "medium"}'
```
### Workflow 3: Webhook Integration
```bash
# 1. Registrare webhook per ricevere notifiche
curl -X POST http://localhost:8000/api/v1/webhooks \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://my-agent.com/notebooklm-webhook",
"events": ["artifact.completed", "artifact.failed", "source.ready"],
"secret": "secure-webhook-secret"
}'
# 2. Avviare generazione lunga
curl -X POST http://localhost:8000/api/v1/notebooks/{id}/generate/audio \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"instructions": "Create engaging podcast"}'
# 3. Il webhook riceverà:
# {
# "event": "artifact.completed",
# "timestamp": "2026-04-05T10:30:00Z",
# "data": {
# "notebook_id": "...",
# "artifact_id": "...",
# "type": "audio",
# "download_url": "..."
# }
# }
```
---
## Response Formats
### Success Response
```json
{
"success": true,
"data": {
"id": "abc123...",
"title": "My Notebook",
"created_at": "2026-04-05T10:30:00Z"
},
"meta": {
"timestamp": "2026-04-05T10:30:00Z",
"request_id": "req-uuid"
}
}
```
### Error Response
```json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid notebook title",
"details": [
{"field": "title", "error": "Title must be at least 3 characters"}
]
},
"meta": {
"timestamp": "2026-04-05T10:30:00Z",
"request_id": "req-uuid"
}
}
```
---
## Webhook Events
### Event Types
| Evento | Descrizione | Payload |
|--------|-------------|---------|
| `notebook.created` | Nuovo notebook creato | `{notebook_id, title}` |
| `source.added` | Nuova fonte aggiunta | `{notebook_id, source_id, type}` |
| `source.ready` | Fonte indicizzata | `{notebook_id, source_id, title}` |
| `source.error` | Errore indicizzazione | `{notebook_id, source_id, error}` |
| `artifact.pending` | Generazione avviata | `{notebook_id, artifact_id, type}` |
| `artifact.completed` | Generazione completata | `{notebook_id, artifact_id, type}` |
| `artifact.failed` | Generazione fallita | `{notebook_id, artifact_id, error}` |
| `research.completed` | Ricerca completata | `{notebook_id, sources_count}` |
### Webhook Security
Gli webhook includono header `X-Webhook-Signature` con HMAC-SHA256:
```python
import hmac
import hashlib
signature = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
# Verificare: signature == request.headers['X-Webhook-Signature']
```
---
## Error Handling
### Error Codes
| Codice | Descrizione | Azione |
|--------|-------------|--------|
| `AUTH_ERROR` | Autenticazione fallita | Verificare API key |
| `NOTEBOOKLM_AUTH_ERROR` | Sessione NotebookLM scaduta | Eseguire `notebooklm login` |
| `VALIDATION_ERROR` | Dati input non validi | Correggere payload |
| `NOT_FOUND` | Risorsa non trovata | Verificare ID |
| `RATE_LIMITED` | Rate limit NotebookLM | Attendere e riprovare |
| `GENERATION_FAILED` | Generazione fallita | Verificare fonti, riprovare |
| `TIMEOUT` | Operazione timeout | Estendere timeout, riprovare |
### Retry Strategy
Per operazioni che falliscono con `RATE_LIMITED`:
- Attendere 5-10 minuti
- Riprovare con exponential backoff
- Massimo 3 retry
---
## Timing Guide
| Operazione | Tempo Tipico | Timeout Consigliato |
|------------|--------------|---------------------|
| Creazione notebook | <1s | 30s |
| Aggiunta fonte URL | 10-60s | 120s |
| Aggiunta PDF | 30s-10min | 600s |
| Ricerca web (fast) | 30s-2min | 180s |
| Ricerca web (deep) | 15-30min | 1800s |
| Generazione quiz | 5-15min | 900s |
| Generazione audio | 10-20min | 1200s |
| Generazione video | 15-45min | 2700s |
| Mind map | Istantaneo | n/a |
---
## Best Practices
1. **Usa webhook per operazioni lunghe** - Non bloccare l'agente in polling
2. **Gestisci rate limits** - NotebookLM ha limiti aggressivi
3. **Verifica firma webhook** - Sicurezza endpoint
4. **Usa UUID completi** in automazione - Evita ambiguità
5. **Isola contesti per agenti paralleli** - Usa profile o NOTEBOOKLM_HOME
---
## Troubleshooting
```bash
# Verifica stato API
curl http://localhost:8000/health
# Verifica autenticazione NotebookLM
notebooklm auth check --test
# Log dettagliati
LOG_LEVEL=DEBUG uv run fastapi dev src/notebooklm_agent/api/main.py
# Lista notebook per verificare
curl http://localhost:8000/api/v1/notebooks -H "X-API-Key: your-key"
```
---
**Skill Version:** 1.0.0
**API Version:** v1
**Last Updated:** 2026-04-05