visionclaw 0.1.209 → 0.1.210-beta.2
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/dist/agent/backup.d.ts +10 -1
- package/dist/agent/backup.d.ts.map +1 -1
- package/dist/agent/backup.js +24 -1
- package/dist/agent/backup.js.map +1 -1
- package/dist/agent/browser-launcher.d.ts.map +1 -1
- package/dist/agent/browser-launcher.js +22 -20
- package/dist/agent/browser-launcher.js.map +1 -1
- package/dist/agent/context.d.ts +1 -1
- package/dist/agent/context.d.ts.map +1 -1
- package/dist/agent/context.js +28 -24
- package/dist/agent/context.js.map +1 -1
- package/dist/agent/engines/claude/session-browser-policy.d.ts.map +1 -1
- package/dist/agent/engines/claude/session-browser-policy.js +2 -16
- package/dist/agent/engines/claude/session-browser-policy.js.map +1 -1
- package/dist/agent/engines/claude/session.d.ts.map +1 -1
- package/dist/agent/engines/claude/session.js +6 -9
- package/dist/agent/engines/claude/session.js.map +1 -1
- package/dist/agent/engines/pi/tools.d.ts +7 -0
- package/dist/agent/engines/pi/tools.d.ts.map +1 -1
- package/dist/agent/engines/pi/tools.js +5 -1
- package/dist/agent/engines/pi/tools.js.map +1 -1
- package/dist/agent/engines/pi-coding/session.d.ts.map +1 -1
- package/dist/agent/engines/pi-coding/session.js +2 -0
- package/dist/agent/engines/pi-coding/session.js.map +1 -1
- package/dist/agent/engines/pi-coding/tools.d.ts +1 -0
- package/dist/agent/engines/pi-coding/tools.d.ts.map +1 -1
- package/dist/agent/engines/pi-coding/tools.js.map +1 -1
- package/dist/agent/gather-context.d.ts.map +1 -1
- package/dist/agent/gather-context.js +3 -1
- package/dist/agent/gather-context.js.map +1 -1
- package/dist/agent/heartbeat-manager.d.ts +3 -1
- package/dist/agent/heartbeat-manager.d.ts.map +1 -1
- package/dist/agent/heartbeat-manager.js +21 -0
- package/dist/agent/heartbeat-manager.js.map +1 -1
- package/dist/agent/interrupt-handler.d.ts.map +1 -1
- package/dist/agent/interrupt-handler.js +7 -1
- package/dist/agent/interrupt-handler.js.map +1 -1
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +76 -23
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/onboarding-gate.d.ts +1 -1
- package/dist/agent/onboarding-gate.d.ts.map +1 -1
- package/dist/agent/onboarding-gate.js +3 -2
- package/dist/agent/onboarding-gate.js.map +1 -1
- package/dist/agent/owner-channel-resolver.d.ts +1 -1
- package/dist/agent/owner-channel-resolver.d.ts.map +1 -1
- package/dist/agent/owner-channel-resolver.js +12 -0
- package/dist/agent/owner-channel-resolver.js.map +1 -1
- package/dist/agent/runtime-surface.d.ts +2 -0
- package/dist/agent/runtime-surface.d.ts.map +1 -1
- package/dist/agent/runtime-surface.js +3 -0
- package/dist/agent/runtime-surface.js.map +1 -1
- package/dist/agent/session-manager.d.ts +1 -1
- package/dist/agent/session-manager.d.ts.map +1 -1
- package/dist/agent/session-manager.js +13 -5
- package/dist/agent/session-manager.js.map +1 -1
- package/dist/agent/state.d.ts +2 -0
- package/dist/agent/state.d.ts.map +1 -1
- package/dist/agent/state.js.map +1 -1
- package/dist/agent/status.d.ts +1 -1
- package/dist/agent/status.d.ts.map +1 -1
- package/dist/agent/status.js +45 -14
- package/dist/agent/status.js.map +1 -1
- package/dist/agent/system-prompt.d.ts +1 -1
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +29 -13
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/usage/usage-gate.d.ts.map +1 -1
- package/dist/agent/usage/usage-gate.js +6 -10
- package/dist/agent/usage/usage-gate.js.map +1 -1
- package/dist/calendar/calendar-interrupt-poller.d.ts +1 -1
- package/dist/calendar/calendar-interrupt-poller.d.ts.map +1 -1
- package/dist/calendar/calendar-interrupt-poller.js +5 -0
- package/dist/calendar/calendar-interrupt-poller.js.map +1 -1
- package/dist/calendar/scheduler.d.ts +1 -1
- package/dist/calendar/scheduler.d.ts.map +1 -1
- package/dist/calendar/scheduler.js +3 -0
- package/dist/calendar/scheduler.js.map +1 -1
- package/dist/channels/gmail.d.ts +3 -2
- package/dist/channels/gmail.d.ts.map +1 -1
- package/dist/channels/gmail.js +1 -0
- package/dist/channels/gmail.js.map +1 -1
- package/dist/channels/manager.d.ts +1 -1
- package/dist/channels/manager.d.ts.map +1 -1
- package/dist/channels/manager.js +22 -11
- package/dist/channels/manager.js.map +1 -1
- package/dist/channels/queue.d.ts +4 -0
- package/dist/channels/queue.d.ts.map +1 -1
- package/dist/channels/queue.js +10 -0
- package/dist/channels/queue.js.map +1 -1
- package/dist/channels/tui.d.ts +24 -10
- package/dist/channels/tui.d.ts.map +1 -1
- package/dist/channels/tui.js +104 -15
- package/dist/channels/tui.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +19 -28
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +3 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/types.d.ts +32 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +48 -1
- package/dist/config/types.js.map +1 -1
- package/dist/e2e/suites/google.d.ts.map +1 -1
- package/dist/e2e/suites/google.js +11 -3
- package/dist/e2e/suites/google.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/obs/rdp/backend.d.ts +12 -0
- package/dist/obs/rdp/backend.d.ts.map +1 -0
- package/dist/obs/rdp/backend.js +10 -0
- package/dist/obs/rdp/backend.js.map +1 -0
- package/dist/obs/rdp/linux-x11-backend.d.ts +25 -0
- package/dist/obs/rdp/linux-x11-backend.d.ts.map +1 -0
- package/dist/obs/rdp/linux-x11-backend.js +161 -0
- package/dist/obs/rdp/linux-x11-backend.js.map +1 -0
- package/dist/obs/rdp/macos-backend.d.ts +12 -0
- package/dist/obs/rdp/macos-backend.d.ts.map +1 -0
- package/dist/obs/rdp/macos-backend.js +39 -0
- package/dist/obs/rdp/macos-backend.js.map +1 -0
- package/dist/obs/rdp/stream-manager.d.ts +3 -0
- package/dist/obs/rdp/stream-manager.d.ts.map +1 -1
- package/dist/obs/rdp/stream-manager.js +23 -42
- package/dist/obs/rdp/stream-manager.js.map +1 -1
- package/dist/obs/server.d.ts +1 -1
- package/dist/obs/server.d.ts.map +1 -1
- package/dist/obs/server.js +8 -3
- package/dist/obs/server.js.map +1 -1
- package/dist/onboarding/bootstrap-client.d.ts +43 -18
- package/dist/onboarding/bootstrap-client.d.ts.map +1 -1
- package/dist/onboarding/bootstrap-client.js +11 -1
- package/dist/onboarding/bootstrap-client.js.map +1 -1
- package/dist/onboarding/generate-wallpaper.d.ts +29 -0
- package/dist/onboarding/generate-wallpaper.d.ts.map +1 -1
- package/dist/onboarding/generate-wallpaper.js +58 -38
- package/dist/onboarding/generate-wallpaper.js.map +1 -1
- package/dist/onboarding/host-resolver.d.ts +2 -0
- package/dist/onboarding/host-resolver.d.ts.map +1 -0
- package/dist/onboarding/host-resolver.js +18 -0
- package/dist/onboarding/host-resolver.js.map +1 -0
- package/dist/onboarding/index.d.ts.map +1 -1
- package/dist/onboarding/index.js +2 -17
- package/dist/onboarding/index.js.map +1 -1
- package/dist/onboarding/onboarding-service-client.d.ts +2 -0
- package/dist/onboarding/onboarding-service-client.d.ts.map +1 -1
- package/dist/onboarding/onboarding-service-client.js.map +1 -1
- package/dist/onboarding/prepare-linux.d.ts +9 -0
- package/dist/onboarding/prepare-linux.d.ts.map +1 -0
- package/dist/onboarding/prepare-linux.js +64 -0
- package/dist/onboarding/prepare-linux.js.map +1 -0
- package/dist/onboarding/send-invite.d.ts +1 -1
- package/dist/onboarding/send-invite.d.ts.map +1 -1
- package/dist/onboarding/send-invite.js +23 -7
- package/dist/onboarding/send-invite.js.map +1 -1
- package/dist/onboarding/setup-shared.d.ts +10 -2
- package/dist/onboarding/setup-shared.d.ts.map +1 -1
- package/dist/onboarding/setup-shared.js +37 -6
- package/dist/onboarding/setup-shared.js.map +1 -1
- package/dist/onboarding/setup-state.d.ts +1 -0
- package/dist/onboarding/setup-state.d.ts.map +1 -1
- package/dist/onboarding/setup-state.js +1 -0
- package/dist/onboarding/setup-state.js.map +1 -1
- package/dist/onboarding/setup-steps.d.ts.map +1 -1
- package/dist/onboarding/setup-steps.js +53 -18
- package/dist/onboarding/setup-steps.js.map +1 -1
- package/dist/onboarding/wallpaper-contract.d.ts +38 -0
- package/dist/onboarding/wallpaper-contract.d.ts.map +1 -0
- package/dist/onboarding/wallpaper-contract.js +2 -0
- package/dist/onboarding/wallpaper-contract.js.map +1 -0
- package/dist/onboarding/wallpaper-linux-x11.d.ts +8 -0
- package/dist/onboarding/wallpaper-linux-x11.d.ts.map +1 -0
- package/dist/onboarding/wallpaper-linux-x11.js +72 -0
- package/dist/onboarding/wallpaper-linux-x11.js.map +1 -0
- package/dist/onboarding/wallpaper-macos.d.ts +4 -0
- package/dist/onboarding/wallpaper-macos.d.ts.map +1 -0
- package/dist/onboarding/wallpaper-macos.js +32 -0
- package/dist/onboarding/wallpaper-macos.js.map +1 -0
- package/dist/onboarding/wallpaper-platform.d.ts +4 -0
- package/dist/onboarding/wallpaper-platform.d.ts.map +1 -0
- package/dist/onboarding/wallpaper-platform.js +41 -0
- package/dist/onboarding/wallpaper-platform.js.map +1 -0
- package/dist/reconfigure.d.ts.map +1 -1
- package/dist/reconfigure.js +16 -5
- package/dist/reconfigure.js.map +1 -1
- package/dist/reset.d.ts.map +1 -1
- package/dist/reset.js +7 -0
- package/dist/reset.js.map +1 -1
- package/dist/restore.d.ts +2 -0
- package/dist/restore.d.ts.map +1 -1
- package/dist/restore.js +25 -0
- package/dist/restore.js.map +1 -1
- package/dist/runtime/linux-baseline.d.ts +2 -0
- package/dist/runtime/linux-baseline.d.ts.map +1 -0
- package/dist/runtime/linux-baseline.js +21 -0
- package/dist/runtime/linux-baseline.js.map +1 -0
- package/dist/service/daemon.d.ts.map +1 -1
- package/dist/service/daemon.js +24 -0
- package/dist/service/daemon.js.map +1 -1
- package/dist/service/systemd.d.ts +11 -0
- package/dist/service/systemd.d.ts.map +1 -0
- package/dist/service/systemd.js +63 -0
- package/dist/service/systemd.js.map +1 -0
- package/dist/system/host-capabilities.d.ts +35 -0
- package/dist/system/host-capabilities.d.ts.map +1 -0
- package/dist/system/host-capabilities.js +107 -0
- package/dist/system/host-capabilities.js.map +1 -0
- package/dist/system/machine-identity.d.ts.map +1 -1
- package/dist/system/machine-identity.js +15 -0
- package/dist/system/machine-identity.js.map +1 -1
- package/dist/tools/computer-use.d.ts.map +1 -1
- package/dist/tools/computer-use.js +9 -2
- package/dist/tools/computer-use.js.map +1 -1
- package/dist/tools/desktop-executor-factory.d.ts.map +1 -1
- package/dist/tools/desktop-executor-factory.js +3 -0
- package/dist/tools/desktop-executor-factory.js.map +1 -1
- package/dist/tools/desktop-executor-linux.d.ts +19 -0
- package/dist/tools/desktop-executor-linux.d.ts.map +1 -0
- package/dist/tools/desktop-executor-linux.js +89 -0
- package/dist/tools/desktop-executor-linux.js.map +1 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -3
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/screenshot.js +7 -2
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tui/client.d.ts +46 -7
- package/dist/tui/client.d.ts.map +1 -1
- package/dist/tui/client.js +60 -16
- package/dist/tui/client.js.map +1 -1
- package/dist/tui/protocol.d.ts +40 -0
- package/dist/tui/protocol.d.ts.map +1 -0
- package/dist/tui/protocol.js +20 -0
- package/dist/tui/protocol.js.map +1 -0
- package/dist/tui/request-store.d.ts +40 -0
- package/dist/tui/request-store.d.ts.map +1 -0
- package/dist/tui/request-store.js +236 -0
- package/dist/tui/request-store.js.map +1 -0
- package/dist/tui/server.d.ts +3 -0
- package/dist/tui/server.d.ts.map +1 -1
- package/dist/tui/server.js +225 -36
- package/dist/tui/server.js.map +1 -1
- package/dist/workspace/google/gmail-email.d.ts +8 -2
- package/dist/workspace/google/gmail-email.d.ts.map +1 -1
- package/dist/workspace/google/gmail-email.js +6 -0
- package/dist/workspace/google/gmail-email.js.map +1 -1
- package/dist/workspace/provider-factory.d.ts +1 -1
- package/dist/workspace/provider-factory.d.ts.map +1 -1
- package/dist/workspace/provider-factory.js +27 -12
- package/dist/workspace/provider-factory.js.map +1 -1
- package/dist-agent/bundle.cjs +7037 -5329
- package/package.json +2 -2
- package/dist/agent/applied-credential-signature.d.ts +0 -53
- package/dist/agent/applied-credential-signature.d.ts.map +0 -1
- package/dist/agent/applied-credential-signature.js +0 -137
- package/dist/agent/applied-credential-signature.js.map +0 -1
- package/dist/agent/engines/client-factory.d.ts +0 -63
- package/dist/agent/engines/client-factory.d.ts.map +0 -1
- package/dist/agent/engines/client-factory.js +0 -382
- package/dist/agent/engines/client-factory.js.map +0 -1
- package/dist/agent/engines/engine.d.ts +0 -8
- package/dist/agent/engines/engine.d.ts.map +0 -1
- package/dist/agent/engines/engine.js +0 -15
- package/dist/agent/engines/engine.js.map +0 -1
- package/dist/agent/engines/openai/file-session.d.ts +0 -19
- package/dist/agent/engines/openai/file-session.d.ts.map +0 -1
- package/dist/agent/engines/openai/file-session.js +0 -78
- package/dist/agent/engines/openai/file-session.js.map +0 -1
- package/dist/agent/engines/openai/file-tools.d.ts +0 -35
- package/dist/agent/engines/openai/file-tools.d.ts.map +0 -1
- package/dist/agent/engines/openai/file-tools.js +0 -194
- package/dist/agent/engines/openai/file-tools.js.map +0 -1
- package/dist/agent/engines/openai/session.d.ts +0 -55
- package/dist/agent/engines/openai/session.d.ts.map +0 -1
- package/dist/agent/engines/openai/session.js +0 -447
- package/dist/agent/engines/openai/session.js.map +0 -1
- package/dist/agent/engines/openai/tools.d.ts +0 -15
- package/dist/agent/engines/openai/tools.d.ts.map +0 -1
- package/dist/agent/engines/openai/tools.js +0 -221
- package/dist/agent/engines/openai/tools.js.map +0 -1
- package/dist/agent/engines/pi/session.d.ts +0 -49
- package/dist/agent/engines/pi/session.d.ts.map +0 -1
- package/dist/agent/engines/pi/session.js +0 -309
- package/dist/agent/engines/pi/session.js.map +0 -1
- package/dist/agent/memory-preload.d.ts +0 -55
- package/dist/agent/memory-preload.d.ts.map +0 -1
- package/dist/agent/memory-preload.js +0 -166
- package/dist/agent/memory-preload.js.map +0 -1
- package/dist/agent/providers/claude/cli-resolver.d.ts +0 -16
- package/dist/agent/providers/claude/cli-resolver.d.ts.map +0 -1
- package/dist/agent/providers/claude/cli-resolver.js +0 -83
- package/dist/agent/providers/claude/cli-resolver.js.map +0 -1
- package/dist/agent/providers/claude/session-browser-policy.d.ts +0 -9
- package/dist/agent/providers/claude/session-browser-policy.d.ts.map +0 -1
- package/dist/agent/providers/claude/session-browser-policy.js +0 -49
- package/dist/agent/providers/claude/session-browser-policy.js.map +0 -1
- package/dist/agent/providers/claude/session.d.ts +0 -304
- package/dist/agent/providers/claude/session.d.ts.map +0 -1
- package/dist/agent/providers/claude/session.js +0 -1236
- package/dist/agent/providers/claude/session.js.map +0 -1
- package/dist/agent/providers/client-factory.d.ts +0 -60
- package/dist/agent/providers/client-factory.d.ts.map +0 -1
- package/dist/agent/providers/client-factory.js +0 -400
- package/dist/agent/providers/client-factory.js.map +0 -1
- package/dist/agent/providers/openai/file-session.d.ts +0 -19
- package/dist/agent/providers/openai/file-session.d.ts.map +0 -1
- package/dist/agent/providers/openai/file-session.js +0 -78
- package/dist/agent/providers/openai/file-session.js.map +0 -1
- package/dist/agent/providers/openai/session.d.ts +0 -55
- package/dist/agent/providers/openai/session.d.ts.map +0 -1
- package/dist/agent/providers/openai/session.js +0 -447
- package/dist/agent/providers/openai/session.js.map +0 -1
- package/dist/agent/providers/openai/tools.d.ts +0 -15
- package/dist/agent/providers/openai/tools.d.ts.map +0 -1
- package/dist/agent/providers/openai/tools.js +0 -229
- package/dist/agent/providers/openai/tools.js.map +0 -1
- package/dist/agent/providers/session-types.d.ts +0 -153
- package/dist/agent/providers/session-types.d.ts.map +0 -1
- package/dist/agent/providers/session-types.js +0 -2
- package/dist/agent/providers/session-types.js.map +0 -1
- package/dist/agent/providers/system-prompt-log.d.ts +0 -9
- package/dist/agent/providers/system-prompt-log.d.ts.map +0 -1
- package/dist/agent/providers/system-prompt-log.js +0 -46
- package/dist/agent/providers/system-prompt-log.js.map +0 -1
- package/dist/agent/qq-claim-signal.d.ts +0 -9
- package/dist/agent/qq-claim-signal.d.ts.map +0 -1
- package/dist/agent/qq-claim-signal.js +0 -38
- package/dist/agent/qq-claim-signal.js.map +0 -1
- package/dist/agent/transcript-backfill.d.ts +0 -54
- package/dist/agent/transcript-backfill.d.ts.map +0 -1
- package/dist/agent/transcript-backfill.js +0 -604
- package/dist/agent/transcript-backfill.js.map +0 -1
- package/dist/agent/transcript-indexer.d.ts +0 -200
- package/dist/agent/transcript-indexer.d.ts.map +0 -1
- package/dist/agent/transcript-indexer.js +0 -775
- package/dist/agent/transcript-indexer.js.map +0 -1
- package/dist/agent/transcript-memory-migrations.d.ts +0 -25
- package/dist/agent/transcript-memory-migrations.d.ts.map +0 -1
- package/dist/agent/transcript-memory-migrations.js +0 -87
- package/dist/agent/transcript-memory-migrations.js.map +0 -1
- package/dist/agent/tunnel-credential-handler.d.ts +0 -90
- package/dist/agent/tunnel-credential-handler.d.ts.map +0 -1
- package/dist/agent/tunnel-credential-handler.js +0 -162
- package/dist/agent/tunnel-credential-handler.js.map +0 -1
- package/dist/agent/usage-backfill-handler.d.ts +0 -18
- package/dist/agent/usage-backfill-handler.d.ts.map +0 -1
- package/dist/agent/usage-backfill-handler.js +0 -69
- package/dist/agent/usage-backfill-handler.js.map +0 -1
- package/dist/agent/usage-gate.d.ts +0 -25
- package/dist/agent/usage-gate.d.ts.map +0 -1
- package/dist/agent/usage-gate.js +0 -83
- package/dist/agent/usage-gate.js.map +0 -1
- package/dist/agent/usage-handler.d.ts +0 -7
- package/dist/agent/usage-handler.d.ts.map +0 -1
- package/dist/agent/usage-handler.js +0 -28
- package/dist/agent/usage-handler.js.map +0 -1
- package/dist/agent/usage-report-builder.d.ts +0 -26
- package/dist/agent/usage-report-builder.d.ts.map +0 -1
- package/dist/agent/usage-report-builder.js +0 -80
- package/dist/agent/usage-report-builder.js.map +0 -1
- package/dist/agent/usage-report-queue.d.ts +0 -26
- package/dist/agent/usage-report-queue.d.ts.map +0 -1
- package/dist/agent/usage-report-queue.js +0 -199
- package/dist/agent/usage-report-queue.js.map +0 -1
- package/dist/agent/usage-report-types.d.ts +0 -41
- package/dist/agent/usage-report-types.d.ts.map +0 -1
- package/dist/agent/usage-report-types.js +0 -2
- package/dist/agent/usage-report-types.js.map +0 -1
- package/dist/agent/usage-reporter.d.ts +0 -31
- package/dist/agent/usage-reporter.d.ts.map +0 -1
- package/dist/agent/usage-reporter.js +0 -102
- package/dist/agent/usage-reporter.js.map +0 -1
- package/dist/agent/wake-cycle-tool-tracker.d.ts +0 -39
- package/dist/agent/wake-cycle-tool-tracker.d.ts.map +0 -1
- package/dist/agent/wake-cycle-tool-tracker.js +0 -72
- package/dist/agent/wake-cycle-tool-tracker.js.map +0 -1
- package/dist/anthropic-credentials.d.ts +0 -24
- package/dist/anthropic-credentials.d.ts.map +0 -1
- package/dist/anthropic-credentials.js +0 -37
- package/dist/anthropic-credentials.js.map +0 -1
- package/dist/billing/payg-handler.d.ts +0 -29
- package/dist/billing/payg-handler.d.ts.map +0 -1
- package/dist/billing/payg-handler.js +0 -92
- package/dist/billing/payg-handler.js.map +0 -1
- package/dist/billing/payment-handler.d.ts +0 -24
- package/dist/billing/payment-handler.d.ts.map +0 -1
- package/dist/billing/payment-handler.js +0 -101
- package/dist/billing/payment-handler.js.map +0 -1
- package/dist/builtin-skills/catalog/phone-adb-automation/SKILL.md +0 -412
- package/dist/builtin-skills/catalog/phone-adb-automation/phone_input.sh +0 -132
- package/dist/builtin-skills/catalog/phone-adb-automation/phone_launch.sh +0 -166
- package/dist/builtin-skills/catalog/phone-adb-automation/phone_screenshot.sh +0 -87
- package/dist/builtin-skills/catalog/phone-adb-automation/phone_security_kbd.py +0 -174
- package/dist/builtin-skills/catalog/phone-adb-automation/phone_setup.sh +0 -274
- package/dist/builtin-skills/catalog/phone-adb-automation/phone_swipe.sh +0 -111
- package/dist/builtin-skills/catalog/phone-adb-automation/phone_tap.sh +0 -87
- package/dist/builtin-skills/catalog/phone-adb-automation/phone_ui_parse.py +0 -176
- package/dist/builtin-skills/catalog/phone-adb-automation/phone_wake_unlock.sh +0 -67
- package/dist/builtin-skills/transcribe-audio/SKILL.md +0 -122
- package/dist/calendar/google-calendar.d.ts +0 -54
- package/dist/calendar/google-calendar.d.ts.map +0 -1
- package/dist/calendar/google-calendar.js +0 -156
- package/dist/calendar/google-calendar.js.map +0 -1
- package/dist/channels/web.d.ts +0 -40
- package/dist/channels/web.d.ts.map +0 -1
- package/dist/channels/web.js +0 -137
- package/dist/channels/web.js.map +0 -1
- package/dist/config/models.d.ts +0 -32
- package/dist/config/models.d.ts.map +0 -1
- package/dist/config/models.js +0 -57
- package/dist/config/models.js.map +0 -1
- package/dist/data-processing/convert-demo-cli.d.ts +0 -7
- package/dist/data-processing/convert-demo-cli.d.ts.map +0 -1
- package/dist/data-processing/convert-demo-cli.js +0 -30
- package/dist/data-processing/convert-demo-cli.js.map +0 -1
- package/dist/data-processing/convert-demo.d.ts +0 -26
- package/dist/data-processing/convert-demo.d.ts.map +0 -1
- package/dist/data-processing/convert-demo.js +0 -233
- package/dist/data-processing/convert-demo.js.map +0 -1
- package/dist/drive/google-drive.d.ts +0 -83
- package/dist/drive/google-drive.d.ts.map +0 -1
- package/dist/drive/google-drive.js +0 -219
- package/dist/drive/google-drive.js.map +0 -1
- package/dist/email/gmail-email.d.ts +0 -64
- package/dist/email/gmail-email.d.ts.map +0 -1
- package/dist/email/gmail-email.js +0 -167
- package/dist/email/gmail-email.js.map +0 -1
- package/dist/factcheck/agent.d.ts +0 -50
- package/dist/factcheck/agent.d.ts.map +0 -1
- package/dist/factcheck/agent.js +0 -508
- package/dist/factcheck/agent.js.map +0 -1
- package/dist/factcheck/financial-verifier.d.ts +0 -49
- package/dist/factcheck/financial-verifier.d.ts.map +0 -1
- package/dist/factcheck/financial-verifier.js +0 -109
- package/dist/factcheck/financial-verifier.js.map +0 -1
- package/dist/factcheck/setup.d.ts +0 -32
- package/dist/factcheck/setup.d.ts.map +0 -1
- package/dist/factcheck/setup.js +0 -70
- package/dist/factcheck/setup.js.map +0 -1
- package/dist/factcheck/sidecar.d.ts +0 -131
- package/dist/factcheck/sidecar.d.ts.map +0 -1
- package/dist/factcheck/sidecar.js +0 -348
- package/dist/factcheck/sidecar.js.map +0 -1
- package/dist/factcheck/store.d.ts +0 -111
- package/dist/factcheck/store.d.ts.map +0 -1
- package/dist/factcheck/store.js +0 -246
- package/dist/factcheck/store.js.map +0 -1
- package/dist/factcheck/web-searcher.d.ts +0 -22
- package/dist/factcheck/web-searcher.d.ts.map +0 -1
- package/dist/factcheck/web-searcher.js +0 -90
- package/dist/factcheck/web-searcher.js.map +0 -1
- package/dist/obs/auth.d.ts +0 -45
- package/dist/obs/auth.d.ts.map +0 -1
- package/dist/obs/auth.js +0 -181
- package/dist/obs/auth.js.map +0 -1
- package/dist/obs/mini-app/tasks.d.ts +0 -2
- package/dist/obs/mini-app/tasks.d.ts.map +0 -1
- package/dist/obs/mini-app/tasks.js +0 -506
- package/dist/obs/mini-app/tasks.js.map +0 -1
- package/dist/obs/rdp/icons/icons/app_windows.svg +0 -4
- package/dist/obs/rdp/icons/icons/clip_get.svg +0 -4
- package/dist/obs/rdp/icons/icons/clip_send.svg +0 -4
- package/dist/obs/rdp/icons/icons/clip_shared.svg +0 -4
- package/dist/obs/rdp/icons/icons/clipboard.svg +0 -4
- package/dist/obs/rdp/icons/icons/clipboard_shared.svg +0 -4
- package/dist/obs/rdp/icons/icons/control.svg +0 -4
- package/dist/obs/rdp/icons/icons/desktop.svg +0 -4
- package/dist/obs/rdp/icons/icons/display.svg +0 -4
- package/dist/obs/rdp/icons/icons/launchpad.svg +0 -4
- package/dist/obs/rdp/icons/icons/mission_control.svg +0 -4
- package/dist/obs/rdp/icons/icons/screenshot.svg +0 -4
- package/dist/obs/rdp/icons/icons/zoom_actual.svg +0 -4
- package/dist/obs/rdp/icons/icons/zoom_fit.svg +0 -4
- package/dist/obs/rdp/icons/icons/zoom_in.svg +0 -4
- package/dist/obs/rdp/icons/icons/zoom_out.svg +0 -4
- package/dist/obs/tunnel-telemetry.d.ts +0 -46
- package/dist/obs/tunnel-telemetry.d.ts.map +0 -1
- package/dist/obs/tunnel-telemetry.js +0 -70
- package/dist/obs/tunnel-telemetry.js.map +0 -1
- package/dist/onboarding/cloudflared-cert.d.ts +0 -15
- package/dist/onboarding/cloudflared-cert.d.ts.map +0 -1
- package/dist/onboarding/cloudflared-cert.js +0 -57
- package/dist/onboarding/cloudflared-cert.js.map +0 -1
- package/dist/onboarding/gh-auth-browser.d.ts +0 -10
- package/dist/onboarding/gh-auth-browser.d.ts.map +0 -1
- package/dist/onboarding/gh-auth-browser.js +0 -70
- package/dist/onboarding/gh-auth-browser.js.map +0 -1
- package/dist/onboarding/provision-eth-wallet.d.ts +0 -7
- package/dist/onboarding/provision-eth-wallet.d.ts.map +0 -1
- package/dist/onboarding/provision-eth-wallet.js +0 -14
- package/dist/onboarding/provision-eth-wallet.js.map +0 -1
- package/dist/onboarding/provision-workspace-account.d.ts +0 -14
- package/dist/onboarding/provision-workspace-account.d.ts.map +0 -1
- package/dist/onboarding/provision-workspace-account.js +0 -165
- package/dist/onboarding/provision-workspace-account.js.map +0 -1
- package/dist/onboarding/provisioning-spec.d.ts +0 -62
- package/dist/onboarding/provisioning-spec.d.ts.map +0 -1
- package/dist/onboarding/provisioning-spec.js +0 -159
- package/dist/onboarding/provisioning-spec.js.map +0 -1
- package/dist/onboarding/send-identity-credentials.d.ts +0 -11
- package/dist/onboarding/send-identity-credentials.d.ts.map +0 -1
- package/dist/onboarding/send-identity-credentials.js +0 -110
- package/dist/onboarding/send-identity-credentials.js.map +0 -1
- package/dist/onboarding/setup-credentials.d.ts +0 -7
- package/dist/onboarding/setup-credentials.d.ts.map +0 -1
- package/dist/onboarding/setup-credentials.js +0 -44
- package/dist/onboarding/setup-credentials.js.map +0 -1
- package/dist/openai-credentials.d.ts +0 -30
- package/dist/openai-credentials.d.ts.map +0 -1
- package/dist/openai-credentials.js +0 -37
- package/dist/openai-credentials.js.map +0 -1
- package/dist/phonecall-credentials.d.ts +0 -21
- package/dist/phonecall-credentials.d.ts.map +0 -1
- package/dist/phonecall-credentials.js +0 -34
- package/dist/phonecall-credentials.js.map +0 -1
- package/dist/realtime/agent-bridge.d.ts +0 -7
- package/dist/realtime/agent-bridge.d.ts.map +0 -1
- package/dist/realtime/agent-bridge.js +0 -31
- package/dist/realtime/agent-bridge.js.map +0 -1
- package/dist/realtime/assets/index.html +0 -1058
- package/dist/realtime/assets/samples/alloy.mp3 +0 -0
- package/dist/realtime/assets/samples/ash.mp3 +0 -0
- package/dist/realtime/assets/samples/ballad.mp3 +0 -0
- package/dist/realtime/assets/samples/cedar.mp3 +0 -0
- package/dist/realtime/assets/samples/coral.mp3 +0 -0
- package/dist/realtime/assets/samples/echo.mp3 +0 -0
- package/dist/realtime/assets/samples/marin.mp3 +0 -0
- package/dist/realtime/assets/samples/sage.mp3 +0 -0
- package/dist/realtime/assets/samples/shimmer.mp3 +0 -0
- package/dist/realtime/assets/samples/verse.mp3 +0 -0
- package/dist/realtime/context.d.ts +0 -14
- package/dist/realtime/context.d.ts.map +0 -1
- package/dist/realtime/context.js +0 -153
- package/dist/realtime/context.js.map +0 -1
- package/dist/realtime/http-helpers.d.ts +0 -5
- package/dist/realtime/http-helpers.d.ts.map +0 -1
- package/dist/realtime/http-helpers.js +0 -29
- package/dist/realtime/http-helpers.js.map +0 -1
- package/dist/realtime/index.d.ts +0 -62
- package/dist/realtime/index.d.ts.map +0 -1
- package/dist/realtime/index.js +0 -94
- package/dist/realtime/index.js.map +0 -1
- package/dist/realtime/server.d.ts +0 -6
- package/dist/realtime/server.d.ts.map +0 -1
- package/dist/realtime/server.js +0 -479
- package/dist/realtime/server.js.map +0 -1
- package/dist/realtime/telegram-auth.d.ts +0 -2
- package/dist/realtime/telegram-auth.d.ts.map +0 -1
- package/dist/realtime/telegram-auth.js +0 -24
- package/dist/realtime/telegram-auth.js.map +0 -1
- package/dist/realtime/tools.d.ts +0 -829
- package/dist/realtime/tools.d.ts.map +0 -1
- package/dist/realtime/tools.js +0 -611
- package/dist/realtime/tools.js.map +0 -1
- package/dist/realtime/types.d.ts +0 -62
- package/dist/realtime/types.d.ts.map +0 -1
- package/dist/realtime/types.js +0 -3
- package/dist/realtime/types.js.map +0 -1
- package/dist/realtime/voice-summarizer.d.ts +0 -4
- package/dist/realtime/voice-summarizer.d.ts.map +0 -1
- package/dist/realtime/voice-summarizer.js +0 -123
- package/dist/realtime/voice-summarizer.js.map +0 -1
- package/dist/realtime/websocket.d.ts +0 -7
- package/dist/realtime/websocket.d.ts.map +0 -1
- package/dist/realtime/websocket.js +0 -65
- package/dist/realtime/websocket.js.map +0 -1
- package/dist/service/gbox-tun.d.ts +0 -14
- package/dist/service/gbox-tun.d.ts.map +0 -1
- package/dist/service/gbox-tun.js +0 -315
- package/dist/service/gbox-tun.js.map +0 -1
- package/dist/skills/installed.d.ts +0 -11
- package/dist/skills/installed.d.ts.map +0 -1
- package/dist/skills/installed.js +0 -35
- package/dist/skills/installed.js.map +0 -1
- package/dist/tools/card.d.ts +0 -11
- package/dist/tools/card.d.ts.map +0 -1
- package/dist/tools/card.js +0 -87
- package/dist/tools/card.js.map +0 -1
- package/dist/tools/coordinate-resolver.d.ts +0 -30
- package/dist/tools/coordinate-resolver.d.ts.map +0 -1
- package/dist/tools/coordinate-resolver.js +0 -104
- package/dist/tools/coordinate-resolver.js.map +0 -1
- package/dist/tools/sms.d.ts +0 -16
- package/dist/tools/sms.d.ts.map +0 -1
- package/dist/tools/sms.js +0 -78
- package/dist/tools/sms.js.map +0 -1
- package/dist/tools/stock-data.d.ts +0 -70
- package/dist/tools/stock-data.d.ts.map +0 -1
- package/dist/tools/stock-data.js +0 -596
- package/dist/tools/stock-data.js.map +0 -1
- package/dist/tools/webapp.d.ts +0 -30
- package/dist/tools/webapp.d.ts.map +0 -1
- package/dist/tools/webapp.js +0 -114
- package/dist/tools/webapp.js.map +0 -1
- package/dist/utils/wechat-monitor.d.ts +0 -21
- package/dist/utils/wechat-monitor.d.ts.map +0 -1
- package/dist/utils/wechat-monitor.js +0 -88
- package/dist/utils/wechat-monitor.js.map +0 -1
- package/dist/webapp/index.d.ts +0 -28
- package/dist/webapp/index.d.ts.map +0 -1
- package/dist/webapp/index.js +0 -75
- package/dist/webapp/index.js.map +0 -1
- package/dist/webapp/server.d.ts +0 -32
- package/dist/webapp/server.d.ts.map +0 -1
- package/dist/webapp/server.js +0 -375
- package/dist/webapp/server.js.map +0 -1
- package/dist/webapp/storage.d.ts +0 -64
- package/dist/webapp/storage.d.ts.map +0 -1
- package/dist/webapp/storage.js +0 -103
- package/dist/webapp/storage.js.map +0 -1
- package/dist/webapp/ui.d.ts +0 -2
- package/dist/webapp/ui.d.ts.map +0 -1
- package/dist/webapp/ui.js +0 -319
- package/dist/webapp/ui.js.map +0 -1
- package/dist-agent/assets/index.html +0 -1058
- package/dist-agent/assets/samples/alloy.mp3 +0 -0
- package/dist-agent/assets/samples/ash.mp3 +0 -0
- package/dist-agent/assets/samples/ballad.mp3 +0 -0
- package/dist-agent/assets/samples/cedar.mp3 +0 -0
- package/dist-agent/assets/samples/coral.mp3 +0 -0
- package/dist-agent/assets/samples/echo.mp3 +0 -0
- package/dist-agent/assets/samples/marin.mp3 +0 -0
- package/dist-agent/assets/samples/sage.mp3 +0 -0
- package/dist-agent/assets/samples/shimmer.mp3 +0 -0
- package/dist-agent/assets/samples/verse.mp3 +0 -0
- package/dist-agent/realtime/assets/index.html +0 -1058
- package/dist-agent/realtime/assets/samples/alloy.mp3 +0 -0
- package/dist-agent/realtime/assets/samples/ash.mp3 +0 -0
- package/dist-agent/realtime/assets/samples/ballad.mp3 +0 -0
- package/dist-agent/realtime/assets/samples/cedar.mp3 +0 -0
- package/dist-agent/realtime/assets/samples/coral.mp3 +0 -0
- package/dist-agent/realtime/assets/samples/echo.mp3 +0 -0
- package/dist-agent/realtime/assets/samples/marin.mp3 +0 -0
- package/dist-agent/realtime/assets/samples/sage.mp3 +0 -0
- package/dist-agent/realtime/assets/samples/shimmer.mp3 +0 -0
- package/dist-agent/realtime/assets/samples/verse.mp3 +0 -0
|
@@ -1,775 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transcript-based structured memory: indexes wake cycle summaries into
|
|
3
|
-
* a SQLite database with FTS5 full-text search and sqlite-vec vector
|
|
4
|
-
* similarity search. Each wake cycle is summarized by an LLM after
|
|
5
|
-
* completion and stored for later retrieval.
|
|
6
|
-
*
|
|
7
|
-
* IMPORTANT — file terminology:
|
|
8
|
-
* - "source file" (DB column `source_file`): the JSONL file that contains
|
|
9
|
-
* the raw data for a wake cycle. This is EITHER:
|
|
10
|
-
* • An engine transcript for live-indexed cycles, such as:
|
|
11
|
-
* - Claude SDK: `~/.claude/projects/<slug>/<sessionId>.jsonl`
|
|
12
|
-
* - Pi Coding Agent: `~/.visionclaw/.../pi-agent/<mode>/sessions/<sessionId>.jsonl`
|
|
13
|
-
* • A **VisionClaw runtime log** (`~/.visionclaw/profiles/<profile>/logs/YYYY-MM-DD.jsonl`)
|
|
14
|
-
* for backfill-indexed cycles.
|
|
15
|
-
* These formats differ:
|
|
16
|
-
* - Claude transcripts: `{type:"user"|"assistant", message:{...}}`
|
|
17
|
-
* - Pi Coding transcripts: `{type:"message", message:{role, content, ...}}`
|
|
18
|
-
* - VisionClaw logs: `{timestamp, level, category, message, data}`
|
|
19
|
-
*
|
|
20
|
-
* This module handles:
|
|
21
|
-
* - SQLite schema creation (wake_cycles + FTS5 + vec0 virtual tables)
|
|
22
|
-
* - Reading source file lines (both Claude transcripts and VisionClaw logs)
|
|
23
|
-
* - Generating summaries via Gemini Flash
|
|
24
|
-
* - Generating embeddings via Gemini Embedding
|
|
25
|
-
* - Inserting indexed records
|
|
26
|
-
* - Keyword (FTS5), semantic (vec0 KNN), and hybrid search
|
|
27
|
-
* - Retrieval of key excerpts and original source file lines
|
|
28
|
-
*/
|
|
29
|
-
import { DatabaseSync } from "node:sqlite";
|
|
30
|
-
import fs from "node:fs";
|
|
31
|
-
import readline from "node:readline";
|
|
32
|
-
import { createGunzip } from "node:zlib";
|
|
33
|
-
import { pipeline } from "node:stream/promises";
|
|
34
|
-
import { PassThrough } from "node:stream";
|
|
35
|
-
import path from "node:path";
|
|
36
|
-
import { GoogleGenAI } from "@google/genai";
|
|
37
|
-
import * as sqliteVec from "sqlite-vec";
|
|
38
|
-
import { getConfigDir } from "../config/index.js";
|
|
39
|
-
import { resolveGeminiApiKey, GEMINI_SUMMARY_MODEL, GEMINI_EMBEDDING_MODEL, } from "../gemini-credentials.js";
|
|
40
|
-
import { logger } from "../logger.js";
|
|
41
|
-
import { getTranscriptParser, } from "./transcript-parsers/index.js";
|
|
42
|
-
function loadSqliteVec(db) {
|
|
43
|
-
const moduleValue = sqliteVec;
|
|
44
|
-
if (typeof moduleValue !== "object" ||
|
|
45
|
-
moduleValue === null ||
|
|
46
|
-
typeof moduleValue.load !== "function") {
|
|
47
|
-
throw new Error("sqlite-vec module did not expose a callable load() function");
|
|
48
|
-
}
|
|
49
|
-
moduleValue.load(db);
|
|
50
|
-
}
|
|
51
|
-
// ---------------------------------------------------------------------------
|
|
52
|
-
// DB singleton
|
|
53
|
-
// ---------------------------------------------------------------------------
|
|
54
|
-
let db = null;
|
|
55
|
-
let stmtInsert = null;
|
|
56
|
-
let stmtInsertVec = null;
|
|
57
|
-
let stmtSearchKeyword = null;
|
|
58
|
-
let stmtSearchSemantic = null;
|
|
59
|
-
let stmtGetById = null;
|
|
60
|
-
let stmtCountByPrefix = null;
|
|
61
|
-
let vecEnabled = false;
|
|
62
|
-
/** Embedding dimension for Gemini Embedding model */
|
|
63
|
-
const EMBEDDING_DIM = 768;
|
|
64
|
-
const EMBEDDING_BYTE_LENGTH = EMBEDDING_DIM * Float32Array.BYTES_PER_ELEMENT;
|
|
65
|
-
function requireStatement(stmt, name) {
|
|
66
|
-
if (!stmt) {
|
|
67
|
-
throw new Error(`Transcript memory statement not initialized: ${name}`);
|
|
68
|
-
}
|
|
69
|
-
return stmt;
|
|
70
|
-
}
|
|
71
|
-
function getDb() {
|
|
72
|
-
if (db)
|
|
73
|
-
return db;
|
|
74
|
-
const dbPath = path.join(getConfigDir(), "transcript-memory.db");
|
|
75
|
-
db = new DatabaseSync(dbPath, { allowExtension: true });
|
|
76
|
-
db.exec("PRAGMA journal_mode = WAL");
|
|
77
|
-
// Load sqlite-vec extension (best-effort — fall back to keyword-only)
|
|
78
|
-
try {
|
|
79
|
-
loadSqliteVec(db);
|
|
80
|
-
vecEnabled = true;
|
|
81
|
-
}
|
|
82
|
-
catch (err) {
|
|
83
|
-
logger.warn(`[transcript-indexer] sqlite-vec extension not loaded, semantic search disabled: ${err instanceof Error ? err.message : String(err)}`);
|
|
84
|
-
vecEnabled = false;
|
|
85
|
-
}
|
|
86
|
-
// Main table
|
|
87
|
-
db.exec(`
|
|
88
|
-
CREATE TABLE IF NOT EXISTS wake_cycles (
|
|
89
|
-
wake_cycle_id TEXT PRIMARY KEY,
|
|
90
|
-
session_type TEXT NOT NULL,
|
|
91
|
-
timestamp_start TEXT NOT NULL,
|
|
92
|
-
timestamp_end TEXT NOT NULL,
|
|
93
|
-
summary TEXT NOT NULL,
|
|
94
|
-
key_excerpts TEXT,
|
|
95
|
-
source_file TEXT NOT NULL,
|
|
96
|
-
start_line INTEGER NOT NULL,
|
|
97
|
-
end_line INTEGER NOT NULL,
|
|
98
|
-
embedding BLOB
|
|
99
|
-
)
|
|
100
|
-
`);
|
|
101
|
-
// Migration: rename old column `transcript_file` → `source_file`
|
|
102
|
-
// SQLite doesn't support RENAME COLUMN in all versions, but >=3.25.0 does.
|
|
103
|
-
// If the old column exists, rename it.
|
|
104
|
-
try {
|
|
105
|
-
const cols = db.prepare("PRAGMA table_info(wake_cycles)").all();
|
|
106
|
-
const hasOldCol = cols.some((c) => c.name === "transcript_file");
|
|
107
|
-
if (hasOldCol) {
|
|
108
|
-
db.exec("ALTER TABLE wake_cycles RENAME COLUMN transcript_file TO source_file");
|
|
109
|
-
logger.system("[transcript-indexer] Migrated column transcript_file → source_file");
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
catch {
|
|
113
|
-
// best-effort — old DBs without the column or already migrated
|
|
114
|
-
}
|
|
115
|
-
// FTS5 virtual table for keyword search.
|
|
116
|
-
// Using content= external-content mode with the main table.
|
|
117
|
-
db.exec(`
|
|
118
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS wake_cycles_fts USING fts5(
|
|
119
|
-
wake_cycle_id,
|
|
120
|
-
summary,
|
|
121
|
-
content=wake_cycles,
|
|
122
|
-
content_rowid=rowid
|
|
123
|
-
)
|
|
124
|
-
`);
|
|
125
|
-
// Triggers to keep FTS5 in sync with the main table
|
|
126
|
-
db.exec(`
|
|
127
|
-
CREATE TRIGGER IF NOT EXISTS wake_cycles_ai AFTER INSERT ON wake_cycles BEGIN
|
|
128
|
-
INSERT INTO wake_cycles_fts(rowid, wake_cycle_id, summary)
|
|
129
|
-
VALUES (new.rowid, new.wake_cycle_id, new.summary);
|
|
130
|
-
END
|
|
131
|
-
`);
|
|
132
|
-
db.exec(`
|
|
133
|
-
CREATE TRIGGER IF NOT EXISTS wake_cycles_ad AFTER DELETE ON wake_cycles BEGIN
|
|
134
|
-
INSERT INTO wake_cycles_fts(wake_cycles_fts, rowid, wake_cycle_id, summary)
|
|
135
|
-
VALUES ('delete', old.rowid, old.wake_cycle_id, old.summary);
|
|
136
|
-
END
|
|
137
|
-
`);
|
|
138
|
-
db.exec(`
|
|
139
|
-
CREATE TRIGGER IF NOT EXISTS wake_cycles_au AFTER UPDATE ON wake_cycles BEGIN
|
|
140
|
-
INSERT INTO wake_cycles_fts(wake_cycles_fts, rowid, wake_cycle_id, summary)
|
|
141
|
-
VALUES ('delete', old.rowid, old.wake_cycle_id, old.summary);
|
|
142
|
-
INSERT INTO wake_cycles_fts(rowid, wake_cycle_id, summary)
|
|
143
|
-
VALUES (new.rowid, new.wake_cycle_id, new.summary);
|
|
144
|
-
END
|
|
145
|
-
`);
|
|
146
|
-
// vec0 virtual table for vector similarity search (requires sqlite-vec)
|
|
147
|
-
if (vecEnabled) {
|
|
148
|
-
db.exec(`
|
|
149
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS wake_cycles_vec USING vec0(
|
|
150
|
-
wake_cycle_id TEXT PRIMARY KEY,
|
|
151
|
-
embedding float[${EMBEDDING_DIM}]
|
|
152
|
-
)
|
|
153
|
-
`);
|
|
154
|
-
stmtInsertVec = db.prepare(`
|
|
155
|
-
INSERT OR REPLACE INTO wake_cycles_vec (wake_cycle_id, embedding)
|
|
156
|
-
VALUES (?, ?)
|
|
157
|
-
`);
|
|
158
|
-
stmtSearchSemantic = db.prepare(`
|
|
159
|
-
SELECT
|
|
160
|
-
v.wake_cycle_id,
|
|
161
|
-
v.distance
|
|
162
|
-
FROM wake_cycles_vec v
|
|
163
|
-
WHERE v.embedding MATCH ?
|
|
164
|
-
AND k = ?
|
|
165
|
-
ORDER BY v.distance
|
|
166
|
-
`);
|
|
167
|
-
// One-time migration: sync existing embeddings from wake_cycles to vec0.
|
|
168
|
-
// Records inserted before sqlite-vec was available have embeddings in the
|
|
169
|
-
// main table but not in the vec0 table. This backfills them.
|
|
170
|
-
try {
|
|
171
|
-
const missingVec = db.prepare(`
|
|
172
|
-
SELECT wc.wake_cycle_id, wc.embedding
|
|
173
|
-
FROM wake_cycles wc
|
|
174
|
-
LEFT JOIN wake_cycles_vec v ON v.wake_cycle_id = wc.wake_cycle_id
|
|
175
|
-
WHERE wc.embedding IS NOT NULL AND v.wake_cycle_id IS NULL
|
|
176
|
-
`).all();
|
|
177
|
-
if (missingVec.length > 0) {
|
|
178
|
-
let skippedIncompatible = 0;
|
|
179
|
-
for (const row of missingVec) {
|
|
180
|
-
if (row.embedding.byteLength !== EMBEDDING_BYTE_LENGTH) {
|
|
181
|
-
skippedIncompatible += 1;
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
stmtInsertVec.run(row.wake_cycle_id, new Uint8Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength));
|
|
185
|
-
}
|
|
186
|
-
const syncedCount = missingVec.length - skippedIncompatible;
|
|
187
|
-
if (syncedCount > 0) {
|
|
188
|
-
logger.system(`[transcript-indexer] Synced ${syncedCount} embedding(s) to vec0 table`);
|
|
189
|
-
}
|
|
190
|
-
if (skippedIncompatible > 0) {
|
|
191
|
-
logger.warn(`[transcript-indexer] Skipped ${skippedIncompatible} incompatible embedding(s) during vec0 sync; they need re-embedding`);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
catch (syncErr) {
|
|
196
|
-
logger.warn(`[transcript-indexer] vec0 sync failed (non-fatal): ${syncErr instanceof Error ? syncErr.message : String(syncErr)}`);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
// Prepared statements
|
|
200
|
-
stmtInsert = db.prepare(`
|
|
201
|
-
INSERT OR REPLACE INTO wake_cycles
|
|
202
|
-
(wake_cycle_id, session_type, timestamp_start, timestamp_end,
|
|
203
|
-
summary, key_excerpts, source_file, start_line, end_line, embedding)
|
|
204
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
205
|
-
`);
|
|
206
|
-
stmtSearchKeyword = db.prepare(`
|
|
207
|
-
SELECT
|
|
208
|
-
wc.wake_cycle_id,
|
|
209
|
-
wc.session_type,
|
|
210
|
-
wc.timestamp_start,
|
|
211
|
-
wc.timestamp_end,
|
|
212
|
-
wc.summary,
|
|
213
|
-
bm25(wake_cycles_fts) AS relevance_score
|
|
214
|
-
FROM wake_cycles_fts fts
|
|
215
|
-
JOIN wake_cycles wc ON wc.rowid = fts.rowid
|
|
216
|
-
WHERE wake_cycles_fts MATCH ?
|
|
217
|
-
ORDER BY bm25(wake_cycles_fts)
|
|
218
|
-
LIMIT ?
|
|
219
|
-
`);
|
|
220
|
-
stmtGetById = db.prepare(`SELECT * FROM wake_cycles WHERE wake_cycle_id = ?`);
|
|
221
|
-
stmtCountByPrefix = db.prepare(`SELECT COUNT(*) as count FROM wake_cycles WHERE wake_cycle_id LIKE ? || '%'`);
|
|
222
|
-
return db;
|
|
223
|
-
}
|
|
224
|
-
// ---------------------------------------------------------------------------
|
|
225
|
-
// Wake cycle ID generation
|
|
226
|
-
// ---------------------------------------------------------------------------
|
|
227
|
-
function formatLocalDate(d) {
|
|
228
|
-
const year = d.getFullYear();
|
|
229
|
-
const month = String(d.getMonth() + 1).padStart(2, "0");
|
|
230
|
-
const day = String(d.getDate()).padStart(2, "0");
|
|
231
|
-
return `${year}-${month}-${day}`;
|
|
232
|
-
}
|
|
233
|
-
function generateWakeCycleId(sessionType) {
|
|
234
|
-
const date = formatLocalDate(new Date());
|
|
235
|
-
const prefix = `${date}_${sessionType}_`;
|
|
236
|
-
// Count existing entries for today + session type to generate a sequence number
|
|
237
|
-
getDb();
|
|
238
|
-
const countStmt = requireStatement(stmtCountByPrefix, "stmtCountByPrefix");
|
|
239
|
-
const row = countStmt.get(prefix);
|
|
240
|
-
const seq = (row?.count ?? 0) + 1;
|
|
241
|
-
return `${prefix}${String(seq).padStart(3, "0")}`;
|
|
242
|
-
}
|
|
243
|
-
// ---------------------------------------------------------------------------
|
|
244
|
-
// Source file reading (engine transcripts or VisionClaw logs)
|
|
245
|
-
// ---------------------------------------------------------------------------
|
|
246
|
-
/**
|
|
247
|
-
* Count lines in a file asynchronously via streaming.
|
|
248
|
-
* Returns 0 if the file does not exist.
|
|
249
|
-
*/
|
|
250
|
-
export async function countFileLines(filePath) {
|
|
251
|
-
if (!fs.existsSync(filePath))
|
|
252
|
-
return 0;
|
|
253
|
-
const inputStream = fs.createReadStream(filePath, { encoding: "utf-8" });
|
|
254
|
-
const rl = readline.createInterface({
|
|
255
|
-
input: inputStream,
|
|
256
|
-
crlfDelay: Infinity,
|
|
257
|
-
});
|
|
258
|
-
let count = 0;
|
|
259
|
-
for await (const _line of rl) {
|
|
260
|
-
count++;
|
|
261
|
-
}
|
|
262
|
-
return count;
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Read specific line range from a JSONL source file (engine transcript or
|
|
266
|
-
* VisionClaw log). Lines are 1-indexed; range is [startLine, endLine)
|
|
267
|
-
* (exclusive end). Handles both plain .jsonl and .jsonl.gz files via streaming.
|
|
268
|
-
*
|
|
269
|
-
* @param maxLines — optional cap on lines returned. When the range contains
|
|
270
|
-
* more lines than this limit, the function samples lines evenly across the
|
|
271
|
-
* range so the start, middle and end of the cycle are all represented.
|
|
272
|
-
*/
|
|
273
|
-
export async function readSourceFileLines(filePath, startLine, endLine, maxLines) {
|
|
274
|
-
// Try the exact path first, then .gz variant
|
|
275
|
-
let actualPath = filePath;
|
|
276
|
-
let isGz = false;
|
|
277
|
-
if (!fs.existsSync(actualPath)) {
|
|
278
|
-
const gzPath = `${actualPath}.gz`;
|
|
279
|
-
if (fs.existsSync(gzPath)) {
|
|
280
|
-
actualPath = gzPath;
|
|
281
|
-
isGz = true;
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
return [];
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
if (actualPath.endsWith(".gz")) {
|
|
288
|
-
isGz = true;
|
|
289
|
-
}
|
|
290
|
-
const lines = [];
|
|
291
|
-
let lineNum = 1;
|
|
292
|
-
let inputStream;
|
|
293
|
-
if (isGz) {
|
|
294
|
-
const fileStream = fs.createReadStream(actualPath);
|
|
295
|
-
const gunzip = createGunzip();
|
|
296
|
-
const passthrough = new PassThrough();
|
|
297
|
-
void pipeline(fileStream, gunzip, passthrough).catch(() => {
|
|
298
|
-
// Stream errors surface when readline tries to read
|
|
299
|
-
});
|
|
300
|
-
inputStream = passthrough;
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
inputStream = fs.createReadStream(actualPath, { encoding: "utf-8" });
|
|
304
|
-
}
|
|
305
|
-
const rl = readline.createInterface({
|
|
306
|
-
input: inputStream,
|
|
307
|
-
crlfDelay: Infinity,
|
|
308
|
-
});
|
|
309
|
-
for await (const line of rl) {
|
|
310
|
-
if (lineNum >= startLine && lineNum < endLine) {
|
|
311
|
-
lines.push(line);
|
|
312
|
-
}
|
|
313
|
-
if (lineNum >= endLine) {
|
|
314
|
-
rl.close();
|
|
315
|
-
break;
|
|
316
|
-
}
|
|
317
|
-
lineNum++;
|
|
318
|
-
}
|
|
319
|
-
// If maxLines is set and we have more lines than the limit, sample evenly.
|
|
320
|
-
// This keeps the start, middle, and end of the cycle represented so the
|
|
321
|
-
// summary captures the full arc of the wake cycle.
|
|
322
|
-
if (maxLines && maxLines > 0 && lines.length > maxLines) {
|
|
323
|
-
const sampled = [];
|
|
324
|
-
const step = lines.length / maxLines;
|
|
325
|
-
for (let i = 0; i < maxLines; i++) {
|
|
326
|
-
sampled.push(lines[Math.floor(i * step)]);
|
|
327
|
-
}
|
|
328
|
-
return sampled;
|
|
329
|
-
}
|
|
330
|
-
return lines;
|
|
331
|
-
}
|
|
332
|
-
// ---------------------------------------------------------------------------
|
|
333
|
-
// Transcript parsing / filtering for summary generation
|
|
334
|
-
// ---------------------------------------------------------------------------
|
|
335
|
-
//
|
|
336
|
-
// Format-specific JSONL parsing lives in `./transcript-parsers/`. The wake
|
|
337
|
-
// cycle indexer dispatches to the right parser via `getTranscriptParser`.
|
|
338
|
-
// The helpers below are kept as Claude-format-specific public exports for
|
|
339
|
-
// tests and any caller that only consumes Claude SDK transcripts; new code
|
|
340
|
-
// that handles multiple formats should call `getTranscriptParser(kind)`
|
|
341
|
-
// directly.
|
|
342
|
-
/**
|
|
343
|
-
* Parse raw JSONL lines from a Claude SDK transcript file into a condensed
|
|
344
|
-
* text representation suitable for summary generation. Thin wrapper around
|
|
345
|
-
* the registered Claude parser.
|
|
346
|
-
*/
|
|
347
|
-
export function parseTranscriptForSummary(lines) {
|
|
348
|
-
return getTranscriptParser("claude").parseForSummary(lines);
|
|
349
|
-
}
|
|
350
|
-
/** Backward-compat wrapper around the Claude parser. */
|
|
351
|
-
export function isOnlyTrivialToolCalls(lines) {
|
|
352
|
-
return getTranscriptParser("claude").isOnlyTrivialToolCalls(lines);
|
|
353
|
-
}
|
|
354
|
-
// ---------------------------------------------------------------------------
|
|
355
|
-
// Summary generation via Gemini
|
|
356
|
-
// ---------------------------------------------------------------------------
|
|
357
|
-
const SUMMARY_PROMPT = `You are analyzing a transcript of an AI agent's wake cycle. Generate a structured summary.
|
|
358
|
-
|
|
359
|
-
Instructions:
|
|
360
|
-
- Focus on: what task was performed, key decisions made, user interactions, and outcomes
|
|
361
|
-
- For "summary": write a detailed paragraph (200-400 words) covering the main activities and results
|
|
362
|
-
- For "key_excerpts": extract 3-8 verbatim quotes from the transcript that capture the most important information (user requests, key decisions, important results)
|
|
363
|
-
- Omit routine/trivial details (heartbeat checks with no action, viewing memory with no changes)
|
|
364
|
-
|
|
365
|
-
Respond with valid JSON only, no markdown fences:
|
|
366
|
-
{"summary": "...", "key_excerpts": ["...", "..."]}
|
|
367
|
-
|
|
368
|
-
TRANSCRIPT:
|
|
369
|
-
`;
|
|
370
|
-
export async function generateSummary(condensedTranscript, config) {
|
|
371
|
-
const apiKey = resolveGeminiApiKey(config);
|
|
372
|
-
const ai = new GoogleGenAI({ apiKey });
|
|
373
|
-
const maxInputChars = 30_000;
|
|
374
|
-
const truncatedInput = condensedTranscript.length > maxInputChars
|
|
375
|
-
? condensedTranscript.slice(0, maxInputChars) +
|
|
376
|
-
"\n...[transcript truncated]"
|
|
377
|
-
: condensedTranscript;
|
|
378
|
-
const response = await ai.models.generateContent({
|
|
379
|
-
model: GEMINI_SUMMARY_MODEL,
|
|
380
|
-
contents: SUMMARY_PROMPT + truncatedInput,
|
|
381
|
-
});
|
|
382
|
-
const text = response.text ?? "";
|
|
383
|
-
const jsonMatch = /\{[\s\S]*\}/.exec(text);
|
|
384
|
-
if (!jsonMatch) {
|
|
385
|
-
return { summary: text.slice(0, 2000), key_excerpts: [] };
|
|
386
|
-
}
|
|
387
|
-
try {
|
|
388
|
-
const parsed = JSON.parse(jsonMatch[0]);
|
|
389
|
-
return {
|
|
390
|
-
summary: parsed.summary ?? text.slice(0, 2000),
|
|
391
|
-
key_excerpts: Array.isArray(parsed.key_excerpts)
|
|
392
|
-
? parsed.key_excerpts
|
|
393
|
-
: [],
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
catch {
|
|
397
|
-
return { summary: text.slice(0, 2000), key_excerpts: [] };
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
// ---------------------------------------------------------------------------
|
|
401
|
-
// Embedding generation via Gemini
|
|
402
|
-
// ---------------------------------------------------------------------------
|
|
403
|
-
export async function generateEmbedding(text, config) {
|
|
404
|
-
try {
|
|
405
|
-
const apiKey = resolveGeminiApiKey(config);
|
|
406
|
-
const ai = new GoogleGenAI({ apiKey });
|
|
407
|
-
const result = await ai.models.embedContent({
|
|
408
|
-
model: GEMINI_EMBEDDING_MODEL,
|
|
409
|
-
contents: text,
|
|
410
|
-
config: { outputDimensionality: EMBEDDING_DIM },
|
|
411
|
-
});
|
|
412
|
-
const values = result.embeddings?.[0]?.values;
|
|
413
|
-
if (!values || values.length === 0)
|
|
414
|
-
return null;
|
|
415
|
-
if (values.length !== EMBEDDING_DIM) {
|
|
416
|
-
throw new Error(`Unexpected embedding dimension: got ${values.length}, expected ${EMBEDDING_DIM}`);
|
|
417
|
-
}
|
|
418
|
-
return new Float32Array(values);
|
|
419
|
-
}
|
|
420
|
-
catch (err) {
|
|
421
|
-
logger.warn(`[transcript-indexer] Embedding generation failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
422
|
-
return null;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
// ---------------------------------------------------------------------------
|
|
426
|
-
// Public API: index a wake cycle
|
|
427
|
-
// ---------------------------------------------------------------------------
|
|
428
|
-
/** Max lines to read from a transcript for summarization.
|
|
429
|
-
* Prevents excessive memory usage on very long wake cycles. */
|
|
430
|
-
const MAX_LINES_FOR_SUMMARY = 2_000;
|
|
431
|
-
/**
|
|
432
|
-
* Index the current wake cycle's engine transcript. Called after each wake
|
|
433
|
-
* cycle completes (fire-and-forget from the main loop).
|
|
434
|
-
*
|
|
435
|
-
* Steps:
|
|
436
|
-
* 1. Read transcript lines for the wake cycle range (capped)
|
|
437
|
-
* 2. Parse and condense with the source-format-specific parser
|
|
438
|
-
* 3. Call Gemini Flash to generate summary + key excerpts
|
|
439
|
-
* 4. Generate embedding for the summary (best-effort)
|
|
440
|
-
* 5. Store in SQLite (wake_cycles + FTS5 auto-synced via triggers)
|
|
441
|
-
*/
|
|
442
|
-
export async function indexWakeCycle(options) {
|
|
443
|
-
const { sessionType, sourceFile, sourceFormat = "claude", startLine, endLine, timestampStart, timestampEnd, trigger, messages, config, } = options;
|
|
444
|
-
// Skip trivial wake cycles
|
|
445
|
-
const lineCount = endLine - startLine;
|
|
446
|
-
if (trigger === "heartbeat" && messages.length === 0 && lineCount < 10) {
|
|
447
|
-
logger.debug("[transcript-indexer] Skipping trivial heartbeat wake cycle");
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
450
|
-
if (lineCount <= 0) {
|
|
451
|
-
logger.debug("[transcript-indexer] Skipping empty wake cycle (no new lines)");
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
const parser = getTranscriptParser(sourceFormat);
|
|
455
|
-
// Step 1: Read transcript lines (capped at MAX_LINES_FOR_SUMMARY to avoid
|
|
456
|
-
// loading a huge file into memory for very long wake cycles).
|
|
457
|
-
const lines = await readSourceFileLines(sourceFile, startLine, endLine, MAX_LINES_FOR_SUMMARY);
|
|
458
|
-
if (lines.length === 0) {
|
|
459
|
-
logger.debug("[transcript-indexer] No source file lines read, skipping");
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
// Step 1.5: Skip cycles that only contain trivial/housekeeping tool calls
|
|
463
|
-
if (parser.isOnlyTrivialToolCalls(lines)) {
|
|
464
|
-
logger.debug(`[transcript-indexer] Skipping wake cycle with only trivial tool calls (format=${sourceFormat})`);
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
// Step 2: Parse and condense using the format-specific parser
|
|
468
|
-
const condensed = parser.parseForSummary(lines);
|
|
469
|
-
if (condensed.length < 50) {
|
|
470
|
-
logger.debug(`[transcript-indexer] Condensed text too short, skipping (format=${sourceFormat})`);
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
// Step 3: Generate summary via Gemini Flash
|
|
474
|
-
const { summary, key_excerpts } = await generateSummary(condensed, config);
|
|
475
|
-
// Step 4: Generate embedding (best-effort, non-blocking failure)
|
|
476
|
-
const embeddingVec = await generateEmbedding(summary, config);
|
|
477
|
-
const embeddingBlob = embeddingVec
|
|
478
|
-
? Buffer.from(embeddingVec.buffer, embeddingVec.byteOffset, embeddingVec.byteLength)
|
|
479
|
-
: null;
|
|
480
|
-
// Step 5: Store in SQLite
|
|
481
|
-
const wakeCycleId = generateWakeCycleId(sessionType);
|
|
482
|
-
getDb();
|
|
483
|
-
const insertStmt = requireStatement(stmtInsert, "stmtInsert");
|
|
484
|
-
insertStmt.run(wakeCycleId, sessionType, timestampStart, timestampEnd, summary, key_excerpts.length > 0 ? JSON.stringify(key_excerpts) : null, sourceFile, startLine, endLine, embeddingBlob);
|
|
485
|
-
// Also insert into vec0 table for semantic search
|
|
486
|
-
if (vecEnabled && stmtInsertVec && embeddingBlob) {
|
|
487
|
-
try {
|
|
488
|
-
stmtInsertVec.run(wakeCycleId, new Uint8Array(embeddingBlob.buffer, embeddingBlob.byteOffset, embeddingBlob.byteLength));
|
|
489
|
-
}
|
|
490
|
-
catch (vecErr) {
|
|
491
|
-
logger.warn(`[transcript-indexer] vec0 insert failed (non-fatal): ${vecErr instanceof Error ? vecErr.message : String(vecErr)}`);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
logger.system(`[transcript-indexer] Indexed wake cycle ${wakeCycleId}: ${lines.length} lines → ${summary.length} char summary`);
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* Insert a pre-built wake cycle record into the database.
|
|
498
|
-
* Used by the backfill CLI to insert records with known timestamps and IDs.
|
|
499
|
-
*
|
|
500
|
-
* @param record.sourceFile — path to the source JSONL file. For backfilled
|
|
501
|
-
* data this is a VisionClaw runtime log file; for live data it is a Claude
|
|
502
|
-
* SDK transcript file.
|
|
503
|
-
*/
|
|
504
|
-
export function insertWakeCycleRecord(record) {
|
|
505
|
-
getDb();
|
|
506
|
-
const insertStmt = requireStatement(stmtInsert, "stmtInsert");
|
|
507
|
-
insertStmt.run(record.wakeCycleId, record.sessionType, record.timestampStart, record.timestampEnd, record.summary, record.keyExcerpts && record.keyExcerpts.length > 0
|
|
508
|
-
? JSON.stringify(record.keyExcerpts)
|
|
509
|
-
: null, record.sourceFile, record.startLine, record.endLine, record.embeddingBlob);
|
|
510
|
-
// Also insert into vec0 table for semantic search
|
|
511
|
-
if (vecEnabled && stmtInsertVec && record.embeddingBlob) {
|
|
512
|
-
try {
|
|
513
|
-
const blob = record.embeddingBlob;
|
|
514
|
-
stmtInsertVec.run(record.wakeCycleId, new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength));
|
|
515
|
-
}
|
|
516
|
-
catch {
|
|
517
|
-
// best-effort — vec insert failure is non-fatal
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
/**
|
|
522
|
-
* Return the total number of wake cycles in the database.
|
|
523
|
-
*/
|
|
524
|
-
export function getWakeCycleCount() {
|
|
525
|
-
const dbInstance = getDb();
|
|
526
|
-
const row = dbInstance.prepare("SELECT COUNT(*) as count FROM wake_cycles").get();
|
|
527
|
-
return row?.count ?? 0;
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
* Check if a wake cycle ID already exists in the database.
|
|
531
|
-
*/
|
|
532
|
-
export function wakeCycleExists(wakeCycleId) {
|
|
533
|
-
getDb();
|
|
534
|
-
const getByIdStmt = requireStatement(stmtGetById, "stmtGetById");
|
|
535
|
-
const row = getByIdStmt.get(wakeCycleId);
|
|
536
|
-
return row !== undefined;
|
|
537
|
-
}
|
|
538
|
-
/**
|
|
539
|
-
* Check whether semantic/vector search is available.
|
|
540
|
-
*/
|
|
541
|
-
export function isSemanticSearchAvailable() {
|
|
542
|
-
getDb();
|
|
543
|
-
return vecEnabled;
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Search wake cycle summaries. Routes to keyword, semantic, or hybrid
|
|
547
|
-
* search based on the `type` option.
|
|
548
|
-
*
|
|
549
|
-
* - keyword: FTS5 full-text search with BM25 ranking (default)
|
|
550
|
-
* - semantic: vec0 KNN search using embedding similarity
|
|
551
|
-
* - hybrid: combines keyword + semantic via Reciprocal Rank Fusion (RRF)
|
|
552
|
-
*/
|
|
553
|
-
export function searchWakeCycles(options) {
|
|
554
|
-
const { type = "keyword" } = options;
|
|
555
|
-
// Fall back to keyword if semantic search is unavailable
|
|
556
|
-
if ((type === "semantic" || type === "hybrid") && !vecEnabled) {
|
|
557
|
-
logger.debug("[transcript-indexer] Semantic search requested but sqlite-vec not loaded, falling back to keyword");
|
|
558
|
-
return searchKeyword(options);
|
|
559
|
-
}
|
|
560
|
-
switch (type) {
|
|
561
|
-
case "semantic":
|
|
562
|
-
return searchSemantic(options);
|
|
563
|
-
case "hybrid":
|
|
564
|
-
return searchHybrid(options);
|
|
565
|
-
default:
|
|
566
|
-
return searchKeyword(options);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
/**
|
|
570
|
-
* FTS5 keyword search with BM25 ranking.
|
|
571
|
-
*/
|
|
572
|
-
function searchKeyword(options) {
|
|
573
|
-
const { query, timeRange, sessionType, limit = 5 } = options;
|
|
574
|
-
getDb();
|
|
575
|
-
// Sanitize the query for FTS5: wrap words in quotes and join with OR
|
|
576
|
-
const sanitized = query
|
|
577
|
-
.split(/\s+/)
|
|
578
|
-
.filter((w) => w.length > 0)
|
|
579
|
-
.map((w) => `"${w.replace(/"/g, "")}"`)
|
|
580
|
-
.join(" OR ");
|
|
581
|
-
if (!sanitized)
|
|
582
|
-
return [];
|
|
583
|
-
// Fetch more than `limit` to allow post-filtering
|
|
584
|
-
const fetchLimit = timeRange ?? sessionType ? limit * 3 : limit;
|
|
585
|
-
const keywordStmt = requireStatement(stmtSearchKeyword, "stmtSearchKeyword");
|
|
586
|
-
const rows = keywordStmt.all(sanitized, fetchLimit);
|
|
587
|
-
// Normalize BM25 scores: raw BM25 is negative (lower = better).
|
|
588
|
-
// Convert to positive 0-1 range where higher = more relevant.
|
|
589
|
-
const normalized = rows.map((r) => ({
|
|
590
|
-
...r,
|
|
591
|
-
relevance_score: normalizeBm25Score(r.relevance_score),
|
|
592
|
-
}));
|
|
593
|
-
return applyFilters(normalized, timeRange, sessionType, limit);
|
|
594
|
-
}
|
|
595
|
-
/**
|
|
596
|
-
* Semantic search requires async embedding generation.
|
|
597
|
-
* This sync stub falls back to keyword — use searchSemanticAsync() instead.
|
|
598
|
-
*/
|
|
599
|
-
function searchSemantic(options) {
|
|
600
|
-
// Semantic search requires async embedding generation;
|
|
601
|
-
// MCP tools call searchSemanticAsync() directly.
|
|
602
|
-
return searchKeyword(options);
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* Async semantic search — generates query embedding then searches vec0.
|
|
606
|
-
*/
|
|
607
|
-
export async function searchSemanticAsync(options) {
|
|
608
|
-
const { query, timeRange, sessionType, limit = 5, config } = options;
|
|
609
|
-
if (!vecEnabled || !stmtSearchSemantic || !config) {
|
|
610
|
-
return searchKeyword(options);
|
|
611
|
-
}
|
|
612
|
-
getDb();
|
|
613
|
-
// Generate embedding for the query
|
|
614
|
-
const queryEmbedding = await generateEmbedding(query, config);
|
|
615
|
-
if (!queryEmbedding) {
|
|
616
|
-
logger.debug("[transcript-indexer] Query embedding generation failed, falling back to keyword");
|
|
617
|
-
return searchKeyword(options);
|
|
618
|
-
}
|
|
619
|
-
// KNN search via vec0
|
|
620
|
-
const queryBlob = new Uint8Array(queryEmbedding.buffer, queryEmbedding.byteOffset, queryEmbedding.byteLength);
|
|
621
|
-
const fetchLimit = timeRange ?? sessionType ? limit * 3 : limit;
|
|
622
|
-
const vecRows = stmtSearchSemantic.all(queryBlob, fetchLimit);
|
|
623
|
-
// Hydrate with full metadata from the main table
|
|
624
|
-
const results = [];
|
|
625
|
-
const getByIdStmt = requireStatement(stmtGetById, "stmtGetById");
|
|
626
|
-
for (const vecRow of vecRows) {
|
|
627
|
-
const row = getByIdStmt.get(vecRow.wake_cycle_id);
|
|
628
|
-
if (row) {
|
|
629
|
-
results.push({
|
|
630
|
-
wake_cycle_id: row.wake_cycle_id,
|
|
631
|
-
session_type: row.session_type,
|
|
632
|
-
timestamp_start: row.timestamp_start,
|
|
633
|
-
timestamp_end: row.timestamp_end,
|
|
634
|
-
summary: row.summary,
|
|
635
|
-
// Normalize distance to 0-1 range: 1/(1+distance).
|
|
636
|
-
// Lower distance = higher score = more relevant.
|
|
637
|
-
relevance_score: 1 / (1 + vecRow.distance),
|
|
638
|
-
});
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
return applyFilters(results, timeRange, sessionType, limit);
|
|
642
|
-
}
|
|
643
|
-
/**
|
|
644
|
-
* Async hybrid search — runs keyword + semantic in parallel, fuses with RRF.
|
|
645
|
-
* Reciprocal Rank Fusion: score = Σ 1/(k + rank_i) for each result system.
|
|
646
|
-
*/
|
|
647
|
-
export async function searchHybridAsync(options) {
|
|
648
|
-
const { limit = 5 } = options;
|
|
649
|
-
// Run both searches — keyword is synchronous, semantic is async
|
|
650
|
-
const keywordResults = searchKeyword({ ...options, limit: limit * 2 });
|
|
651
|
-
const semanticResults = await searchSemanticAsync({
|
|
652
|
-
...options,
|
|
653
|
-
limit: limit * 2,
|
|
654
|
-
});
|
|
655
|
-
return fuseWithRRF(keywordResults, semanticResults, limit);
|
|
656
|
-
}
|
|
657
|
-
/**
|
|
658
|
-
* Reciprocal Rank Fusion (RRF) to merge results from multiple search systems.
|
|
659
|
-
* k=60 is the standard RRF constant.
|
|
660
|
-
*/
|
|
661
|
-
function fuseWithRRF(keywordResults, semanticResults, limit, k = 60) {
|
|
662
|
-
const scoreMap = new Map();
|
|
663
|
-
const recordMap = new Map();
|
|
664
|
-
// Score from keyword results
|
|
665
|
-
for (let rank = 0; rank < keywordResults.length; rank++) {
|
|
666
|
-
const r = keywordResults[rank];
|
|
667
|
-
const rrfScore = 1 / (k + rank + 1);
|
|
668
|
-
scoreMap.set(r.wake_cycle_id, (scoreMap.get(r.wake_cycle_id) ?? 0) + rrfScore);
|
|
669
|
-
recordMap.set(r.wake_cycle_id, r);
|
|
670
|
-
}
|
|
671
|
-
// Score from semantic results
|
|
672
|
-
for (let rank = 0; rank < semanticResults.length; rank++) {
|
|
673
|
-
const r = semanticResults[rank];
|
|
674
|
-
const rrfScore = 1 / (k + rank + 1);
|
|
675
|
-
scoreMap.set(r.wake_cycle_id, (scoreMap.get(r.wake_cycle_id) ?? 0) + rrfScore);
|
|
676
|
-
if (!recordMap.has(r.wake_cycle_id)) {
|
|
677
|
-
recordMap.set(r.wake_cycle_id, r);
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
// Sort by fused score (descending) and take top `limit`
|
|
681
|
-
const fused = [...scoreMap.entries()]
|
|
682
|
-
.sort((a, b) => b[1] - a[1])
|
|
683
|
-
.slice(0, limit)
|
|
684
|
-
.map(([id, score]) => {
|
|
685
|
-
const record = recordMap.get(id);
|
|
686
|
-
if (!record) {
|
|
687
|
-
throw new Error(`Missing fused record for wake cycle ${id}`);
|
|
688
|
-
}
|
|
689
|
-
return { ...record, relevance_score: score };
|
|
690
|
-
});
|
|
691
|
-
return fused;
|
|
692
|
-
}
|
|
693
|
-
/**
|
|
694
|
-
* Stub for synchronous hybrid — delegates to keyword (the async version
|
|
695
|
-
* is called from the MCP tool layer).
|
|
696
|
-
*/
|
|
697
|
-
function searchHybrid(options) {
|
|
698
|
-
// Hybrid requires async embedding generation; this sync fallback
|
|
699
|
-
// returns keyword results. The MCP tool uses searchHybridAsync().
|
|
700
|
-
return searchKeyword(options);
|
|
701
|
-
}
|
|
702
|
-
/**
|
|
703
|
-
* Apply time range, session type filters and limit to search results.
|
|
704
|
-
*/
|
|
705
|
-
function applyFilters(results, timeRange, sessionType, limit) {
|
|
706
|
-
let filtered = results;
|
|
707
|
-
if (timeRange) {
|
|
708
|
-
filtered = filtered.filter((r) => r.timestamp_start >= timeRange.start &&
|
|
709
|
-
r.timestamp_end <= timeRange.end);
|
|
710
|
-
}
|
|
711
|
-
if (sessionType) {
|
|
712
|
-
filtered = filtered.filter((r) => r.session_type === sessionType);
|
|
713
|
-
}
|
|
714
|
-
return filtered.slice(0, limit);
|
|
715
|
-
}
|
|
716
|
-
/**
|
|
717
|
-
* Normalize BM25 scores (which are negative, lower = better) to positive
|
|
718
|
-
* scores where higher = better. Uses: score = 1 / (1 + |bm25|).
|
|
719
|
-
* This gives a 0-1 range suitable for display.
|
|
720
|
-
*/
|
|
721
|
-
export function normalizeBm25Score(bm25) {
|
|
722
|
-
return 1 / (1 + Math.abs(bm25));
|
|
723
|
-
}
|
|
724
|
-
// ---------------------------------------------------------------------------
|
|
725
|
-
// Public API: get details
|
|
726
|
-
// ---------------------------------------------------------------------------
|
|
727
|
-
/**
|
|
728
|
-
* Get the key_excerpts for a specific wake cycle.
|
|
729
|
-
*/
|
|
730
|
-
export function getWakeCycleExcerpts(wakeCycleId) {
|
|
731
|
-
getDb();
|
|
732
|
-
const getByIdStmt = requireStatement(stmtGetById, "stmtGetById");
|
|
733
|
-
const row = getByIdStmt.get(wakeCycleId);
|
|
734
|
-
if (!row)
|
|
735
|
-
return null;
|
|
736
|
-
return row.key_excerpts;
|
|
737
|
-
}
|
|
738
|
-
/**
|
|
739
|
-
* Get the full original source content for a specific wake cycle.
|
|
740
|
-
* Reads from the source file (Claude transcript or VisionClaw log),
|
|
741
|
-
* decompressing .gz if needed. No line limit is applied here so the
|
|
742
|
-
* agent can access the complete original data when needed.
|
|
743
|
-
*/
|
|
744
|
-
export async function getWakeCycleFullTranscript(wakeCycleId) {
|
|
745
|
-
getDb();
|
|
746
|
-
const getByIdStmt = requireStatement(stmtGetById, "stmtGetById");
|
|
747
|
-
const row = getByIdStmt.get(wakeCycleId);
|
|
748
|
-
if (!row)
|
|
749
|
-
return null;
|
|
750
|
-
const lines = await readSourceFileLines(row.source_file, row.start_line, row.end_line);
|
|
751
|
-
if (lines.length === 0) {
|
|
752
|
-
return "[Source file no longer available. The summary and key excerpts above are the only preserved content.]";
|
|
753
|
-
}
|
|
754
|
-
return lines.join("\n");
|
|
755
|
-
}
|
|
756
|
-
// ---------------------------------------------------------------------------
|
|
757
|
-
// Cleanup
|
|
758
|
-
// ---------------------------------------------------------------------------
|
|
759
|
-
/**
|
|
760
|
-
* Close the database connection. Call during graceful shutdown.
|
|
761
|
-
*/
|
|
762
|
-
export function closeTranscriptMemoryDb() {
|
|
763
|
-
if (db) {
|
|
764
|
-
db.close();
|
|
765
|
-
db = null;
|
|
766
|
-
stmtInsert = null;
|
|
767
|
-
stmtInsertVec = null;
|
|
768
|
-
stmtSearchKeyword = null;
|
|
769
|
-
stmtSearchSemantic = null;
|
|
770
|
-
stmtGetById = null;
|
|
771
|
-
stmtCountByPrefix = null;
|
|
772
|
-
vecEnabled = false;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
//# sourceMappingURL=transcript-indexer.js.map
|