sensorium-mcp 3.0.103 → 3.1.0-refactor.1
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 +25 -0
- package/dist/config/agent-settings.d.ts +69 -0
- package/dist/config/agent-settings.d.ts.map +1 -0
- package/dist/config/agent-settings.js +225 -0
- package/dist/config/agent-settings.js.map +1 -0
- package/dist/config/agent-templates.d.ts +39 -0
- package/dist/config/agent-templates.d.ts.map +1 -0
- package/dist/config/agent-templates.js +105 -0
- package/dist/config/agent-templates.js.map +1 -0
- package/dist/config/index.d.ts +16 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +58 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/keep-alive-settings.d.ts +29 -0
- package/dist/config/keep-alive-settings.d.ts.map +1 -0
- package/dist/config/keep-alive-settings.js +100 -0
- package/dist/config/keep-alive-settings.js.map +1 -0
- package/dist/config/mcp-settings.d.ts +59 -0
- package/dist/config/mcp-settings.d.ts.map +1 -0
- package/dist/config/mcp-settings.js +196 -0
- package/dist/config/mcp-settings.js.map +1 -0
- package/dist/config/misc-settings.d.ts +46 -0
- package/dist/config/misc-settings.d.ts.map +1 -0
- package/dist/config/misc-settings.js +146 -0
- package/dist/config/misc-settings.js.map +1 -0
- package/dist/config/settings-store.d.ts +10 -0
- package/dist/config/settings-store.d.ts.map +1 -0
- package/dist/config/settings-store.js +65 -0
- package/dist/config/settings-store.js.map +1 -0
- package/dist/dashboard/log-parser.d.ts.map +1 -1
- package/dist/dashboard/log-parser.js +12 -2
- package/dist/dashboard/log-parser.js.map +1 -1
- package/dist/dashboard/presets.d.ts +1 -1
- package/dist/dashboard/presets.d.ts.map +1 -1
- package/dist/dashboard/presets.js +1 -1
- package/dist/dashboard/presets.js.map +1 -1
- package/dist/dashboard/routes/agent-templates.d.ts.map +1 -1
- package/dist/dashboard/routes/agent-templates.js +13 -8
- package/dist/dashboard/routes/agent-templates.js.map +1 -1
- package/dist/dashboard/routes/claude.d.ts.map +1 -1
- package/dist/dashboard/routes/claude.js +6 -3
- package/dist/dashboard/routes/claude.js.map +1 -1
- package/dist/dashboard/routes/copilot.d.ts.map +1 -1
- package/dist/dashboard/routes/copilot.js +16 -7
- package/dist/dashboard/routes/copilot.js.map +1 -1
- package/dist/dashboard/routes/data.d.ts.map +1 -1
- package/dist/dashboard/routes/data.js +43 -15
- package/dist/dashboard/routes/data.js.map +1 -1
- package/dist/dashboard/routes/env-vars.d.ts.map +1 -1
- package/dist/dashboard/routes/env-vars.js.map +1 -1
- package/dist/dashboard/routes/mcp-servers.d.ts.map +1 -1
- package/dist/dashboard/routes/mcp-servers.js +11 -5
- package/dist/dashboard/routes/mcp-servers.js.map +1 -1
- package/dist/dashboard/routes/prompts.d.ts.map +1 -1
- package/dist/dashboard/routes/prompts.js +2 -2
- package/dist/dashboard/routes/prompts.js.map +1 -1
- package/dist/dashboard/routes/settings.d.ts.map +1 -1
- package/dist/dashboard/routes/settings.js +5 -3
- package/dist/dashboard/routes/settings.js.map +1 -1
- package/dist/dashboard/routes/skills.d.ts.map +1 -1
- package/dist/dashboard/routes/skills.js +4 -4
- package/dist/dashboard/routes/skills.js.map +1 -1
- package/dist/dashboard/routes/snapshots.d.ts.map +1 -1
- package/dist/dashboard/routes/snapshots.js +18 -11
- package/dist/dashboard/routes/snapshots.js.map +1 -1
- package/dist/dashboard/routes/templates.d.ts.map +1 -1
- package/dist/dashboard/routes/templates.js +6 -3
- package/dist/dashboard/routes/templates.js.map +1 -1
- package/dist/dashboard/routes/threads-create.d.ts +22 -0
- package/dist/dashboard/routes/threads-create.d.ts.map +1 -0
- package/dist/dashboard/routes/threads-create.js +225 -0
- package/dist/dashboard/routes/threads-create.js.map +1 -0
- package/dist/dashboard/routes/threads-helpers.d.ts +28 -0
- package/dist/dashboard/routes/threads-helpers.d.ts.map +1 -0
- package/dist/dashboard/routes/threads-helpers.js +138 -0
- package/dist/dashboard/routes/threads-helpers.js.map +1 -0
- package/dist/dashboard/routes/threads-read.d.ts +26 -0
- package/dist/dashboard/routes/threads-read.d.ts.map +1 -0
- package/dist/dashboard/routes/threads-read.js +118 -0
- package/dist/dashboard/routes/threads-read.js.map +1 -0
- package/dist/dashboard/routes/threads.d.ts +5 -44
- package/dist/dashboard/routes/threads.d.ts.map +1 -1
- package/dist/dashboard/routes/threads.js +40 -496
- package/dist/dashboard/routes/threads.js.map +1 -1
- package/dist/dashboard/routes/types.d.ts.map +1 -1
- package/dist/dashboard/routes/types.js.map +1 -1
- package/dist/dashboard/routes.d.ts.map +1 -1
- package/dist/dashboard/routes.js +9 -5
- package/dist/dashboard/routes.js.map +1 -1
- package/dist/data/daily-marker.d.ts.map +1 -1
- package/dist/data/daily-marker.js +1 -1
- package/dist/data/daily-marker.js.map +1 -1
- package/dist/data/file-storage.d.ts.map +1 -1
- package/dist/data/file-storage.js +40 -16
- package/dist/data/file-storage.js.map +1 -1
- package/dist/data/interfaces.d.ts +23 -2
- package/dist/data/interfaces.d.ts.map +1 -1
- package/dist/data/memory/bootstrap.d.ts +1 -1
- package/dist/data/memory/bootstrap.d.ts.map +1 -1
- package/dist/data/memory/bootstrap.js +32 -13
- package/dist/data/memory/bootstrap.js.map +1 -1
- package/dist/data/memory/consolidation.d.ts.map +1 -1
- package/dist/data/memory/consolidation.js +17 -8
- package/dist/data/memory/consolidation.js.map +1 -1
- package/dist/data/memory/db-types.d.ts +4 -0
- package/dist/data/memory/db-types.d.ts.map +1 -0
- package/dist/data/memory/db-types.js +2 -0
- package/dist/data/memory/db-types.js.map +1 -0
- package/dist/data/memory/episodes.d.ts.map +1 -1
- package/dist/data/memory/episodes.js +3 -5
- package/dist/data/memory/episodes.js.map +1 -1
- package/dist/data/memory/index.d.ts +28 -14
- package/dist/data/memory/index.d.ts.map +1 -1
- package/dist/data/memory/index.js +28 -14
- package/dist/data/memory/index.js.map +1 -1
- package/dist/data/memory/migration-runner.d.ts +1 -1
- package/dist/data/memory/migration-runner.d.ts.map +1 -1
- package/dist/data/memory/migration-runner.js +23 -15
- package/dist/data/memory/migration-runner.js.map +1 -1
- package/dist/data/memory/narrative-lint.d.ts +12 -0
- package/dist/data/memory/narrative-lint.d.ts.map +1 -0
- package/dist/data/memory/narrative-lint.js +117 -0
- package/dist/data/memory/narrative-lint.js.map +1 -0
- package/dist/data/memory/narrative-resolutions.d.ts +26 -0
- package/dist/data/memory/narrative-resolutions.d.ts.map +1 -0
- package/dist/data/memory/narrative-resolutions.js +81 -0
- package/dist/data/memory/narrative-resolutions.js.map +1 -0
- package/dist/data/memory/narrative-sources.d.ts +19 -0
- package/dist/data/memory/narrative-sources.d.ts.map +1 -0
- package/dist/data/memory/narrative-sources.js +150 -0
- package/dist/data/memory/narrative-sources.js.map +1 -0
- package/dist/data/memory/narrative-store.d.ts +11 -0
- package/dist/data/memory/narrative-store.d.ts.map +1 -0
- package/dist/data/memory/narrative-store.js +80 -0
- package/dist/data/memory/narrative-store.js.map +1 -0
- package/dist/data/memory/narrative-types.d.ts +15 -0
- package/dist/data/memory/narrative-types.d.ts.map +1 -0
- package/dist/data/memory/narrative-types.js +3 -0
- package/dist/data/memory/narrative-types.js.map +1 -0
- package/dist/data/memory/narrative.d.ts +5 -2
- package/dist/data/memory/narrative.d.ts.map +1 -1
- package/dist/data/memory/narrative.js +31 -521
- package/dist/data/memory/narrative.js.map +1 -1
- package/dist/data/memory/note-archival.d.ts +17 -0
- package/dist/data/memory/note-archival.d.ts.map +1 -0
- package/dist/data/memory/note-archival.js +48 -0
- package/dist/data/memory/note-archival.js.map +1 -0
- package/dist/data/memory/note-embeddings.d.ts +27 -0
- package/dist/data/memory/note-embeddings.d.ts.map +1 -0
- package/dist/data/memory/note-embeddings.js +98 -0
- package/dist/data/memory/note-embeddings.js.map +1 -0
- package/dist/data/memory/reflection-dedup.d.ts +17 -0
- package/dist/data/memory/reflection-dedup.d.ts.map +1 -0
- package/dist/data/memory/reflection-dedup.js +55 -0
- package/dist/data/memory/reflection-dedup.js.map +1 -0
- package/dist/data/memory/reflection-gates.d.ts +40 -0
- package/dist/data/memory/reflection-gates.d.ts.map +1 -0
- package/dist/data/memory/reflection-gates.js +220 -0
- package/dist/data/memory/reflection-gates.js.map +1 -0
- package/dist/data/memory/reflection-sources.d.ts +13 -0
- package/dist/data/memory/reflection-sources.d.ts.map +1 -0
- package/dist/data/memory/reflection-sources.js +115 -0
- package/dist/data/memory/reflection-sources.js.map +1 -0
- package/dist/data/memory/reflection.d.ts +5 -35
- package/dist/data/memory/reflection.d.ts.map +1 -1
- package/dist/data/memory/reflection.js +25 -329
- package/dist/data/memory/reflection.js.map +1 -1
- package/dist/data/memory/schema-ddl.d.ts +1 -1
- package/dist/data/memory/schema-ddl.d.ts.map +1 -1
- package/dist/data/memory/schema-ddl.js +5 -3
- package/dist/data/memory/schema-ddl.js.map +1 -1
- package/dist/data/memory/schema-guard.d.ts +1 -1
- package/dist/data/memory/schema-guard.d.ts.map +1 -1
- package/dist/data/memory/schema-guard.js +5 -4
- package/dist/data/memory/schema-guard.js.map +1 -1
- package/dist/data/memory/schema.d.ts +2 -2
- package/dist/data/memory/schema.d.ts.map +1 -1
- package/dist/data/memory/schema.js +4 -2
- package/dist/data/memory/schema.js.map +1 -1
- package/dist/data/memory/{semantic.d.ts → semantic-notes.d.ts} +6 -72
- package/dist/data/memory/semantic-notes.d.ts.map +1 -0
- package/dist/data/memory/semantic-notes.js +249 -0
- package/dist/data/memory/semantic-notes.js.map +1 -0
- package/dist/data/memory/semantic-search.d.ts +29 -0
- package/dist/data/memory/semantic-search.d.ts.map +1 -0
- package/dist/data/memory/semantic-search.js +156 -0
- package/dist/data/memory/semantic-search.js.map +1 -0
- package/dist/data/memory/synthesis.d.ts.map +1 -1
- package/dist/data/memory/synthesis.js +15 -7
- package/dist/data/memory/synthesis.js.map +1 -1
- package/dist/data/memory/thread-registry.d.ts +2 -2
- package/dist/data/memory/thread-registry.d.ts.map +1 -1
- package/dist/data/memory/thread-registry.js +74 -36
- package/dist/data/memory/thread-registry.js.map +1 -1
- package/dist/data/memory/topic-index.d.ts +20 -0
- package/dist/data/memory/topic-index.d.ts.map +1 -0
- package/dist/data/memory/topic-index.js +91 -0
- package/dist/data/memory/topic-index.js.map +1 -0
- package/dist/data/memory/topic-shift.js +1 -1
- package/dist/data/memory/topic-shift.js.map +1 -1
- package/dist/data/memory/utils.d.ts +0 -5
- package/dist/data/memory/utils.d.ts.map +1 -1
- package/dist/data/memory/utils.js +0 -94
- package/dist/data/memory/utils.js.map +1 -1
- package/dist/data/sent-message.repository.js +2 -2
- package/dist/data/sent-message.repository.js.map +1 -1
- package/dist/data/templates.js +2 -2
- package/dist/data/templates.js.map +1 -1
- package/dist/index.js +21 -19
- package/dist/index.js.map +1 -1
- package/dist/integrations/openai/chat.d.ts.map +1 -1
- package/dist/integrations/openai/chat.js +5 -5
- package/dist/integrations/openai/chat.js.map +1 -1
- package/dist/integrations/openai/speech.d.ts +1 -1
- package/dist/integrations/openai/speech.d.ts.map +1 -1
- package/dist/integrations/openai/speech.js +1 -3
- package/dist/integrations/openai/speech.js.map +1 -1
- package/dist/integrations/openai/video.d.ts.map +1 -1
- package/dist/integrations/openai/video.js +21 -10
- package/dist/integrations/openai/video.js.map +1 -1
- package/dist/integrations/openai/vision.d.ts.map +1 -1
- package/dist/integrations/openai/vision.js.map +1 -1
- package/dist/integrations/openai/voice-emotion.d.ts.map +1 -1
- package/dist/integrations/openai/voice-emotion.js +2 -2
- package/dist/integrations/openai/voice-emotion.js.map +1 -1
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/{logger.js → lib/logger.js} +77 -50
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/markdown.d.ts.map +1 -0
- package/dist/{markdown.js → lib/markdown.js} +13 -5
- package/dist/lib/markdown.js.map +1 -0
- package/dist/{types.d.ts → lib/types.d.ts} +0 -1
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/{utils.js → lib/utils.js} +29 -9
- package/dist/lib/utils.js.map +1 -0
- package/dist/llm/json.d.ts +14 -0
- package/dist/llm/json.d.ts.map +1 -0
- package/dist/llm/json.js +112 -0
- package/dist/llm/json.js.map +1 -0
- package/dist/llm/prompts/narrative.d.ts +7 -0
- package/dist/llm/prompts/narrative.d.ts.map +1 -0
- package/dist/llm/prompts/narrative.js +124 -0
- package/dist/llm/prompts/narrative.js.map +1 -0
- package/dist/llm/prompts/reflection.d.ts +6 -0
- package/dist/llm/prompts/reflection.d.ts.map +1 -0
- package/dist/llm/prompts/reflection.js +77 -0
- package/dist/llm/prompts/reflection.js.map +1 -0
- package/dist/server/factory.d.ts +2 -2
- package/dist/server/factory.d.ts.map +1 -1
- package/dist/server/factory.js +152 -73
- package/dist/server/factory.js.map +1 -1
- package/dist/{http-server.d.ts → server/http-server.d.ts} +2 -2
- package/dist/server/http-server.d.ts.map +1 -0
- package/dist/{http-server.js → server/http-server.js} +38 -17
- package/dist/server/http-server.js.map +1 -0
- package/dist/{stdio-server.d.ts → server/stdio-server.d.ts} +1 -1
- package/dist/server/stdio-server.d.ts.map +1 -0
- package/dist/{stdio-server.js → server/stdio-server.js} +25 -11
- package/dist/server/stdio-server.js.map +1 -0
- package/dist/services/agent-spawn.service.d.ts +1 -1
- package/dist/services/agent-spawn.service.d.ts.map +1 -1
- package/dist/services/agent-spawn.service.js +17 -7
- package/dist/services/agent-spawn.service.js.map +1 -1
- package/dist/services/background-runner.d.ts +2 -2
- package/dist/services/background-runner.d.ts.map +1 -1
- package/dist/services/background-runner.js +8 -3
- package/dist/services/background-runner.js.map +1 -1
- package/dist/services/claude-spawn.service.d.ts.map +1 -1
- package/dist/services/claude-spawn.service.js +61 -52
- package/dist/services/claude-spawn.service.js.map +1 -1
- package/dist/services/codex-spawn.service.d.ts.map +1 -1
- package/dist/services/codex-spawn.service.js +52 -40
- package/dist/services/codex-spawn.service.js.map +1 -1
- package/dist/services/consolidation-prompts.d.ts +26 -0
- package/dist/services/consolidation-prompts.d.ts.map +1 -0
- package/dist/services/consolidation-prompts.js +144 -0
- package/dist/services/consolidation-prompts.js.map +1 -0
- package/dist/services/consolidation.service.d.ts +1 -5
- package/dist/services/consolidation.service.d.ts.map +1 -1
- package/dist/services/consolidation.service.js +53 -322
- package/dist/services/consolidation.service.js.map +1 -1
- package/dist/services/copilot-spawn.service.d.ts.map +1 -1
- package/dist/services/copilot-spawn.service.js +47 -57
- package/dist/services/copilot-spawn.service.js.map +1 -1
- package/dist/{daily-session.d.ts → services/daily-session.d.ts} +1 -1
- package/dist/services/daily-session.d.ts.map +1 -0
- package/dist/{daily-session.js → services/daily-session.js} +15 -14
- package/dist/services/daily-session.js.map +1 -0
- package/dist/services/dispatcher/broker.d.ts +0 -6
- package/dist/services/dispatcher/broker.d.ts.map +1 -1
- package/dist/services/dispatcher/broker.js +46 -38
- package/dist/services/dispatcher/broker.js.map +1 -1
- package/dist/services/dispatcher/index.d.ts +1 -1
- package/dist/services/dispatcher/index.d.ts.map +1 -1
- package/dist/services/dispatcher/index.js +1 -1
- package/dist/services/dispatcher/index.js.map +1 -1
- package/dist/services/dispatcher/lock.d.ts.map +1 -1
- package/dist/services/dispatcher/lock.js +24 -9
- package/dist/services/dispatcher/lock.js.map +1 -1
- package/dist/services/dispatcher/poller.d.ts +1 -1
- package/dist/services/dispatcher/poller.d.ts.map +1 -1
- package/dist/services/dispatcher/poller.js +74 -49
- package/dist/services/dispatcher/poller.js.map +1 -1
- package/dist/services/drive.d.ts.map +1 -0
- package/dist/{drive.js → services/drive.js} +1 -1
- package/dist/services/drive.js.map +1 -0
- package/dist/services/intent.d.ts.map +1 -0
- package/dist/{intent.js → services/intent.js} +78 -23
- package/dist/services/intent.js.map +1 -0
- package/dist/services/keep-alive-sync.service.d.ts +11 -0
- package/dist/services/keep-alive-sync.service.d.ts.map +1 -0
- package/dist/services/keep-alive-sync.service.js +47 -0
- package/dist/services/keep-alive-sync.service.js.map +1 -0
- package/dist/services/keeper.service.d.ts +1 -1
- package/dist/services/keeper.service.d.ts.map +1 -1
- package/dist/services/keeper.service.js +31 -18
- package/dist/services/keeper.service.js.map +1 -1
- package/dist/services/maintenance-signal.js +1 -1
- package/dist/services/maintenance-signal.js.map +1 -1
- package/dist/services/mcp-config.service.d.ts.map +1 -1
- package/dist/services/mcp-config.service.js +19 -6
- package/dist/services/mcp-config.service.js.map +1 -1
- package/dist/services/memory-briefing.service.d.ts.map +1 -1
- package/dist/services/memory-briefing.service.js +13 -7
- package/dist/services/memory-briefing.service.js.map +1 -1
- package/dist/services/memory-pruning.service.d.ts +12 -0
- package/dist/services/memory-pruning.service.d.ts.map +1 -0
- package/dist/services/memory-pruning.service.js +177 -0
- package/dist/services/memory-pruning.service.js.map +1 -0
- package/dist/services/process.service.d.ts +7 -2
- package/dist/services/process.service.d.ts.map +1 -1
- package/dist/services/process.service.js +233 -103
- package/dist/services/process.service.js.map +1 -1
- package/dist/services/reconnect-snapshot.service.d.ts.map +1 -1
- package/dist/services/reconnect-snapshot.service.js +3 -3
- package/dist/services/reconnect-snapshot.service.js.map +1 -1
- package/dist/{scheduler.d.ts → services/scheduler.d.ts} +1 -23
- package/dist/services/scheduler.d.ts.map +1 -0
- package/dist/{scheduler.js → services/scheduler.js} +6 -8
- package/dist/services/scheduler.js.map +1 -0
- package/dist/services/self-update.service.d.ts +15 -5
- package/dist/services/self-update.service.d.ts.map +1 -1
- package/dist/services/self-update.service.js +85 -41
- package/dist/services/self-update.service.js.map +1 -1
- package/dist/services/spawn-common.d.ts +40 -16
- package/dist/services/spawn-common.d.ts.map +1 -1
- package/dist/services/spawn-common.js +163 -36
- package/dist/services/spawn-common.js.map +1 -1
- package/dist/{telegram.d.ts → services/telegram.d.ts} +3 -3
- package/dist/services/telegram.d.ts.map +1 -0
- package/dist/{telegram.js → services/telegram.js} +16 -8
- package/dist/services/telegram.js.map +1 -0
- package/dist/services/thread-config.service.d.ts +25 -0
- package/dist/services/thread-config.service.d.ts.map +1 -0
- package/dist/services/thread-config.service.js +73 -0
- package/dist/services/thread-config.service.js.map +1 -0
- package/dist/services/thread-health.service.d.ts.map +1 -1
- package/dist/services/thread-health.service.js +23 -9
- package/dist/services/thread-health.service.js.map +1 -1
- package/dist/services/thread-lifecycle.service.d.ts.map +1 -1
- package/dist/services/thread-lifecycle.service.js +21 -7
- package/dist/services/thread-lifecycle.service.js.map +1 -1
- package/dist/services/topic.service.d.ts.map +1 -1
- package/dist/services/topic.service.js +17 -6
- package/dist/services/topic.service.js.map +1 -1
- package/dist/services/worker-cleanup.service.d.ts +3 -2
- package/dist/services/worker-cleanup.service.d.ts.map +1 -1
- package/dist/services/worker-cleanup.service.js +31 -19
- package/dist/services/worker-cleanup.service.js.map +1 -1
- package/dist/sessions/dashboard-registry.d.ts +38 -0
- package/dist/sessions/dashboard-registry.d.ts.map +1 -0
- package/dist/sessions/dashboard-registry.js +84 -0
- package/dist/sessions/dashboard-registry.js.map +1 -0
- package/dist/{sessions.d.ts → sessions/mcp-registry.d.ts} +3 -60
- package/dist/sessions/mcp-registry.d.ts.map +1 -0
- package/dist/{sessions.js → sessions/mcp-registry.js} +5 -214
- package/dist/sessions/mcp-registry.js.map +1 -0
- package/dist/sessions/session-store.d.ts +17 -0
- package/dist/sessions/session-store.d.ts.map +1 -0
- package/dist/sessions/session-store.js +69 -0
- package/dist/sessions/session-store.js.map +1 -0
- package/dist/sessions/topic-registry.d.ts +14 -0
- package/dist/sessions/topic-registry.d.ts.map +1 -0
- package/dist/sessions/topic-registry.js +67 -0
- package/dist/sessions/topic-registry.js.map +1 -0
- package/dist/tools/definitions.d.ts +1 -9
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/defs/memory-defs.d.ts +1 -1
- package/dist/tools/defs/memory-defs.d.ts.map +1 -1
- package/dist/tools/defs/memory-defs.js +1 -1
- package/dist/tools/defs/memory-defs.js.map +1 -1
- package/dist/tools/defs/session-defs.d.ts +1 -1
- package/dist/tools/defs/session-defs.d.ts.map +1 -1
- package/dist/tools/defs/session-defs.js +3 -14
- package/dist/tools/defs/session-defs.js.map +1 -1
- package/dist/tools/defs/skill-defs.d.ts +1 -1
- package/dist/tools/defs/skill-defs.d.ts.map +1 -1
- package/dist/tools/defs/types.d.ts +11 -0
- package/dist/tools/defs/types.d.ts.map +1 -0
- package/dist/{chat-ui/src → tools/defs}/types.js.map +1 -1
- package/dist/tools/defs/utility-defs.d.ts +1 -1
- package/dist/tools/defs/utility-defs.d.ts.map +1 -1
- package/dist/tools/defs/utility-defs.js.map +1 -1
- package/dist/tools/defs/wait-defs.d.ts +1 -1
- package/dist/tools/defs/wait-defs.d.ts.map +1 -1
- package/dist/tools/delegate-tool.d.ts +2 -2
- package/dist/tools/delegate-tool.d.ts.map +1 -1
- package/dist/tools/delegate-tool.js +57 -37
- package/dist/tools/delegate-tool.js.map +1 -1
- package/dist/tools/memory-tools.d.ts +2 -2
- package/dist/tools/memory-tools.d.ts.map +1 -1
- package/dist/tools/memory-tools.js +108 -37
- package/dist/tools/memory-tools.js.map +1 -1
- package/dist/{response-builders.d.ts → tools/response-builders.d.ts} +2 -2
- package/dist/tools/response-builders.d.ts.map +1 -0
- package/dist/{response-builders.js → tools/response-builders.js} +151 -30
- package/dist/tools/response-builders.js.map +1 -0
- package/dist/tools/session-tools.d.ts +5 -14
- package/dist/tools/session-tools.d.ts.map +1 -1
- package/dist/tools/session-tools.js +17 -12
- package/dist/tools/session-tools.js.map +1 -1
- package/dist/tools/shared-agent-utils.d.ts +1 -1
- package/dist/tools/shared-agent-utils.d.ts.map +1 -1
- package/dist/tools/shared-agent-utils.js +2 -4
- package/dist/tools/shared-agent-utils.js.map +1 -1
- package/dist/tools/skill-tools.d.ts +1 -1
- package/dist/tools/skill-tools.d.ts.map +1 -1
- package/dist/tools/skill-tools.js +12 -7
- package/dist/tools/skill-tools.js.map +1 -1
- package/dist/tools/start-session-tool.d.ts +3 -3
- package/dist/tools/start-session-tool.d.ts.map +1 -1
- package/dist/tools/start-session-tool.js +35 -25
- package/dist/tools/start-session-tool.js.map +1 -1
- package/dist/tools/utility-tools.d.ts +3 -3
- package/dist/tools/utility-tools.d.ts.map +1 -1
- package/dist/tools/utility-tools.js +46 -28
- package/dist/tools/utility-tools.js.map +1 -1
- package/dist/tools/wait/auto-forward.d.ts +1 -1
- package/dist/tools/wait/auto-forward.d.ts.map +1 -1
- package/dist/tools/wait/auto-forward.js +6 -4
- package/dist/tools/wait/auto-forward.js.map +1 -1
- package/dist/tools/wait/context.d.ts +45 -0
- package/dist/tools/wait/context.d.ts.map +1 -0
- package/dist/tools/wait/context.js +5 -0
- package/dist/tools/wait/context.js.map +1 -0
- package/dist/tools/wait/drive-handler.d.ts +2 -2
- package/dist/tools/wait/drive-handler.d.ts.map +1 -1
- package/dist/tools/wait/drive-handler.js +24 -12
- package/dist/tools/wait/drive-handler.js.map +1 -1
- package/dist/tools/wait/index.d.ts +2 -1
- package/dist/tools/wait/index.d.ts.map +1 -1
- package/dist/tools/wait/index.js.map +1 -1
- package/dist/tools/wait/media-processor.d.ts +4 -4
- package/dist/tools/wait/media-processor.d.ts.map +1 -1
- package/dist/tools/wait/media-processor.js +17 -8
- package/dist/tools/wait/media-processor.js.map +1 -1
- package/dist/tools/wait/message-delivery.d.ts +5 -5
- package/dist/tools/wait/message-delivery.d.ts.map +1 -1
- package/dist/tools/wait/message-delivery.js +78 -37
- package/dist/tools/wait/message-delivery.js.map +1 -1
- package/dist/tools/wait/message-processing.d.ts +2 -2
- package/dist/tools/wait/message-processing.d.ts.map +1 -1
- package/dist/tools/wait/message-processing.js +95 -37
- package/dist/tools/wait/message-processing.js.map +1 -1
- package/dist/tools/wait/poll-loop.d.ts +2 -41
- package/dist/tools/wait/poll-loop.d.ts.map +1 -1
- package/dist/tools/wait/poll-loop.js +75 -23
- package/dist/tools/wait/poll-loop.js.map +1 -1
- package/dist/tools/wait/reaction-handler.d.ts +3 -3
- package/dist/tools/wait/reaction-handler.d.ts.map +1 -1
- package/dist/tools/wait/reaction-handler.js +6 -6
- package/dist/tools/wait/reaction-handler.js.map +1 -1
- package/dist/tools/wait/task-handler.d.ts +1 -1
- package/dist/tools/wait/task-handler.d.ts.map +1 -1
- package/dist/tools/wait/task-handler.js +5 -4
- package/dist/tools/wait/task-handler.js.map +1 -1
- package/package.json +11 -2
- package/templates/code-review.default.md +1 -1
- package/templates/fire-and-forget.default.md +1 -1
- package/templates/handoff.default.md +1 -1
- package/templates/sensorium-repair.default.md +1 -1
- package/templates/sleep.default.md +1 -1
- package/dist/chat-ui/src/main.d.ts +0 -2
- package/dist/chat-ui/src/main.d.ts.map +0 -1
- package/dist/chat-ui/src/main.js +0 -4
- package/dist/chat-ui/src/main.js.map +0 -1
- package/dist/chat-ui/src/markdown.d.ts +0 -2
- package/dist/chat-ui/src/markdown.d.ts.map +0 -1
- package/dist/chat-ui/src/markdown.js +0 -39
- package/dist/chat-ui/src/markdown.js.map +0 -1
- package/dist/chat-ui/src/mock-data.d.ts +0 -4
- package/dist/chat-ui/src/mock-data.d.ts.map +0 -1
- package/dist/chat-ui/src/mock-data.js +0 -230
- package/dist/chat-ui/src/mock-data.js.map +0 -1
- package/dist/chat-ui/src/types.d.ts +0 -47
- package/dist/chat-ui/src/types.d.ts.map +0 -1
- package/dist/chat-ui/vite.config.d.ts +0 -3
- package/dist/chat-ui/vite.config.d.ts.map +0 -1
- package/dist/chat-ui/vite.config.js +0 -14
- package/dist/chat-ui/vite.config.js.map +0 -1
- package/dist/config.d.ts +0 -228
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -841
- package/dist/config.js.map +0 -1
- package/dist/daily-session.d.ts.map +0 -1
- package/dist/daily-session.js.map +0 -1
- package/dist/dashboard.d.ts +0 -10
- package/dist/dashboard.d.ts.map +0 -1
- package/dist/dashboard.js +0 -10
- package/dist/dashboard.js.map +0 -1
- package/dist/data/memory/semantic.d.ts.map +0 -1
- package/dist/data/memory/semantic.js +0 -588
- package/dist/data/memory/semantic.js.map +0 -1
- package/dist/dispatcher.d.ts +0 -9
- package/dist/dispatcher.d.ts.map +0 -1
- package/dist/dispatcher.js +0 -9
- package/dist/dispatcher.js.map +0 -1
- package/dist/drive.d.ts.map +0 -1
- package/dist/drive.js.map +0 -1
- package/dist/http-server.d.ts.map +0 -1
- package/dist/http-server.js.map +0 -1
- package/dist/intent.d.ts.map +0 -1
- package/dist/intent.js.map +0 -1
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js.map +0 -1
- package/dist/markdown.d.ts.map +0 -1
- package/dist/markdown.js.map +0 -1
- package/dist/memory.d.ts +0 -9
- package/dist/memory.d.ts.map +0 -1
- package/dist/memory.js +0 -9
- package/dist/memory.js.map +0 -1
- package/dist/openai.d.ts +0 -13
- package/dist/openai.d.ts.map +0 -1
- package/dist/openai.js +0 -17
- package/dist/openai.js.map +0 -1
- package/dist/response-builders.d.ts.map +0 -1
- package/dist/response-builders.js.map +0 -1
- package/dist/scheduler.d.ts.map +0 -1
- package/dist/scheduler.js.map +0 -1
- package/dist/sessions.d.ts.map +0 -1
- package/dist/sessions.js.map +0 -1
- package/dist/stdio-server.d.ts.map +0 -1
- package/dist/stdio-server.js.map +0 -1
- package/dist/telegram.d.ts.map +0 -1
- package/dist/telegram.js.map +0 -1
- package/dist/tool-definitions.d.ts +0 -2
- package/dist/tool-definitions.d.ts.map +0 -1
- package/dist/tool-definitions.js +0 -2
- package/dist/tool-definitions.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js.map +0 -1
- /package/dist/{logger.d.ts → lib/logger.d.ts} +0 -0
- /package/dist/{markdown.d.ts → lib/markdown.d.ts} +0 -0
- /package/dist/{types.js → lib/types.js} +0 -0
- /package/dist/{utils.d.ts → lib/utils.d.ts} +0 -0
- /package/dist/{drive.d.ts → services/drive.d.ts} +0 -0
- /package/dist/{intent.d.ts → services/intent.d.ts} +0 -0
- /package/dist/{chat-ui/src → tools/defs}/types.js +0 -0
|
@@ -12,155 +12,18 @@
|
|
|
12
12
|
* coherent temporal awareness across long-running sessions.
|
|
13
13
|
*/
|
|
14
14
|
import { chatCompletion } from "../../integrations/openai/chat.js";
|
|
15
|
+
import { buildPrompt, buildHierarchicalPrompt } from "../../llm/prompts/narrative.js";
|
|
16
|
+
import { findFillerPhrase, findDateViolation, findLowDensitySentences, } from "./narrative-lint.js";
|
|
17
|
+
import { CHILD_RESOLUTION, INPUT_CHAR_BUDGETS, MIN_HISTORY_DAYS, NARRATIVE_MODEL, OUTPUT_TOKEN_TARGETS, enumerateChildWindows, } from "./narrative-resolutions.js";
|
|
18
|
+
import { getChildNarratives, getCurrentNarrative, getLastNarrative, isCooldownActive, } from "./narrative-store.js";
|
|
19
|
+
import { extractEpisodeText, formatChildNarrativesForLLM, formatEpisodeLine, formatEpisodesForLLM, formatNotesForLLM, getEarliestEpisodeDate, getEpisodesInPeriod, getHistorySpanDays, getNotesInPeriod, } from "./narrative-sources.js";
|
|
15
20
|
import { getThread } from "./thread-registry.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import { log } from "../../logger.js";
|
|
19
|
-
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
20
|
-
const NARRATIVE_FILLER_PHRASES = [
|
|
21
|
-
/\bsignificant progress\b/i,
|
|
22
|
-
/\bnotable improvements?\b/i,
|
|
23
|
-
/\bvarious features\b/i,
|
|
24
|
-
/\bseveral enhancements\b/i,
|
|
25
|
-
/\bsignificant (evolution|strides|developments?)\b/i,
|
|
26
|
-
/\boverall.{0,20}(positive|good|well)\b/i,
|
|
27
|
-
/\bpivotal (moments?|decisions?|turning)\b/i,
|
|
28
|
-
/\bcrucial (step|milestone|decision)\b/i,
|
|
29
|
-
/\bnotable (milestone|achievement|development)\b/i,
|
|
30
|
-
/\bsubstantial (progress|improvement)\b/i,
|
|
31
|
-
/\bremarkable (progress|growth|improvement)\b/i,
|
|
32
|
-
/\bmeaningful (progress|improvement|change)\b/i,
|
|
33
|
-
/\bas I (navigated|reflected|observed|witnessed)\b/i,
|
|
34
|
-
/\bthis (prompted|led) me to reflect\b/i,
|
|
35
|
-
/\bI (noticed|observed|witnessed) a (critical|pivotal|key)\b/i,
|
|
36
|
-
/\bmarked by a series of\b/i,
|
|
37
|
-
/\bpart of a broader effort\b/i,
|
|
38
|
-
/\bshaped the (direction|trajectory)\b/i,
|
|
39
|
-
/\bturning points? that\b/i,
|
|
40
|
-
/\bset the stage for\b/i,
|
|
41
|
-
/\bnot only .{5,40} but also\b/i,
|
|
42
|
-
/\bculminating in\b/i,
|
|
43
|
-
/\bthe focus remains on\b/i,
|
|
44
|
-
/\bdriven by a commitment\b/i,
|
|
45
|
-
/\bthis decision to\b/i,
|
|
46
|
-
/\bthe current status reflects\b/i,
|
|
47
|
-
/\bresulting in a more\b/i,
|
|
48
|
-
/\bleading to more\b/i,
|
|
49
|
-
/\baddress(ed|ing) the root causes? of\b/i,
|
|
50
|
-
/\benhancing overall\b/i,
|
|
51
|
-
/\baligning with\b/i,
|
|
52
|
-
];
|
|
53
|
-
function findFillerPhrase(text) {
|
|
54
|
-
for (const pattern of NARRATIVE_FILLER_PHRASES) {
|
|
55
|
-
const match = pattern.exec(text);
|
|
56
|
-
if (match)
|
|
57
|
-
return match[0];
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
function findDateViolation(text, periodStart, periodEnd) {
|
|
62
|
-
const startDate = new Date(periodStart);
|
|
63
|
-
const endDate = new Date(periodEnd);
|
|
64
|
-
const validYears = new Set();
|
|
65
|
-
for (let y = startDate.getFullYear(); y <= endDate.getFullYear(); y++)
|
|
66
|
-
validYears.add(y);
|
|
67
|
-
// Check standalone year references (e.g. "in 2025", "2025–2026")
|
|
68
|
-
const yearMatches = text.matchAll(/\b(20\d{2})\b/g);
|
|
69
|
-
for (const m of yearMatches) {
|
|
70
|
-
const year = parseInt(m[1], 10);
|
|
71
|
-
if (!validYears.has(year))
|
|
72
|
-
return `year ${year} outside valid range ${[...validYears].join("–")}`;
|
|
73
|
-
}
|
|
74
|
-
// Check month+year combos (e.g. "March 2026", "Apr 2025")
|
|
75
|
-
const monthNames = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"];
|
|
76
|
-
const monthPattern = /\b(Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\s+(20\d{2})\b/gi;
|
|
77
|
-
for (const m of text.matchAll(monthPattern)) {
|
|
78
|
-
const monthStr = m[1].toLowerCase().slice(0, 3);
|
|
79
|
-
const monthIdx = monthNames.findIndex((mn) => mn.startsWith(monthStr));
|
|
80
|
-
const year = parseInt(m[2], 10);
|
|
81
|
-
if (monthIdx === -1)
|
|
82
|
-
continue;
|
|
83
|
-
const refDate = new Date(year, monthIdx, 15);
|
|
84
|
-
const windowStart = new Date(startDate);
|
|
85
|
-
windowStart.setDate(windowStart.getDate() - 7);
|
|
86
|
-
const windowEnd = new Date(endDate);
|
|
87
|
-
windowEnd.setDate(windowEnd.getDate() + 7);
|
|
88
|
-
if (refDate < windowStart || refDate > windowEnd) {
|
|
89
|
-
return `"${m[0]}" falls outside the period ${periodStart.slice(0, 10)} to ${periodEnd.slice(0, 10)}`;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
function findLowDensitySentences(text) {
|
|
95
|
-
const sentences = text.split(/(?<=[.!?])\s+/).filter(s => s.length > 20);
|
|
96
|
-
if (sentences.length === 0)
|
|
97
|
-
return { count: 0, total: 0, examples: [] };
|
|
98
|
-
const identifierPattern = /\b(?:\d{4}[-/]\d{2}[-/]\d{2}|\d{1,2}:\d{2}|v\d+\.\d+|#\d+|ID\s*\d+|\d{3,}|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\w*\s+\d{1,2}|(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday))/i;
|
|
99
|
-
const quotedNamePattern = /['"][^'"]+['"]|`[^`]+`/;
|
|
100
|
-
const namedEntityPattern = /thread\s*\d+|ID\s*\d+|(?:MCP|API|LLM|GPT|SQL|WAL|CLI|SDK|PR|CI|CD)\b/i;
|
|
101
|
-
const midSentenceProperNoun = (s) => {
|
|
102
|
-
const afterFirst = s.replace(/^\S+\s+/, "");
|
|
103
|
-
return /\b[A-Z][a-z]{2,}/.test(afterFirst);
|
|
104
|
-
};
|
|
105
|
-
const hasNumber = (s) => /\d+/.test(s);
|
|
106
|
-
const lowDensity = [];
|
|
107
|
-
for (const sentence of sentences) {
|
|
108
|
-
const hasIdentifier = identifierPattern.test(sentence);
|
|
109
|
-
const hasProperNoun = midSentenceProperNoun(sentence);
|
|
110
|
-
const hasQuotedName = quotedNamePattern.test(sentence);
|
|
111
|
-
const hasEntity = namedEntityPattern.test(sentence);
|
|
112
|
-
const hasNum = hasNumber(sentence);
|
|
113
|
-
if (!hasIdentifier && !hasProperNoun && !hasQuotedName && !hasEntity && !hasNum) {
|
|
114
|
-
lowDensity.push(sentence.slice(0, 80));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return { count: lowDensity.length, total: sentences.length, examples: lowDensity.slice(0, 3) };
|
|
118
|
-
}
|
|
119
|
-
/** Cooldown per resolution before regenerating */
|
|
120
|
-
const COOLDOWNS = {
|
|
121
|
-
day: 2 * 60 * 60 * 1000, // 2 hours
|
|
122
|
-
week: 12 * 60 * 60 * 1000, // 12 hours
|
|
123
|
-
month: 24 * 60 * 60 * 1000, // 24 hours
|
|
124
|
-
quarter: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
125
|
-
half_year: 14 * 24 * 60 * 60 * 1000, // 14 days
|
|
126
|
-
};
|
|
127
|
-
/** Target output token count per resolution */
|
|
128
|
-
const OUTPUT_TOKEN_TARGETS = {
|
|
129
|
-
day: 400,
|
|
130
|
-
week: 800,
|
|
131
|
-
month: 1600,
|
|
132
|
-
quarter: 3000,
|
|
133
|
-
half_year: 4000,
|
|
134
|
-
};
|
|
135
|
-
const INPUT_CHAR_BUDGETS = {
|
|
136
|
-
day: { episodes: 30_000, notes: 10_000 },
|
|
137
|
-
week: { episodes: 50_000, notes: 15_000 },
|
|
138
|
-
month: { episodes: 60_000, notes: 20_000 },
|
|
139
|
-
quarter: { episodes: 80_000, notes: 25_000 },
|
|
140
|
-
half_year: { episodes: 100_000, notes: 30_000 },
|
|
141
|
-
};
|
|
142
|
-
const CHILD_RESOLUTION = {
|
|
143
|
-
month: "week",
|
|
144
|
-
quarter: "month",
|
|
145
|
-
half_year: "quarter",
|
|
146
|
-
};
|
|
147
|
-
/** Minimum episode-history span (days) before a resolution becomes eligible.
|
|
148
|
-
* Without this, a young thread with ≥5 episodes gets month/quarter/half_year
|
|
149
|
-
* narratives that just re-summarize the same few days under coarser labels.
|
|
150
|
-
* A resolution needs at least one full child-period of real history to mean
|
|
151
|
-
* anything, so month wants a week, quarter a month, half_year a quarter. */
|
|
152
|
-
const MIN_HISTORY_DAYS = {
|
|
153
|
-
day: 0,
|
|
154
|
-
week: 0,
|
|
155
|
-
month: 7,
|
|
156
|
-
quarter: 30,
|
|
157
|
-
half_year: 90,
|
|
158
|
-
};
|
|
159
|
-
const NARRATIVE_MODEL = process.env.NARRATIVE_MODEL || process.env.CONSOLIDATION_MODEL || "gpt-4o";
|
|
21
|
+
import { errorMessage } from "../../lib/utils.js";
|
|
22
|
+
import { log } from "../../lib/logger.js";
|
|
160
23
|
// ─── Period Calculation ──────────────────────────────────────────────────────
|
|
161
24
|
/** Max backward reach for a day narrative when catching a cross-midnight gap. */
|
|
162
25
|
const DAY_GAP_MAX_LOOKBACK_MS = 3 * 24 * 60 * 60 * 1000;
|
|
163
|
-
function getPeriodBounds(db, threadId, resolution) {
|
|
26
|
+
export function getPeriodBounds(db, threadId, resolution) {
|
|
164
27
|
const now = new Date();
|
|
165
28
|
const end = now.toISOString();
|
|
166
29
|
if (resolution === "day") {
|
|
@@ -208,289 +71,7 @@ function getPeriodBounds(db, threadId, resolution) {
|
|
|
208
71
|
const _exhaustive = resolution;
|
|
209
72
|
throw new Error(`Unhandled narrative resolution: ${_exhaustive}`);
|
|
210
73
|
}
|
|
211
|
-
|
|
212
|
-
const row = db
|
|
213
|
-
.prepare(`SELECT MIN(timestamp) as earliest FROM episodes WHERE thread_id = ?`)
|
|
214
|
-
.get(threadId);
|
|
215
|
-
return row?.earliest ?? null;
|
|
216
|
-
}
|
|
217
|
-
/** Days of episode history a thread has (earliest episode → now); 0 if none. */
|
|
218
|
-
function getHistorySpanDays(db, threadId) {
|
|
219
|
-
const earliest = getEarliestEpisodeDate(db, threadId);
|
|
220
|
-
if (!earliest)
|
|
221
|
-
return 0;
|
|
222
|
-
return (Date.now() - new Date(earliest).getTime()) / 86_400_000;
|
|
223
|
-
}
|
|
224
|
-
// ─── Source Data Collection ──────────────────────────────────────────────────
|
|
225
|
-
function getEpisodesInPeriod(db, threadId, start, end) {
|
|
226
|
-
const rows = db
|
|
227
|
-
.prepare(`SELECT * FROM episodes
|
|
228
|
-
WHERE thread_id = ? AND timestamp >= ? AND timestamp <= ?
|
|
229
|
-
ORDER BY timestamp ASC`)
|
|
230
|
-
.all(threadId, start, end);
|
|
231
|
-
// Inline light rowToEpisode to avoid circular dep
|
|
232
|
-
return rows.map((r) => ({
|
|
233
|
-
episodeId: r.episode_id,
|
|
234
|
-
sessionId: r.session_id,
|
|
235
|
-
threadId: r.thread_id,
|
|
236
|
-
timestamp: r.timestamp,
|
|
237
|
-
type: r.type,
|
|
238
|
-
modality: r.modality,
|
|
239
|
-
content: parseJsonObject(r.content),
|
|
240
|
-
topicTags: parseJsonArray(r.topic_tags),
|
|
241
|
-
importance: r.importance,
|
|
242
|
-
consolidated: r.consolidated === 1,
|
|
243
|
-
accessedCount: r.accessed_count,
|
|
244
|
-
lastAccessed: r.last_accessed,
|
|
245
|
-
createdAt: r.created_at,
|
|
246
|
-
}));
|
|
247
|
-
}
|
|
248
|
-
function getNotesInPeriod(db, threadId, start) {
|
|
249
|
-
const rows = db
|
|
250
|
-
.prepare(`SELECT * FROM semantic_notes
|
|
251
|
-
WHERE thread_id = ? AND valid_to IS NULL AND created_at >= ?
|
|
252
|
-
ORDER BY access_count DESC LIMIT 30`)
|
|
253
|
-
.all(threadId, start);
|
|
254
|
-
return rows.map((r) => ({
|
|
255
|
-
noteId: r.note_id,
|
|
256
|
-
type: r.type,
|
|
257
|
-
content: r.content,
|
|
258
|
-
keywords: parseJsonArray(r.keywords),
|
|
259
|
-
confidence: r.confidence,
|
|
260
|
-
sourceEpisodes: parseJsonArray(r.source_episodes),
|
|
261
|
-
linkedNotes: parseJsonArray(r.linked_notes),
|
|
262
|
-
linkReasons: parseJsonObject(r.link_reasons),
|
|
263
|
-
validFrom: r.valid_from,
|
|
264
|
-
validTo: r.valid_to,
|
|
265
|
-
supersededBy: r.superseded_by,
|
|
266
|
-
accessCount: r.access_count,
|
|
267
|
-
lastAccessed: r.last_accessed,
|
|
268
|
-
createdAt: r.created_at,
|
|
269
|
-
updatedAt: r.updated_at,
|
|
270
|
-
priority: r.priority ?? 0,
|
|
271
|
-
threadId: r.thread_id,
|
|
272
|
-
isGuardrail: r.is_guardrail === 1,
|
|
273
|
-
pinned: r.pinned === 1,
|
|
274
|
-
qualityScore: r.quality_score ?? null,
|
|
275
|
-
}));
|
|
276
|
-
}
|
|
277
|
-
// ─── Child Narrative Retrieval ──────────────────────────────────────────────
|
|
278
|
-
function getChildNarratives(db, threadId, resolution, start, end) {
|
|
279
|
-
const child = CHILD_RESOLUTION[resolution];
|
|
280
|
-
if (!child)
|
|
281
|
-
return [];
|
|
282
|
-
const rows = db
|
|
283
|
-
.prepare(`SELECT * FROM temporal_narratives
|
|
284
|
-
WHERE thread_id = ? AND resolution = ? AND period_start >= ? AND period_start <= ?
|
|
285
|
-
ORDER BY period_start ASC`)
|
|
286
|
-
.all(threadId, child, start, end);
|
|
287
|
-
return rows.map((r) => ({
|
|
288
|
-
id: r.id,
|
|
289
|
-
threadId: r.thread_id,
|
|
290
|
-
resolution: r.resolution,
|
|
291
|
-
periodStart: r.period_start,
|
|
292
|
-
periodEnd: r.period_end,
|
|
293
|
-
narrative: r.narrative,
|
|
294
|
-
sourceEpisodeCount: r.source_episode_count,
|
|
295
|
-
sourceNoteCount: r.source_note_count,
|
|
296
|
-
model: r.model,
|
|
297
|
-
createdAt: r.created_at,
|
|
298
|
-
}));
|
|
299
|
-
}
|
|
300
|
-
function formatChildNarrativesForLLM(narratives) {
|
|
301
|
-
return narratives
|
|
302
|
-
.map((n) => {
|
|
303
|
-
const fmtDate = (d) => new Date(d).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
|
|
304
|
-
return `--- ${n.resolution} narrative (${fmtDate(n.periodStart)} – ${fmtDate(n.periodEnd)}, ${n.sourceEpisodeCount} episodes) ---\n${n.narrative}`;
|
|
305
|
-
})
|
|
306
|
-
.join("\n\n");
|
|
307
|
-
}
|
|
308
|
-
// ─── Content Extraction ──────────────────────────────────────────────────────
|
|
309
|
-
function extractEpisodeText(ep) {
|
|
310
|
-
const content = ep.content;
|
|
311
|
-
const text = (content.text || content.raw || content.caption || content.message || "");
|
|
312
|
-
return text.slice(0, 1500);
|
|
313
|
-
}
|
|
314
|
-
function formatEpisodeLine(ep, text) {
|
|
315
|
-
const ts = ep.timestamp.slice(0, 16).replace("T", " ");
|
|
316
|
-
const imp = ep.importance != null && ep.importance !== 0.5 ? ` [imp: ${ep.importance.toFixed(1)}]` : "";
|
|
317
|
-
const tags = ep.topicTags.length > 0 ? ` [tags: ${ep.topicTags.join(", ")}]` : "";
|
|
318
|
-
return `[${ts}] (${ep.type}/${ep.modality})${imp}${tags} ${text}`;
|
|
319
|
-
}
|
|
320
|
-
function formatEpisodesForLLM(episodes, maxChars) {
|
|
321
|
-
const importanceBudget = Math.round(maxChars * 0.3);
|
|
322
|
-
// Pool 1: top episodes by importance (guaranteed inclusion)
|
|
323
|
-
const byImportance = [...episodes].sort((a, b) => (b.importance ?? 0.5) - (a.importance ?? 0.5));
|
|
324
|
-
const selected = new Set();
|
|
325
|
-
const pool1 = [];
|
|
326
|
-
let pool1Chars = 0;
|
|
327
|
-
for (const ep of byImportance) {
|
|
328
|
-
const text = extractEpisodeText(ep);
|
|
329
|
-
if (!text.trim())
|
|
330
|
-
continue;
|
|
331
|
-
const line = formatEpisodeLine(ep, text);
|
|
332
|
-
if (pool1Chars + line.length > importanceBudget)
|
|
333
|
-
break;
|
|
334
|
-
pool1.push({ ep, line });
|
|
335
|
-
selected.add(ep.episodeId);
|
|
336
|
-
pool1Chars += line.length;
|
|
337
|
-
}
|
|
338
|
-
// Pool 2: chronological fill (remaining budget)
|
|
339
|
-
const remainingBudget = maxChars - pool1Chars;
|
|
340
|
-
const chronological = [...episodes]
|
|
341
|
-
.filter(ep => !selected.has(ep.episodeId))
|
|
342
|
-
.sort((a, b) => (a.timestamp < b.timestamp ? -1 : 1));
|
|
343
|
-
const pool2 = [];
|
|
344
|
-
let pool2Chars = 0;
|
|
345
|
-
for (const ep of chronological) {
|
|
346
|
-
const text = extractEpisodeText(ep);
|
|
347
|
-
if (!text.trim())
|
|
348
|
-
continue;
|
|
349
|
-
const line = formatEpisodeLine(ep, text);
|
|
350
|
-
if (pool2Chars + line.length > remainingBudget)
|
|
351
|
-
break;
|
|
352
|
-
pool2.push({ ep, line });
|
|
353
|
-
pool2Chars += line.length;
|
|
354
|
-
}
|
|
355
|
-
// Merge both pools and sort chronologically for coherent reading
|
|
356
|
-
return [...pool1, ...pool2]
|
|
357
|
-
.sort((a, b) => (a.ep.timestamp < b.ep.timestamp ? -1 : 1))
|
|
358
|
-
.map(x => x.line)
|
|
359
|
-
.join("\n");
|
|
360
|
-
}
|
|
361
|
-
function formatNotesForLLM(notes, maxChars) {
|
|
362
|
-
const lines = [];
|
|
363
|
-
let chars = 0;
|
|
364
|
-
for (const n of notes) {
|
|
365
|
-
const line = `- [${n.type}] ${n.content.slice(0, 600)} (conf: ${n.confidence.toFixed(2)})`;
|
|
366
|
-
if (chars + line.length > maxChars)
|
|
367
|
-
break;
|
|
368
|
-
lines.push(line);
|
|
369
|
-
chars += line.length;
|
|
370
|
-
}
|
|
371
|
-
return lines.join("\n");
|
|
372
|
-
}
|
|
373
|
-
// ─── LLM Prompts ─────────────────────────────────────────────────────────────
|
|
374
|
-
function buildPrompt(resolution, episodesText, notesText, episodeCount, periodLabel, periodStart) {
|
|
375
|
-
const startYear = new Date(periodStart).getFullYear();
|
|
376
|
-
const endYear = new Date().getFullYear();
|
|
377
|
-
const instructions = {
|
|
378
|
-
day: `Write a narrative of what happened today (${periodLabel}). Tell the story chronologically — what happened, why, what it caused. Include timestamps (hours:minutes) for each event. Write in flowing prose, connecting events with cause and effect. Be specific: name systems, threads, versions, IDs. Target ~400 tokens.`,
|
|
379
|
-
week: `Write a narrative of the key developments this week (${periodLabel}). Tell the story chronologically by day. For each event: what triggered it, what was decided, what resulted. Connect events across days — show how Monday's decision led to Wednesday's outcome. Write in flowing prose, not a list. Use day-level dates, no hours. Target ~800 tokens.`,
|
|
380
|
-
month: `Write a chronological decision log for this month (${periodLabel}). Format: "Date — decision/event. Reason. Result." One entry per line. Each entry should have enough context to stand alone — a reader who sees only this entry should understand why it matters. Only include: decisions that changed project direction, bugs that broke something, features shipped. Skip routine fixes, code reviews, type errors, status checks. Day-level dates, no hours. End with unresolved items. Target ~1600 tokens.`,
|
|
381
|
-
quarter: `Write a narrative overview of this quarter (${periodLabel}) organized by initiative. Group by subsystem (e.g. "Dashboard", "Memory system", "Narrative pipeline", "Session management"). For each initiative, write 1-2 flowing paragraphs that tell the STORY of how it evolved: what the state was at the start of the quarter, what problems appeared, what decisions were made and why, and where it ended up. Reference specific dates, versions, and IDs as evidence within the prose — but do NOT use a list or log format. The reader should understand the arc of each initiative from a connected narrative, not from scanning dated entries. Include initiatives where direction changed, major bugs appeared, features shipped, or architecture shifted. Episodes marked [imp: 0.6+] are operator-priority — weave them in. End with a short "Unresolved" section. Target ~3000 tokens.`,
|
|
382
|
-
half_year: `Write a high-level evolution summary for this half-year (${periodLabel}). Do NOT repeat the quarterly grouped changelog — instead, synthesize it into 5-8 thematic arcs that show HOW the project evolved. For each arc: what the system looked like at the start, what forces drove change, and where it ended up. Example arcs: "Memory system evolution", "Session management maturity", "Narrative pipeline development". Within each arc, reference specific dates and versions as evidence, but the focus is the trajectory, not individual events. End with a "Current state" section: what works, what's fragile, what's next. Target ~4000 tokens.`,
|
|
383
|
-
};
|
|
384
|
-
const styleByResolution = {
|
|
385
|
-
day: `STYLE:
|
|
386
|
-
- Write flowing prose, not bullet points or numbered lists. Connect events into a story.
|
|
387
|
-
- First person for yourself ("I did..."), third person for the operator ("The operator...").
|
|
388
|
-
- Name every system, thread, feature by exact name with IDs where available.
|
|
389
|
-
- Be concrete — every sentence needs at least one identifier (name, version, date, ID, number).
|
|
390
|
-
- Preserve cause-and-effect chains: "X happened because Y, which led to Z."
|
|
391
|
-
- No filler phrases: "significant progress", "notable improvement", "pivotal moment", "crucial step".
|
|
392
|
-
- NEVER open with "In [Month]..." or "During [Month]..." — start with what happened.
|
|
393
|
-
- NEVER write introductory or concluding paragraphs that summarize.`,
|
|
394
|
-
week: `STYLE:
|
|
395
|
-
- Write flowing prose, not bullet points or numbered lists. Connect events into a weekly story.
|
|
396
|
-
- First person for yourself ("I did..."), third person for the operator ("The operator...").
|
|
397
|
-
- Name every system, thread, feature by exact name with IDs where available.
|
|
398
|
-
- Be concrete — every sentence needs at least one identifier (name, version, date, ID, number).
|
|
399
|
-
- Preserve cause-and-effect chains across days.
|
|
400
|
-
- No filler phrases: "significant progress", "notable improvement", "pivotal moment", "crucial step".
|
|
401
|
-
- NEVER open with "In [Month]..." or "During [Month]..." — start with what happened.
|
|
402
|
-
- NEVER write introductory or concluding paragraphs that summarize.`,
|
|
403
|
-
month: `STYLE:
|
|
404
|
-
- Each log entry: 1-2 sentences with full context. A reader should understand the entry without reading others.
|
|
405
|
-
- First person for yourself ("I did..."), third person for the operator ("The operator...").
|
|
406
|
-
- Name every system, thread, feature by exact name with IDs where available.
|
|
407
|
-
- No filler phrases: "significant progress", "notable improvement", "pivotal moment", "crucial step".
|
|
408
|
-
- NEVER open with "In [Month]..." or "During [Month]..." or "The period was marked by...".
|
|
409
|
-
- NEVER write introductory or concluding paragraphs.`,
|
|
410
|
-
quarter: `STYLE:
|
|
411
|
-
- Start each initiative with its name on its own line, then write 1-2 prose paragraphs. NO dated entries, NO log format.
|
|
412
|
-
- Write flowing connected narrative — "The memory system entered the quarter with X problem. In April, Y happened because Z, which led to W by May."
|
|
413
|
-
- First person for yourself ("I did..."), third person for the operator ("The operator...").
|
|
414
|
-
- Name every system, thread, feature by exact name with IDs where available.
|
|
415
|
-
- Reference dates and versions naturally within prose, not as entry prefixes.
|
|
416
|
-
- Show cross-month cause-effect — how one month's decisions shaped the next.
|
|
417
|
-
- No filler phrases: "significant progress", "notable improvement", "pivotal moment", "crucial step".
|
|
418
|
-
- NEVER open with "In [Month]..." or "During [Month]..." or "The period was marked by...".
|
|
419
|
-
- NEVER write introductory or concluding paragraphs.`,
|
|
420
|
-
half_year: `STYLE:
|
|
421
|
-
- Write in thematic arc paragraphs, not a chronological list. Each arc = 1-2 paragraphs.
|
|
422
|
-
- First person for yourself ("I did..."), third person for the operator ("The operator...").
|
|
423
|
-
- Name every system, thread, feature by exact name with IDs where available.
|
|
424
|
-
- Within each arc, reference specific dates and versions as evidence of the trajectory.
|
|
425
|
-
- No filler phrases: "significant progress", "notable improvement", "pivotal moment", "crucial step".
|
|
426
|
-
- NEVER open with "In [Month]..." or "During [Month]..." or "The period was marked by...".
|
|
427
|
-
- NEVER write an introductory paragraph. Start directly with the first arc.`,
|
|
428
|
-
};
|
|
429
|
-
return `You are a temporal memory narrator. You create concise records from raw interaction data.
|
|
430
|
-
|
|
431
|
-
${instructions[resolution]}
|
|
432
|
-
|
|
433
|
-
${styleByResolution[resolution]}
|
|
434
|
-
- Only use years in the range ${startYear}${startYear !== endYear ? `–${endYear}` : ""}.
|
|
435
|
-
|
|
436
|
-
SOURCE DATA (${episodeCount} episodes):
|
|
437
|
-
|
|
438
|
-
=== Recent Episodes ===
|
|
439
|
-
${episodesText || "(no episodes in this period)"}
|
|
440
|
-
|
|
441
|
-
=== Relevant Knowledge ===
|
|
442
|
-
${notesText || "(no notes)"}
|
|
443
|
-
|
|
444
|
-
Write now. Plain text, no markdown.`;
|
|
445
|
-
}
|
|
446
|
-
function buildHierarchicalPrompt(resolution, childNarrativesText, childResolution, childCount, periodLabel, periodStart) {
|
|
447
|
-
const startYear = new Date(periodStart).getFullYear();
|
|
448
|
-
const endYear = new Date().getFullYear();
|
|
449
|
-
const instructions = {
|
|
450
|
-
month: `Write a chronological decision log for this month (${periodLabel}). You have ${childCount} weekly narratives below. Format: "Date — decision/event. Reason. Result." One entry per line. Each entry should have enough context to stand alone — a reader who sees only this entry should understand why it matters. Preserve important context from the weekly narratives — don't compress away the reasons and consequences. Only include: decisions that changed project direction, bugs that broke something, features shipped. Skip routine fixes, code reviews, type errors. Day-level dates, no hours. End with unresolved items. Target ~1600 tokens.`,
|
|
451
|
-
quarter: `Write a narrative overview of this quarter (${periodLabel}) organized by initiative. You have ${childCount} monthly narratives and possibly top-importance raw episodes below. Group by subsystem (e.g. "Dashboard", "Memory system", "Narrative pipeline", "Session management"). For each initiative, write 1-2 flowing paragraphs that tell the STORY of how it evolved: what the state was at the start, what problems appeared, what decisions were made and why, and where it ended up. Reference specific dates, versions, and IDs within the prose — but do NOT use a list or log format. Synthesize the monthly narratives into a connected story, don't just re-list their entries. The reader should understand each initiative's arc from prose, not from scanning dated lines. Raw episodes marked [imp: 0.6+] are operator-priority — weave them in. End with a short "Unresolved" section. Target ~3000 tokens.`,
|
|
452
|
-
half_year: `Write a high-level evolution summary for this half-year (${periodLabel}). You have ${childCount} quarterly changelogs and possibly top-importance raw episodes below. Do NOT repeat the quarterly grouped changelogs — instead, synthesize them into 5-8 thematic arcs that show HOW the project evolved over 6 months. For each arc: what the system looked like at the start of the period, what forces drove change (operator feedback, bugs, scaling needs), and where it ended up. Example arcs: "Memory system evolution", "Session management maturity", "Narrative pipeline development". Within each arc, reference specific dates and versions as evidence, but the focus is the trajectory — not individual events. End with a "Current state" section: what works, what's fragile, what's next. Target ~4000 tokens.`,
|
|
453
|
-
};
|
|
454
|
-
const styleByResolution = {
|
|
455
|
-
month: `STYLE:
|
|
456
|
-
- Each log entry: 1-3 sentences with full context. Explain the situation, not just the fact.
|
|
457
|
-
- First person for yourself ("I did..."), third person for the operator ("The operator...").
|
|
458
|
-
- Name every system, thread, feature by exact name with IDs where available.
|
|
459
|
-
- Every sentence must have at least one identifier (name, version, date, ID, number).
|
|
460
|
-
- No filler phrases: "significant progress", "notable improvement", "pivotal moment", "crucial step", "driven by", "shaped the direction", "the focus remains on".
|
|
461
|
-
- NEVER open with "In [Month]..." or "During [Month]..." or "The period was marked by...".
|
|
462
|
-
- NEVER write introductory or concluding paragraphs.`,
|
|
463
|
-
quarter: `STYLE:
|
|
464
|
-
- Start each initiative with its name on its own line, then write 1-2 prose paragraphs. NO dated entries, NO log format.
|
|
465
|
-
- Write flowing connected narrative that tells the story of each initiative's evolution.
|
|
466
|
-
- First person for yourself ("I did..."), third person for the operator ("The operator...").
|
|
467
|
-
- Name every system, thread, feature by exact name with IDs where available.
|
|
468
|
-
- Reference dates and versions naturally within prose, not as entry prefixes.
|
|
469
|
-
- No filler phrases: "significant progress", "notable improvement", "pivotal moment", "crucial step", "driven by", "shaped the direction", "the focus remains on".
|
|
470
|
-
- NEVER open with "In [Month]..." or "During [Month]..." or "The period was marked by...".
|
|
471
|
-
- NEVER write introductory or concluding paragraphs.`,
|
|
472
|
-
half_year: `STYLE:
|
|
473
|
-
- Write in thematic arc paragraphs. Each arc = 1-2 paragraphs showing system evolution.
|
|
474
|
-
- First person for yourself ("I did..."), third person for the operator ("The operator...").
|
|
475
|
-
- Name every system, thread, feature by exact name with IDs where available.
|
|
476
|
-
- Reference dates and versions as evidence of the trajectory within prose.
|
|
477
|
-
- No filler phrases: "significant progress", "notable improvement", "pivotal moment", "crucial step", "driven by", "shaped the direction", "the focus remains on".
|
|
478
|
-
- NEVER open with "In [Month]..." or "During [Month]..." or "The period was marked by...".
|
|
479
|
-
- NEVER write introductory or concluding paragraphs.`,
|
|
480
|
-
};
|
|
481
|
-
return `You are a temporal memory narrator. You synthesize lower-resolution narratives into higher-level summaries.
|
|
482
|
-
|
|
483
|
-
${instructions[resolution]}
|
|
484
|
-
|
|
485
|
-
${styleByResolution[resolution] || ""}
|
|
486
|
-
- Only use years in the range ${startYear}${startYear !== endYear ? `–${endYear}` : ""}.
|
|
487
|
-
|
|
488
|
-
SOURCE: ${childCount} ${childResolution} narratives
|
|
489
|
-
|
|
490
|
-
${childNarrativesText}
|
|
491
|
-
|
|
492
|
-
Write now. Plain text, no markdown.`;
|
|
493
|
-
}
|
|
74
|
+
// ─── Prompt Assembly ─────────────────────────────────────────────────────────
|
|
494
75
|
function buildFlatPrompt(db, knowledgeThreadId, resolution, start, end, periodLabel) {
|
|
495
76
|
const episodes = getEpisodesInPeriod(db, knowledgeThreadId, start, end);
|
|
496
77
|
const minEpisodes = resolution === "day" ? 3 : 5;
|
|
@@ -508,97 +89,14 @@ function buildFlatPrompt(db, knowledgeThreadId, resolution, start, end, periodLa
|
|
|
508
89
|
noteCount: notes.length,
|
|
509
90
|
};
|
|
510
91
|
}
|
|
511
|
-
// ─── Cooldown Check ──────────────────────────────────────────────────────────
|
|
512
|
-
function getLastNarrative(db, threadId, resolution) {
|
|
513
|
-
const row = db
|
|
514
|
-
.prepare(`SELECT * FROM temporal_narratives
|
|
515
|
-
WHERE thread_id = ? AND resolution = ?
|
|
516
|
-
ORDER BY period_start DESC LIMIT 1`)
|
|
517
|
-
.get(threadId, resolution);
|
|
518
|
-
if (!row)
|
|
519
|
-
return null;
|
|
520
|
-
return {
|
|
521
|
-
id: row.id,
|
|
522
|
-
threadId: row.thread_id,
|
|
523
|
-
resolution: row.resolution,
|
|
524
|
-
periodStart: row.period_start,
|
|
525
|
-
periodEnd: row.period_end,
|
|
526
|
-
narrative: row.narrative,
|
|
527
|
-
sourceEpisodeCount: row.source_episode_count,
|
|
528
|
-
sourceNoteCount: row.source_note_count,
|
|
529
|
-
model: row.model,
|
|
530
|
-
createdAt: row.created_at,
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
function getCurrentNarrative(db, threadId, resolution) {
|
|
534
|
-
const row = db
|
|
535
|
-
.prepare(`SELECT * FROM temporal_narratives
|
|
536
|
-
WHERE thread_id = ? AND resolution = ?
|
|
537
|
-
AND period_start <= datetime('now')
|
|
538
|
-
AND period_end >= datetime('now', '-1 day')
|
|
539
|
-
ORDER BY julianday(period_end) - julianday(period_start) DESC, created_at DESC
|
|
540
|
-
LIMIT 1`)
|
|
541
|
-
.get(threadId, resolution);
|
|
542
|
-
if (!row)
|
|
543
|
-
return null;
|
|
544
|
-
return {
|
|
545
|
-
id: row.id,
|
|
546
|
-
threadId: row.thread_id,
|
|
547
|
-
resolution: row.resolution,
|
|
548
|
-
periodStart: row.period_start,
|
|
549
|
-
periodEnd: row.period_end,
|
|
550
|
-
narrative: row.narrative,
|
|
551
|
-
sourceEpisodeCount: row.source_episode_count,
|
|
552
|
-
sourceNoteCount: row.source_note_count,
|
|
553
|
-
model: row.model,
|
|
554
|
-
createdAt: row.created_at,
|
|
555
|
-
};
|
|
556
|
-
}
|
|
557
|
-
function isCooldownActive(db, threadId, resolution) {
|
|
558
|
-
const last = getLastNarrative(db, threadId, resolution);
|
|
559
|
-
if (!last)
|
|
560
|
-
return false;
|
|
561
|
-
const elapsed = Date.now() - new Date(last.createdAt).getTime();
|
|
562
|
-
return elapsed < COOLDOWNS[resolution];
|
|
563
|
-
}
|
|
564
92
|
// ─── Generation ──────────────────────────────────────────────────────────────
|
|
565
|
-
function getChildWindowDays(resolution) {
|
|
566
|
-
switch (resolution) {
|
|
567
|
-
case "week": return 1;
|
|
568
|
-
case "month": return 7;
|
|
569
|
-
case "quarter": return 30;
|
|
570
|
-
case "half_year": return 90;
|
|
571
|
-
default: return 0;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
function enumerateChildWindows(resolution, parentStart, parentEnd) {
|
|
575
|
-
const childRes = CHILD_RESOLUTION[resolution];
|
|
576
|
-
if (!childRes)
|
|
577
|
-
return [];
|
|
578
|
-
const windowDays = getChildWindowDays(resolution);
|
|
579
|
-
if (windowDays === 0)
|
|
580
|
-
return [];
|
|
581
|
-
const windows = [];
|
|
582
|
-
const pEnd = new Date(parentEnd);
|
|
583
|
-
const cur = new Date(parentStart);
|
|
584
|
-
cur.setUTCHours(0, 0, 0, 0);
|
|
585
|
-
while (cur < pEnd) {
|
|
586
|
-
const wEnd = new Date(cur);
|
|
587
|
-
wEnd.setUTCDate(wEnd.getUTCDate() + windowDays);
|
|
588
|
-
if (wEnd > pEnd)
|
|
589
|
-
wEnd.setTime(pEnd.getTime());
|
|
590
|
-
windows.push({ start: cur.toISOString(), end: wEnd.toISOString() });
|
|
591
|
-
cur.setUTCDate(cur.getUTCDate() + windowDays);
|
|
592
|
-
}
|
|
593
|
-
return windows;
|
|
594
|
-
}
|
|
595
93
|
async function backfillChildNarratives(db, threadId, resolution, parentStart, parentEnd) {
|
|
596
94
|
const childRes = CHILD_RESOLUTION[resolution];
|
|
597
95
|
if (!childRes)
|
|
598
96
|
return;
|
|
599
97
|
const knowledgeThreadId = threadId;
|
|
600
98
|
const existing = getChildNarratives(db, knowledgeThreadId, resolution, parentStart, parentEnd);
|
|
601
|
-
const existingStarts = new Set(existing.map(n => n.periodStart.slice(0, 10)));
|
|
99
|
+
const existingStarts = new Set(existing.map((n) => n.periodStart.slice(0, 10)));
|
|
602
100
|
const windows = enumerateChildWindows(resolution, parentStart, parentEnd);
|
|
603
101
|
for (const w of windows) {
|
|
604
102
|
if (existingStarts.has(w.start.slice(0, 10)))
|
|
@@ -640,7 +138,7 @@ async function generateNarrative(db, threadId, resolution, periodOverride) {
|
|
|
640
138
|
const children = getChildNarratives(db, knowledgeThreadId, resolution, start, end);
|
|
641
139
|
if (children.length > 0) {
|
|
642
140
|
const childText = formatChildNarrativesForLLM(children);
|
|
643
|
-
const coveredPeriods = new Set(children.flatMap(c => {
|
|
141
|
+
const coveredPeriods = new Set(children.flatMap((c) => {
|
|
644
142
|
const dates = [];
|
|
645
143
|
const cur = new Date(c.periodStart);
|
|
646
144
|
const stop = new Date(c.periodEnd);
|
|
@@ -651,7 +149,7 @@ async function generateNarrative(db, threadId, resolution, periodOverride) {
|
|
|
651
149
|
return dates;
|
|
652
150
|
}));
|
|
653
151
|
const episodes = getEpisodesInPeriod(db, knowledgeThreadId, start, end);
|
|
654
|
-
const gapEpisodes = episodes.filter(ep => !coveredPeriods.has(ep.timestamp.slice(0, 10)));
|
|
152
|
+
const gapEpisodes = episodes.filter((ep) => !coveredPeriods.has(ep.timestamp.slice(0, 10)));
|
|
655
153
|
const budget = INPUT_CHAR_BUDGETS[resolution];
|
|
656
154
|
const gapText = gapEpisodes.length > 0 ? formatEpisodesForLLM(gapEpisodes, budget.episodes) : "";
|
|
657
155
|
// For quarter/half_year: inject top-20 highest-importance raw episodes so strategic
|
|
@@ -659,14 +157,17 @@ async function generateNarrative(db, threadId, resolution, periodOverride) {
|
|
|
659
157
|
let topEpisodesText = "";
|
|
660
158
|
if (resolution === "quarter" || resolution === "half_year") {
|
|
661
159
|
const topN = [...episodes]
|
|
662
|
-
.filter(ep => (ep.importance ?? 0.5) >= 0.6)
|
|
160
|
+
.filter((ep) => (ep.importance ?? 0.5) >= 0.6)
|
|
663
161
|
.sort((a, b) => (b.importance ?? 0.5) - (a.importance ?? 0.5))
|
|
664
162
|
.slice(0, 20);
|
|
665
163
|
if (topN.length > 0) {
|
|
666
|
-
topEpisodesText = topN
|
|
164
|
+
topEpisodesText = topN
|
|
165
|
+
.map((ep) => {
|
|
667
166
|
const text = extractEpisodeText(ep);
|
|
668
167
|
return text.trim() ? formatEpisodeLine(ep, text) : "";
|
|
669
|
-
})
|
|
168
|
+
})
|
|
169
|
+
.filter(Boolean)
|
|
170
|
+
.join("\n");
|
|
670
171
|
}
|
|
671
172
|
}
|
|
672
173
|
const parts = [`=== ${children.length} ${childRes} narrative(s) ===\n${childText}`];
|
|
@@ -676,7 +177,8 @@ async function generateNarrative(db, threadId, resolution, periodOverride) {
|
|
|
676
177
|
parts.push(`=== Raw episodes from uncovered periods ===\n${gapText}`);
|
|
677
178
|
const source = parts.join("\n\n");
|
|
678
179
|
prompt = buildHierarchicalPrompt(resolution, source, childRes, children.length, periodLabel, start);
|
|
679
|
-
sourceEpisodeCount =
|
|
180
|
+
sourceEpisodeCount =
|
|
181
|
+
children.reduce((sum, c) => sum + c.sourceEpisodeCount, 0) + gapEpisodes.length;
|
|
680
182
|
sourceNoteCount = 0;
|
|
681
183
|
log.info(`[narrative] ${resolution}: ${children.length} ${childRes} narratives + ${gapEpisodes.length} gap episodes`);
|
|
682
184
|
}
|
|
@@ -728,9 +230,17 @@ async function generateNarrative(db, threadId, resolution, periodOverride) {
|
|
|
728
230
|
if (dateViolation)
|
|
729
231
|
corrections.push(`Fix date error: ${dateViolation}. Only reference dates within the period ${start.slice(0, 10)} to ${end.slice(0, 10)}. Do NOT substitute the current year for dates in earlier periods.`);
|
|
730
232
|
if (hasDensityProblem)
|
|
731
|
-
corrections.push(`${density.count} sentences contain no identifiers (names, dates, numbers, IDs). Examples: ${density.examples.map(s => `"${s}..."`).join("; ")}. Every sentence must contain at least one concrete identifier.`);
|
|
732
|
-
const retryPrompt = prompt +
|
|
733
|
-
|
|
233
|
+
corrections.push(`${density.count} sentences contain no identifiers (names, dates, numbers, IDs). Examples: ${density.examples.map((s) => `"${s}..."`).join("; ")}. Every sentence must contain at least one concrete identifier.`);
|
|
234
|
+
const retryPrompt = prompt +
|
|
235
|
+
"\n\n" +
|
|
236
|
+
corrections.join(" ") +
|
|
237
|
+
" Every claim must reference a specific event or decision from the source data.";
|
|
238
|
+
const retried = await chatCompletion([{ role: "user", content: retryPrompt }], apiKey, {
|
|
239
|
+
model: NARRATIVE_MODEL,
|
|
240
|
+
temperature: 0.3,
|
|
241
|
+
maxTokens: Math.round(OUTPUT_TOKEN_TARGETS[resolution] * 1.5),
|
|
242
|
+
timeoutMs: 60_000,
|
|
243
|
+
});
|
|
734
244
|
if (retried?.trim()) {
|
|
735
245
|
const retryFiller = findFillerPhrase(retried.trim());
|
|
736
246
|
const retryDate = findDateViolation(retried.trim(), start, end);
|