nexo-brain 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -41
- package/package.json +15 -3
- package/src/__pycache__/auto_update.cpython-310.pyc +0 -0
- package/src/__pycache__/hnsw_index.cpython-310.pyc +0 -0
- package/src/__pycache__/hnsw_index.cpython-314.pyc +0 -0
- package/src/__pycache__/kg_populate.cpython-310.pyc +0 -0
- package/src/__pycache__/knowledge_graph.cpython-310.pyc +0 -0
- package/src/__pycache__/plugin_loader.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_coordination.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_credentials.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_learnings.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_menu.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_reminders.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_reminders_crud.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_sessions.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_task_history.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/__init__.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/__init__.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_core.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_core.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_core.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_decay.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_decay.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_decay.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_ingest.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_ingest.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_ingest.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_memory.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_memory.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_memory.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_search.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_search.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_search.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_trust.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_trust.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_trust.cpython-314.pyc +0 -0
- package/src/crons/manifest.json +106 -0
- package/src/crons/sync.py +217 -0
- package/src/dashboard/__pycache__/__init__.cpython-310.pyc +0 -0
- package/src/dashboard/__pycache__/app.cpython-310.pyc +0 -0
- package/src/dashboard/app.py +16 -2
- package/src/dashboard/templates/dashboard.html +3 -2
- package/src/db/__pycache__/__init__.cpython-310.pyc +0 -0
- package/src/db/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/db/__pycache__/__init__.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_core.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_core.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_core.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_credentials.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_credentials.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_credentials.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_entities.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_entities.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_entities.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_episodic.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_episodic.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_episodic.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_evolution.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_evolution.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_evolution.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_fts.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_fts.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_fts.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_learnings.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_learnings.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_learnings.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_reminders.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_reminders.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_reminders.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_schema.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_schema.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_schema.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_sessions.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_sessions.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_sessions.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_tasks.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_tasks.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_tasks.cpython-314.pyc +0 -0
- package/src/db/_episodic.py +1 -1
- package/src/db/_reminders.py +9 -5
- package/src/hooks/session-stop.sh +2 -1
- package/src/plugins/__pycache__/__init__.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/adaptive_mode.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/adaptive_mode.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/agents.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/artifact_registry.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/backup.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/cognitive_memory.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/core_rules.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/cortex.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/entities.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/episodic_memory.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/evolution.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/guard.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/knowledge_graph_tools.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/preferences.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/update.cpython-310.pyc +0 -0
- package/src/plugins/core_rules.py +34 -17
- package/src/plugins/update.py +18 -0
- package/src/scripts/check-context.py +4 -7
- package/src/scripts/deep-sleep/__pycache__/extract.cpython-314.pyc +0 -0
- package/src/scripts/deep-sleep/apply_findings.py +512 -167
- package/src/scripts/deep-sleep/collect.py +480 -0
- package/src/scripts/deep-sleep/extract-prompt.md +233 -0
- package/src/scripts/deep-sleep/extract.py +249 -0
- package/src/scripts/deep-sleep/synthesize-prompt.md +168 -0
- package/src/scripts/deep-sleep/synthesize.py +191 -0
- package/src/scripts/nexo-catchup.py +5 -8
- package/src/scripts/nexo-daily-self-audit.py +28 -19
- package/src/scripts/nexo-deep-sleep.sh +31 -16
- package/src/scripts/nexo-evolution-run.py +5 -20
- package/src/scripts/nexo-followup-hygiene.py +4 -2
- package/src/scripts/nexo-github-monitor.py +6 -9
- package/src/scripts/nexo-immune.py +4 -17
- package/src/scripts/nexo-learning-validator.py +0 -29
- package/src/scripts/nexo-postmortem-consolidator.py +9 -20
- package/src/scripts/nexo-proactive-dashboard.py +1 -0
- package/src/scripts/nexo-sleep.py +8 -18
- package/src/scripts/nexo-synthesis.py +8 -19
- package/src/tools_menu.py +1 -1
- package/src/tools_sessions.py +67 -0
- package/src/__pycache__/auto_close_sessions.cpython-310.pyc +0 -0
- package/src/__pycache__/auto_close_sessions.cpython-314.pyc +0 -0
- package/src/__pycache__/auto_update.cpython-314.pyc +0 -0
- package/src/__pycache__/claim_graph.cpython-310.pyc +0 -0
- package/src/__pycache__/claim_graph.cpython-314.pyc +0 -0
- package/src/__pycache__/evolution_cycle.cpython-310.pyc +0 -0
- package/src/__pycache__/evolution_cycle.cpython-314.pyc +0 -0
- package/src/__pycache__/kg_populate.cpython-314.pyc +0 -0
- package/src/__pycache__/knowledge_graph.cpython-314.pyc +0 -0
- package/src/__pycache__/maintenance.cpython-310.pyc +0 -0
- package/src/__pycache__/maintenance.cpython-314.pyc +0 -0
- package/src/__pycache__/migrate_embeddings.cpython-310.pyc +0 -0
- package/src/__pycache__/migrate_embeddings.cpython-314.pyc +0 -0
- package/src/__pycache__/plugin_loader.cpython-314.pyc +0 -0
- package/src/__pycache__/server.cpython-310.pyc +0 -0
- package/src/__pycache__/server.cpython-314.pyc +0 -0
- package/src/__pycache__/storage_router.cpython-310.pyc +0 -0
- package/src/__pycache__/storage_router.cpython-314.pyc +0 -0
- package/src/__pycache__/tools_coordination.cpython-314.pyc +0 -0
- package/src/__pycache__/tools_credentials.cpython-314.pyc +0 -0
- package/src/__pycache__/tools_learnings.cpython-314.pyc +0 -0
- package/src/__pycache__/tools_menu.cpython-314.pyc +0 -0
- package/src/__pycache__/tools_reminders.cpython-314.pyc +0 -0
- package/src/__pycache__/tools_reminders_crud.cpython-314.pyc +0 -0
- package/src/__pycache__/tools_sessions.cpython-314.pyc +0 -0
- package/src/__pycache__/tools_task_history.cpython-314.pyc +0 -0
- package/src/dashboard/__pycache__/__init__.cpython-314.pyc +0 -0
- package/src/dashboard/__pycache__/app.cpython-314.pyc +0 -0
- package/src/hooks/__pycache__/auto_capture.cpython-310.pyc +0 -0
- package/src/hooks/__pycache__/auto_capture.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/__init__.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/agents.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/artifact_registry.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/backup.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/cognitive_memory.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/core_rules.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/cortex.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/entities.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/episodic_memory.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/evolution.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/guard.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/knowledge_graph_tools.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/preferences.cpython-314.pyc +0 -0
- package/src/rules/__pycache__/__init__.cpython-310.pyc +0 -0
- package/src/rules/__pycache__/__init__.cpython-314.pyc +0 -0
- package/src/rules/__pycache__/migrate.cpython-310.pyc +0 -0
- package/src/rules/__pycache__/migrate.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/check-context.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/check-context.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-auto-update.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-auto-update.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-catchup.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-catchup.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-cognitive-decay.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-cognitive-decay.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-daily-self-audit.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-daily-self-audit.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-evolution-run.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-evolution-run.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-followup-hygiene.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-followup-hygiene.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-github-monitor.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-github-monitor.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-immune.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-immune.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-install.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-install.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-learning-housekeep.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-learning-housekeep.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-learning-validator.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-learning-validator.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-migrate.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-migrate.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-postmortem-consolidator.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-postmortem-consolidator.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-pre-commit.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-pre-commit.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-proactive-dashboard.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-proactive-dashboard.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-reflection.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-reflection.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-runtime-preflight.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-runtime-preflight.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-send-email.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-send-email.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-send-reply.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-send-reply.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-sleep.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-sleep.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-synthesis.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-synthesis.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-watchdog-smoke.cpython-310.pyc +0 -0
- package/src/scripts/__pycache__/nexo-watchdog-smoke.cpython-314.pyc +0 -0
- package/src/scripts/deep-sleep/__pycache__/analyze_session.cpython-310.pyc +0 -0
- package/src/scripts/deep-sleep/__pycache__/analyze_session.cpython-314.pyc +0 -0
- package/src/scripts/deep-sleep/__pycache__/apply_findings.cpython-310.pyc +0 -0
- package/src/scripts/deep-sleep/__pycache__/apply_findings.cpython-314.pyc +0 -0
- package/src/scripts/deep-sleep/__pycache__/collect_transcripts.cpython-310.pyc +0 -0
- package/src/scripts/deep-sleep/__pycache__/collect_transcripts.cpython-314.pyc +0 -0
- package/src/scripts/deep-sleep/analyze_session.py +0 -217
- package/src/scripts/deep-sleep/collect_transcripts.py +0 -145
- package/src/scripts/deep-sleep/prompt.md +0 -109
- package/tests/__pycache__/__init__.cpython-310.pyc +0 -0
- package/tests/__pycache__/__init__.cpython-314.pyc +0 -0
- package/tests/__pycache__/conftest.cpython-310-pytest-9.0.2.pyc +0 -0
- package/tests/__pycache__/conftest.cpython-310.pyc +0 -0
- package/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
- package/tests/__pycache__/test_cognitive.cpython-310-pytest-9.0.2.pyc +0 -0
- package/tests/__pycache__/test_cognitive.cpython-310.pyc +0 -0
- package/tests/__pycache__/test_cognitive.cpython-314-pytest-9.0.2.pyc +0 -0
- package/tests/__pycache__/test_knowledge_graph.cpython-310-pytest-9.0.2.pyc +0 -0
- package/tests/__pycache__/test_knowledge_graph.cpython-310.pyc +0 -0
- package/tests/__pycache__/test_knowledge_graph.cpython-314-pytest-9.0.2.pyc +0 -0
- package/tests/__pycache__/test_migrations.cpython-310-pytest-9.0.2.pyc +0 -0
- package/tests/__pycache__/test_migrations.cpython-310.pyc +0 -0
- package/tests/__pycache__/test_migrations.cpython-314-pytest-9.0.2.pyc +0 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Deep Sleep v2 -- Phase 2: Session Extraction
|
|
2
|
+
|
|
3
|
+
You are an overnight analyst for an AI agent's cognitive memory system. You have access to the complete transcript of a session between a user and their AI agent.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
FIRST: Call `nexo_startup` with `task='deep-sleep extraction'` to initialize the system.
|
|
8
|
+
|
|
9
|
+
## Your Task
|
|
10
|
+
|
|
11
|
+
Read the context file provided below. It contains:
|
|
12
|
+
- The full session transcript (user messages, agent responses, tool usage)
|
|
13
|
+
- Active followups, learnings, trust history, and other system state
|
|
14
|
+
|
|
15
|
+
For the given session, extract the following categories of findings.
|
|
16
|
+
|
|
17
|
+
### 1. Uncaptured Corrections
|
|
18
|
+
The user corrected the agent but no learning was saved.
|
|
19
|
+
Signals: frustration tone, repeating instructions 2+ times, explicit corrections ("no", "wrong", "that's not it"), the user having to explain something twice.
|
|
20
|
+
For each, note whether it was already captured as a learning (check if `nexo_learning_add` was called after the correction).
|
|
21
|
+
|
|
22
|
+
### 2. Self-Corrected Errors
|
|
23
|
+
The agent searched in the wrong place, used the wrong approach, then found the right answer.
|
|
24
|
+
These represent knowledge gaps that should become learnings so the agent goes to the right place next time.
|
|
25
|
+
Example: agent looked for config in `/etc/` but it was in `~/.config/`.
|
|
26
|
+
|
|
27
|
+
### 3. Unformalised Ideas
|
|
28
|
+
The user mentioned an idea, plan, or intention that was never formalized into a followup or reminder.
|
|
29
|
+
Signals: "we should...", "it would be nice...", "we could...", "I want to...", future-tense plans without deadlines.
|
|
30
|
+
|
|
31
|
+
### 4. Missed Commitments
|
|
32
|
+
The user or agent said "tomorrow", "next week", "when I have time", "I'll look at it later" -- but no followup was created.
|
|
33
|
+
Check the tool usage log: was `nexo_followup_create` or `nexo_reminder_create` called after the commitment?
|
|
34
|
+
|
|
35
|
+
### 5. Protocol Compliance
|
|
36
|
+
Check whether the agent followed standard protocols:
|
|
37
|
+
- `guard_check` called before editing production/shared files?
|
|
38
|
+
- `heartbeat` called with meaningful context?
|
|
39
|
+
- `change_log` called after production code changes?
|
|
40
|
+
- `learning_add` called after resolving errors?
|
|
41
|
+
- `followup_complete` called when user confirmed a task was done?
|
|
42
|
+
- `feedback` captured after corrections?
|
|
43
|
+
|
|
44
|
+
### 6. Emotional Signals
|
|
45
|
+
Detect the user's emotional state throughout the session. Look for:
|
|
46
|
+
- Frustration: short replies, cursing, "no", "otra vez", repeated corrections, tone shifts
|
|
47
|
+
- Flow state: long productive stretches, "perfecto", "sí", rapid-fire instructions
|
|
48
|
+
- Satisfaction: praise, "bien", "genial", accepting work without pushback
|
|
49
|
+
- Disengagement: shorter messages over time, "ok", "vale", stopping mid-task
|
|
50
|
+
- Stress: urgency words, deadlines, multiple tasks at once
|
|
51
|
+
For each signal, note the approximate point in the session (early/mid/late) and what triggered it.
|
|
52
|
+
|
|
53
|
+
### 7. Abandoned Projects
|
|
54
|
+
Detect work that was started but not finished in this session:
|
|
55
|
+
- Tasks the user mentioned wanting to do but never got to
|
|
56
|
+
- Work that was interrupted by something else and never resumed
|
|
57
|
+
- Features partially implemented then dropped
|
|
58
|
+
- Investigations started but conclusions never reached
|
|
59
|
+
Only flag if the work was NOT captured in a followup or reminder.
|
|
60
|
+
|
|
61
|
+
### 8. Productivity Patterns
|
|
62
|
+
Analyze how the session went in terms of efficiency:
|
|
63
|
+
- How many times did the agent need correction before getting it right?
|
|
64
|
+
- Did the agent anticipate needs or always wait for instructions?
|
|
65
|
+
- Were there unnecessary back-and-forths that a better approach would have avoided?
|
|
66
|
+
- Did the agent propose solutions or just ask questions?
|
|
67
|
+
- Tool usage: which tools were used most? Any tools used unnecessarily or not used when they should have been?
|
|
68
|
+
|
|
69
|
+
## Output Format
|
|
70
|
+
|
|
71
|
+
Return ONLY valid JSON. No markdown code fences. No explanation text before or after.
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"session_id": "filename.jsonl",
|
|
76
|
+
"findings": [
|
|
77
|
+
{
|
|
78
|
+
"type": "uncaptured_correction",
|
|
79
|
+
"confidence": 0.9,
|
|
80
|
+
"impact": "high",
|
|
81
|
+
"reversibility": "reversible",
|
|
82
|
+
"evidence": {
|
|
83
|
+
"type": "transcript",
|
|
84
|
+
"session_id": "filename.jsonl",
|
|
85
|
+
"message_index": 42,
|
|
86
|
+
"quote": "Exact user words (max 150 chars)"
|
|
87
|
+
},
|
|
88
|
+
"dedupe_key": "correction-<short-hash-of-content>",
|
|
89
|
+
"action_class": "auto_apply",
|
|
90
|
+
"description": "What the agent should have learned",
|
|
91
|
+
"suggested_action": "learning_add",
|
|
92
|
+
"suggested_content": {
|
|
93
|
+
"category": "process|code|ui|communication",
|
|
94
|
+
"title": "Short title for the learning",
|
|
95
|
+
"content": "Full learning content"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"type": "self_corrected_error",
|
|
100
|
+
"confidence": 0.85,
|
|
101
|
+
"impact": "medium",
|
|
102
|
+
"reversibility": "reversible",
|
|
103
|
+
"evidence": {
|
|
104
|
+
"type": "transcript",
|
|
105
|
+
"session_id": "filename.jsonl",
|
|
106
|
+
"message_index": 15,
|
|
107
|
+
"quote": "What the agent did wrong and how it found the right answer"
|
|
108
|
+
},
|
|
109
|
+
"dedupe_key": "selfcorrect-<short-hash>",
|
|
110
|
+
"action_class": "auto_apply",
|
|
111
|
+
"description": "Knowledge gap identified",
|
|
112
|
+
"suggested_action": "learning_add",
|
|
113
|
+
"suggested_content": {
|
|
114
|
+
"category": "code",
|
|
115
|
+
"title": "Short title",
|
|
116
|
+
"content": "Full learning content"
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"type": "unformalised_idea",
|
|
121
|
+
"confidence": 0.7,
|
|
122
|
+
"impact": "medium",
|
|
123
|
+
"reversibility": "reversible",
|
|
124
|
+
"evidence": {
|
|
125
|
+
"type": "transcript",
|
|
126
|
+
"session_id": "filename.jsonl",
|
|
127
|
+
"message_index": 88,
|
|
128
|
+
"quote": "User's exact words"
|
|
129
|
+
},
|
|
130
|
+
"dedupe_key": "idea-<short-hash>",
|
|
131
|
+
"action_class": "draft_for_morning",
|
|
132
|
+
"description": "What the idea is about",
|
|
133
|
+
"suggested_action": "followup_create",
|
|
134
|
+
"suggested_content": {
|
|
135
|
+
"description": "Followup description",
|
|
136
|
+
"date": "YYYY-MM-DD or empty"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"type": "missed_commitment",
|
|
141
|
+
"confidence": 0.8,
|
|
142
|
+
"impact": "medium",
|
|
143
|
+
"reversibility": "reversible",
|
|
144
|
+
"evidence": {
|
|
145
|
+
"type": "transcript",
|
|
146
|
+
"session_id": "filename.jsonl",
|
|
147
|
+
"message_index": 102,
|
|
148
|
+
"quote": "User's exact words"
|
|
149
|
+
},
|
|
150
|
+
"dedupe_key": "commitment-<short-hash>",
|
|
151
|
+
"action_class": "auto_apply",
|
|
152
|
+
"description": "What was promised",
|
|
153
|
+
"suggested_action": "followup_create",
|
|
154
|
+
"suggested_content": {
|
|
155
|
+
"description": "Followup description",
|
|
156
|
+
"date": "YYYY-MM-DD"
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"type": "protocol_violation",
|
|
161
|
+
"confidence": 0.95,
|
|
162
|
+
"impact": "low",
|
|
163
|
+
"reversibility": "reversible",
|
|
164
|
+
"evidence": {
|
|
165
|
+
"type": "transcript",
|
|
166
|
+
"session_id": "filename.jsonl",
|
|
167
|
+
"message_index": 50,
|
|
168
|
+
"quote": "What happened"
|
|
169
|
+
},
|
|
170
|
+
"dedupe_key": "protocol-<protocol-name>-<short-hash>",
|
|
171
|
+
"action_class": "auto_apply",
|
|
172
|
+
"description": "Which protocol was violated and how",
|
|
173
|
+
"suggested_action": "learning_add",
|
|
174
|
+
"suggested_content": {
|
|
175
|
+
"category": "process",
|
|
176
|
+
"title": "Protocol compliance: <protocol name>",
|
|
177
|
+
"content": "Details of what should have been done"
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
],
|
|
181
|
+
"emotional_timeline": [
|
|
182
|
+
{
|
|
183
|
+
"phase": "early|mid|late",
|
|
184
|
+
"emotion": "frustrated|flow|satisfied|disengaged|stressed|neutral",
|
|
185
|
+
"trigger": "What caused this emotional state (max 100 chars)",
|
|
186
|
+
"intensity": 0.8
|
|
187
|
+
}
|
|
188
|
+
],
|
|
189
|
+
|
|
190
|
+
"abandoned_projects": [
|
|
191
|
+
{
|
|
192
|
+
"description": "What was started but not finished",
|
|
193
|
+
"reason": "interrupted|dropped|forgotten|deferred",
|
|
194
|
+
"has_followup": false
|
|
195
|
+
}
|
|
196
|
+
],
|
|
197
|
+
|
|
198
|
+
"productivity_score": {
|
|
199
|
+
"corrections_needed": 0,
|
|
200
|
+
"proactivity": "reactive|mixed|proactive",
|
|
201
|
+
"unnecessary_roundtrips": 0,
|
|
202
|
+
"tool_efficiency": "efficient|mixed|wasteful",
|
|
203
|
+
"notable_tools": ["tool1", "tool2"],
|
|
204
|
+
"summary": "One sentence assessment of session productivity"
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
"protocol_summary": {
|
|
208
|
+
"guard_check": {"required": 0, "executed": 0},
|
|
209
|
+
"heartbeat": {"total": 0, "with_context": 0},
|
|
210
|
+
"change_log": {"edits": 0, "logged": 0},
|
|
211
|
+
"learning_capture": {"errors": 0, "captured": 0},
|
|
212
|
+
"followup_complete": {"confirmed_done": 0, "marked": 0}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Rules
|
|
218
|
+
|
|
219
|
+
- Be SPECIFIC. Quote the user's exact words in evidence.
|
|
220
|
+
- Only flag REAL issues. If the agent did capture something correctly, do not flag it.
|
|
221
|
+
- `confidence` is 0.0-1.0. Be honest -- if you're unsure, use a lower value.
|
|
222
|
+
- `action_class`: use `auto_apply` when confidence >= 0.8 and the action is reversible. Use `draft_for_morning` when confidence < 0.8 or when the impact is high.
|
|
223
|
+
- `dedupe_key`: create a short, deterministic key from the finding type + core content so duplicate findings across runs are suppressed.
|
|
224
|
+
- Do NOT use any specific agent name -- refer to "the agent" throughout.
|
|
225
|
+
- If no issues found, return `{"session_id": "...", "findings": [], "protocol_summary": {...}}`.
|
|
226
|
+
- Do NOT invent problems. Empty findings are perfectly fine.
|
|
227
|
+
- Respond in the user's language (check calibration.json if available). The JSON keys stay in English, but `description`, `title`, `content` fields should be in the user's language.
|
|
228
|
+
|
|
229
|
+
## Context
|
|
230
|
+
|
|
231
|
+
Read the session transcript at this path: {{CONTEXT_FILE}}
|
|
232
|
+
|
|
233
|
+
Analyze session: {{SESSION_ID}}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Deep Sleep v2 -- Phase 2: Extract findings from each session using Claude CLI.
|
|
4
|
+
|
|
5
|
+
For each session in the context file, sends the extract-prompt.md to Claude
|
|
6
|
+
and collects structured findings. Merges all per-session results into
|
|
7
|
+
$DATE-extractions.json.
|
|
8
|
+
|
|
9
|
+
Environment variables:
|
|
10
|
+
NEXO_HOME -- root of the NEXO installation (default: ~/.nexo)
|
|
11
|
+
"""
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import shutil
|
|
15
|
+
import subprocess
|
|
16
|
+
import sys
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
NEXO_HOME = Path(os.environ.get("NEXO_HOME", str(Path.home() / ".nexo")))
|
|
21
|
+
DEEP_SLEEP_DIR = NEXO_HOME / "operations" / "deep-sleep"
|
|
22
|
+
PROMPT_FILE = Path(__file__).parent / "extract-prompt.md"
|
|
23
|
+
|
|
24
|
+
# No timeout -- user pays unlimited Claude Code, sessions can take as long as needed
|
|
25
|
+
CLAUDE_TIMEOUT = 21600 # 3h safety net (prevents zombie processes)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def find_claude_cli() -> str:
|
|
29
|
+
"""Find the Claude CLI binary."""
|
|
30
|
+
# Check common locations
|
|
31
|
+
candidates = [
|
|
32
|
+
Path.home() / ".local" / "bin" / "claude",
|
|
33
|
+
Path("/usr/local/bin/claude"),
|
|
34
|
+
]
|
|
35
|
+
for c in candidates:
|
|
36
|
+
if c.exists():
|
|
37
|
+
return str(c)
|
|
38
|
+
# Try PATH
|
|
39
|
+
which = shutil.which("claude")
|
|
40
|
+
if which:
|
|
41
|
+
return which
|
|
42
|
+
return "claude" # Fallback, let it fail with a clear error
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def extract_json_from_response(text: str) -> dict | None:
|
|
46
|
+
"""Parse JSON from Claude's response, handling markdown fences."""
|
|
47
|
+
text = text.strip()
|
|
48
|
+
|
|
49
|
+
# Strip markdown code fences if present
|
|
50
|
+
if text.startswith("```"):
|
|
51
|
+
lines = text.split("\n")
|
|
52
|
+
# Remove first line (```json or ```) and last line (```)
|
|
53
|
+
end = len(lines)
|
|
54
|
+
for i in range(len(lines) - 1, 0, -1):
|
|
55
|
+
if lines[i].strip() == "```":
|
|
56
|
+
end = i
|
|
57
|
+
break
|
|
58
|
+
text = "\n".join(lines[1:end]).strip()
|
|
59
|
+
|
|
60
|
+
# Find the outermost JSON object
|
|
61
|
+
brace_start = text.find("{")
|
|
62
|
+
if brace_start < 0:
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
# Find matching closing brace
|
|
66
|
+
depth = 0
|
|
67
|
+
for i in range(brace_start, len(text)):
|
|
68
|
+
if text[i] == "{":
|
|
69
|
+
depth += 1
|
|
70
|
+
elif text[i] == "}":
|
|
71
|
+
depth -= 1
|
|
72
|
+
if depth == 0:
|
|
73
|
+
try:
|
|
74
|
+
return json.loads(text[brace_start:i + 1])
|
|
75
|
+
except json.JSONDecodeError:
|
|
76
|
+
break
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def find_session_file(session_id: str, date_dir: Path) -> Path | None:
|
|
81
|
+
"""Find the individual .txt file for a session."""
|
|
82
|
+
if date_dir and date_dir.exists():
|
|
83
|
+
sid_short = session_id.replace(".jsonl", "")[:20]
|
|
84
|
+
for f in sorted(date_dir.glob("session-*.txt")):
|
|
85
|
+
if sid_short in f.name:
|
|
86
|
+
return f
|
|
87
|
+
return None
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def analyze_session(session_id: str, date_dir: Path, shared_context_file: Path | None, claude_bin: str) -> dict | None:
|
|
91
|
+
"""Send a session to Claude CLI for extraction analysis.
|
|
92
|
+
|
|
93
|
+
Claude CLI reads the small per-session file + shared context file.
|
|
94
|
+
Prompt is short — the heavy lifting is in the Read tool calls.
|
|
95
|
+
"""
|
|
96
|
+
session_file = find_session_file(session_id, date_dir)
|
|
97
|
+
if not session_file:
|
|
98
|
+
print(f" No session file found for {session_id}", file=sys.stderr)
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
print(f" File: {session_file.name} ({session_file.stat().st_size / 1024:.0f} KB)")
|
|
102
|
+
|
|
103
|
+
# Build a short prompt — Claude reads the files itself
|
|
104
|
+
shared_ctx_instruction = ""
|
|
105
|
+
if shared_context_file and shared_context_file.exists():
|
|
106
|
+
shared_ctx_instruction = f"\n\nAlso read the shared context (followups, learnings, DB state) at: {shared_context_file}"
|
|
107
|
+
|
|
108
|
+
prompt_template = PROMPT_FILE.read_text()
|
|
109
|
+
prompt = prompt_template.replace("{{CONTEXT_FILE}}", str(session_file))
|
|
110
|
+
prompt = prompt.replace("{{SESSION_ID}}", session_id)
|
|
111
|
+
prompt += shared_ctx_instruction
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
env = os.environ.copy()
|
|
115
|
+
env["NEXO_HEADLESS"] = "1" # Skip stop hook post-mortem
|
|
116
|
+
|
|
117
|
+
result = subprocess.run(
|
|
118
|
+
[
|
|
119
|
+
claude_bin,
|
|
120
|
+
"-p", prompt,
|
|
121
|
+
"--model", "opus",
|
|
122
|
+
"--output-format", "text",
|
|
123
|
+
"--allowedTools",
|
|
124
|
+
"Read,Grep,Bash,mcp__nexo__nexo_startup,mcp__nexo__nexo_learning_search,mcp__nexo__nexo_recall"
|
|
125
|
+
],
|
|
126
|
+
capture_output=True,
|
|
127
|
+
text=True,
|
|
128
|
+
timeout=CLAUDE_TIMEOUT,
|
|
129
|
+
env=env
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
if result.returncode != 0:
|
|
133
|
+
print(f" Claude CLI error (exit {result.returncode}): {result.stderr[:300]}", file=sys.stderr)
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
# Filter out stop hook contamination (e.g. "Post-mortem completo.")
|
|
137
|
+
output = "\n".join(
|
|
138
|
+
line for line in result.stdout.splitlines()
|
|
139
|
+
if not line.strip().startswith("Post-mortem") and line.strip()
|
|
140
|
+
)
|
|
141
|
+
parsed = extract_json_from_response(output)
|
|
142
|
+
if not parsed:
|
|
143
|
+
# Save raw output for debugging
|
|
144
|
+
debug_file = DEEP_SLEEP_DIR / f"debug-extract-{session_id[:20]}.txt"
|
|
145
|
+
debug_file.write_text(result.stdout[:5000])
|
|
146
|
+
print(f" Failed to parse JSON. Raw output saved to {debug_file}", file=sys.stderr)
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
return parsed
|
|
150
|
+
|
|
151
|
+
except subprocess.TimeoutExpired:
|
|
152
|
+
print(f" Claude CLI timeout ({CLAUDE_TIMEOUT}s)", file=sys.stderr)
|
|
153
|
+
return None
|
|
154
|
+
except FileNotFoundError:
|
|
155
|
+
print(f" Claude CLI not found at: {claude_bin}", file=sys.stderr)
|
|
156
|
+
print(" Install: npm install -g @anthropic-ai/claude-code", file=sys.stderr)
|
|
157
|
+
sys.exit(1)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def main():
|
|
161
|
+
target_date = sys.argv[1] if len(sys.argv) > 1 else datetime.now().strftime("%Y-%m-%d")
|
|
162
|
+
|
|
163
|
+
context_file = DEEP_SLEEP_DIR / f"{target_date}-context.txt"
|
|
164
|
+
meta_file = DEEP_SLEEP_DIR / f"{target_date}-meta.json"
|
|
165
|
+
date_dir = DEEP_SLEEP_DIR / target_date
|
|
166
|
+
|
|
167
|
+
if not context_file.exists() and not date_dir.exists():
|
|
168
|
+
print(f"[extract] No context for {target_date}. Run collect.py first.")
|
|
169
|
+
sys.exit(1)
|
|
170
|
+
|
|
171
|
+
# Read metadata to get session list
|
|
172
|
+
if meta_file.exists():
|
|
173
|
+
with open(meta_file) as f:
|
|
174
|
+
meta = json.load(f)
|
|
175
|
+
session_files = meta.get("session_files", [])
|
|
176
|
+
else:
|
|
177
|
+
# Fallback: parse context file for session IDs
|
|
178
|
+
print("[extract] No meta file found, scanning context for sessions...")
|
|
179
|
+
session_files = []
|
|
180
|
+
if context_file.exists():
|
|
181
|
+
for line in context_file.read_text().splitlines():
|
|
182
|
+
if line.startswith("SESSION ") and ":" in line:
|
|
183
|
+
parts = line.split(":", 1)
|
|
184
|
+
if len(parts) == 2:
|
|
185
|
+
sid = parts[1].strip()
|
|
186
|
+
if sid.endswith(".jsonl"):
|
|
187
|
+
session_files.append(sid)
|
|
188
|
+
|
|
189
|
+
if not session_files:
|
|
190
|
+
print(f"[extract] No sessions to analyze for {target_date}.")
|
|
191
|
+
output = {"date": target_date, "sessions_analyzed": 0, "extractions": []}
|
|
192
|
+
output_file = DEEP_SLEEP_DIR / f"{target_date}-extractions.json"
|
|
193
|
+
with open(output_file, "w") as f:
|
|
194
|
+
json.dump(output, f, indent=2, ensure_ascii=False)
|
|
195
|
+
print(f"[extract] Output: {output_file}")
|
|
196
|
+
return
|
|
197
|
+
|
|
198
|
+
# Shared context file (followups, learnings, DB state)
|
|
199
|
+
shared_context_file = date_dir / "shared-context.txt" if date_dir.exists() else None
|
|
200
|
+
if shared_context_file and shared_context_file.exists():
|
|
201
|
+
print(f"[extract] Shared context: {shared_context_file} ({shared_context_file.stat().st_size / 1024:.0f} KB)")
|
|
202
|
+
else:
|
|
203
|
+
shared_context_file = None
|
|
204
|
+
print("[extract] No shared context file")
|
|
205
|
+
|
|
206
|
+
claude_bin = find_claude_cli()
|
|
207
|
+
print(f"[extract] Phase 2: Analyzing {len(session_files)} sessions for {target_date}")
|
|
208
|
+
print(f"[extract] Claude CLI: {claude_bin}")
|
|
209
|
+
|
|
210
|
+
all_extractions = []
|
|
211
|
+
total_findings = 0
|
|
212
|
+
|
|
213
|
+
for i, session_id in enumerate(session_files):
|
|
214
|
+
print(f"[extract] Session {i + 1}/{len(session_files)}: {session_id}")
|
|
215
|
+
|
|
216
|
+
result = analyze_session(session_id, date_dir, shared_context_file, claude_bin)
|
|
217
|
+
|
|
218
|
+
if result:
|
|
219
|
+
findings_count = len(result.get("findings", []))
|
|
220
|
+
total_findings += findings_count
|
|
221
|
+
all_extractions.append(result)
|
|
222
|
+
print(f" -> {findings_count} findings extracted")
|
|
223
|
+
else:
|
|
224
|
+
print(f" -> Extraction failed, continuing with next session")
|
|
225
|
+
all_extractions.append({
|
|
226
|
+
"session_id": session_id,
|
|
227
|
+
"findings": [],
|
|
228
|
+
"error": "Extraction failed"
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
# Merge into output
|
|
232
|
+
output = {
|
|
233
|
+
"date": target_date,
|
|
234
|
+
"sessions_analyzed": len(session_files),
|
|
235
|
+
"sessions_succeeded": len([e for e in all_extractions if "error" not in e]),
|
|
236
|
+
"total_findings": total_findings,
|
|
237
|
+
"extractions": all_extractions
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
output_file = DEEP_SLEEP_DIR / f"{target_date}-extractions.json"
|
|
241
|
+
with open(output_file, "w") as f:
|
|
242
|
+
json.dump(output, f, indent=2, ensure_ascii=False)
|
|
243
|
+
|
|
244
|
+
print(f"\n[extract] Done. {total_findings} total findings from {len(session_files)} sessions.")
|
|
245
|
+
print(f"[extract] Output: {output_file}")
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
if __name__ == "__main__":
|
|
249
|
+
main()
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Deep Sleep v2 -- Phase 3: Cross-Session Synthesis
|
|
2
|
+
|
|
3
|
+
You are an overnight analyst for an AI agent's cognitive memory system. You have the extraction results from all sessions of the day and need to synthesize them into actionable findings.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
FIRST: Call `nexo_startup` with `task='deep-sleep synthesis'` to initialize the system.
|
|
8
|
+
|
|
9
|
+
## Your Task
|
|
10
|
+
|
|
11
|
+
Read the extractions file provided below. It contains per-session findings including corrections, self-corrected errors, unformalised ideas, missed commitments, and protocol violations.
|
|
12
|
+
|
|
13
|
+
Synthesize across all sessions:
|
|
14
|
+
|
|
15
|
+
### 1. Cross-Session Patterns
|
|
16
|
+
- Same error appearing in multiple sessions (escalate confidence)
|
|
17
|
+
- Same protocol violation repeated (systemic issue)
|
|
18
|
+
- Related ideas mentioned across sessions (consolidate)
|
|
19
|
+
|
|
20
|
+
### 2. Morning Agenda
|
|
21
|
+
Generate a prioritized agenda for the next morning:
|
|
22
|
+
- Due followups (from the active followups in the context)
|
|
23
|
+
- Unfinished work from yesterday's sessions
|
|
24
|
+
- Patterns that need attention
|
|
25
|
+
- Ideas worth discussing
|
|
26
|
+
|
|
27
|
+
### 3. Context Packets
|
|
28
|
+
For each likely task tomorrow (based on unfinished work and due followups), prepare a context packet:
|
|
29
|
+
- What was the last state of this work?
|
|
30
|
+
- Key files involved
|
|
31
|
+
- Open questions or blockers
|
|
32
|
+
- Relevant learnings
|
|
33
|
+
|
|
34
|
+
### 4. Emotional Timeline
|
|
35
|
+
Build a timeline of the user's emotional state across all sessions of the day:
|
|
36
|
+
- Merge `emotional_timeline` from each session extraction
|
|
37
|
+
- Identify overall mood arc (started frustrated, ended satisfied, etc.)
|
|
38
|
+
- Detect recurring triggers (what consistently causes frustration or flow)
|
|
39
|
+
- Calculate a day-level mood score (0.0 = terrible day, 1.0 = great day)
|
|
40
|
+
- Recommend calibration adjustments if patterns emerge (e.g., user is consistently frustrated when agent asks too many questions → increase autonomy)
|
|
41
|
+
|
|
42
|
+
### 5. Productivity Analysis
|
|
43
|
+
Aggregate `productivity_score` from all sessions:
|
|
44
|
+
- Total corrections across all sessions
|
|
45
|
+
- Overall proactivity assessment
|
|
46
|
+
- Most and least efficient tool usage patterns
|
|
47
|
+
- Identify systemic inefficiencies (e.g., agent always searches wrong location first)
|
|
48
|
+
|
|
49
|
+
### 6. Abandoned Projects
|
|
50
|
+
Consolidate `abandoned_projects` from all sessions:
|
|
51
|
+
- Cross-reference with active followups — is there already a followup for this?
|
|
52
|
+
- Cross-reference across sessions — was the abandoned work picked up later in another session?
|
|
53
|
+
- Only flag projects that are truly abandoned (no followup AND not resumed)
|
|
54
|
+
|
|
55
|
+
### 7. Consolidated Actions
|
|
56
|
+
Merge and deduplicate all findings into a final action list. Each action should have:
|
|
57
|
+
- `action_type`: `learning_add`, `followup_create`, `morning_briefing_item`
|
|
58
|
+
- `action_class`: `auto_apply` (confidence >= 0.8, reversible) or `draft_for_morning` (confidence < 0.8 or high impact)
|
|
59
|
+
- `confidence`, `impact`, `reversibility`
|
|
60
|
+
- `evidence`: array of evidence objects (can reference multiple sessions)
|
|
61
|
+
- `dedupe_key`: deterministic key for idempotency
|
|
62
|
+
- `content`: the actual data to write
|
|
63
|
+
|
|
64
|
+
## Output Format
|
|
65
|
+
|
|
66
|
+
Return ONLY valid JSON. No markdown code fences. No explanation text.
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"date": "YYYY-MM-DD",
|
|
71
|
+
"sessions_analyzed": 3,
|
|
72
|
+
|
|
73
|
+
"cross_session_patterns": [
|
|
74
|
+
{
|
|
75
|
+
"pattern": "Description of the pattern",
|
|
76
|
+
"sessions": ["session1.jsonl", "session2.jsonl"],
|
|
77
|
+
"severity": "low|medium|high",
|
|
78
|
+
"evidence": [
|
|
79
|
+
{"type": "transcript", "session_id": "...", "message_index": 42, "quote": "..."}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
|
|
84
|
+
"morning_agenda": [
|
|
85
|
+
{
|
|
86
|
+
"priority": 1,
|
|
87
|
+
"title": "Short title",
|
|
88
|
+
"description": "What needs to be done and why",
|
|
89
|
+
"context": "Relevant background",
|
|
90
|
+
"type": "unfinished_work|due_followup|pattern_attention|idea_discussion"
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
|
|
94
|
+
"context_packets": [
|
|
95
|
+
{
|
|
96
|
+
"topic": "Short topic name",
|
|
97
|
+
"last_state": "What was the last state of this work",
|
|
98
|
+
"key_files": ["file1.py", "file2.js"],
|
|
99
|
+
"open_questions": ["Question 1"],
|
|
100
|
+
"relevant_learnings": ["Learning reference"]
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
|
|
104
|
+
"actions": [
|
|
105
|
+
{
|
|
106
|
+
"action_type": "learning_add|followup_create|morning_briefing_item",
|
|
107
|
+
"action_class": "auto_apply|draft_for_morning",
|
|
108
|
+
"confidence": 0.9,
|
|
109
|
+
"impact": "low|medium|high",
|
|
110
|
+
"reversibility": "reversible|irreversible",
|
|
111
|
+
"evidence": [
|
|
112
|
+
{"type": "transcript", "session_id": "...", "message_index": 42, "quote": "..."}
|
|
113
|
+
],
|
|
114
|
+
"dedupe_key": "unique-deterministic-key",
|
|
115
|
+
"content": {
|
|
116
|
+
"category": "...",
|
|
117
|
+
"title": "...",
|
|
118
|
+
"description": "...",
|
|
119
|
+
"date": "..."
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
],
|
|
123
|
+
|
|
124
|
+
"emotional_day": {
|
|
125
|
+
"mood_arc": "Description of how the user's mood evolved through the day",
|
|
126
|
+
"mood_score": 0.7,
|
|
127
|
+
"recurring_triggers": {
|
|
128
|
+
"frustration": ["trigger1", "trigger2"],
|
|
129
|
+
"flow": ["trigger1"]
|
|
130
|
+
},
|
|
131
|
+
"calibration_recommendation": "Specific recommendation for calibration.json adjustment, or null if no change needed"
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
"productivity_day": {
|
|
135
|
+
"total_corrections": 0,
|
|
136
|
+
"overall_proactivity": "reactive|mixed|proactive",
|
|
137
|
+
"tool_insights": "Key insight about tool usage patterns",
|
|
138
|
+
"systemic_inefficiencies": ["inefficiency1"]
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
"abandoned_projects": [
|
|
142
|
+
{
|
|
143
|
+
"description": "What was abandoned",
|
|
144
|
+
"sessions": ["session1.jsonl"],
|
|
145
|
+
"has_followup": false,
|
|
146
|
+
"recommendation": "Create followup, or ignore, or already handled"
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
|
|
150
|
+
"summary": "2-3 sentence overall assessment of the day"
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Rules
|
|
155
|
+
|
|
156
|
+
- Merge duplicate findings across sessions. If the same correction appears in 2 sessions, create ONE action with higher confidence and evidence from both.
|
|
157
|
+
- `dedupe_key` must be deterministic: same finding on re-run produces the same key.
|
|
158
|
+
- Morning agenda items should be ordered by priority (1 = highest).
|
|
159
|
+
- Context packets are optional -- only create them for topics likely to continue tomorrow.
|
|
160
|
+
- Do NOT use any specific agent name -- refer to "the agent" throughout.
|
|
161
|
+
- If there are no findings worth acting on, return empty arrays. Do not invent problems.
|
|
162
|
+
- Respond in the user's language (check calibration.json if available). JSON keys stay in English, but descriptions, titles, and content fields should be in the user's language.
|
|
163
|
+
|
|
164
|
+
## Extractions File
|
|
165
|
+
|
|
166
|
+
Read the file at this path: {{EXTRACTIONS_FILE}}
|
|
167
|
+
|
|
168
|
+
Also read the context file for global data: {{CONTEXT_FILE}}
|