@xopcai/xopc 0.0.93 → 0.0.94
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/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/agents-OqhbJkMf.js +222 -0
- package/dist/gateway/static/root/assets/apps-page-OHXW9XP8.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-4N2R-jof.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-CsGkK9h9.js → channels-status-swr-Bv6f9kDq.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-api-CyAm0xJT.js → cron-api-BtaQaHJq.js} +1 -1
- package/dist/gateway/static/root/assets/cron-page-Dah32HJK.js +1 -0
- package/dist/gateway/static/root/assets/{dist-DHwVV8XK.js → dist-BJfD9Qvs.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BK8kcc4F.js → extension-debug-page-DnYuMzmH.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-Cf8X_QUc.js → extension-page-CJfc-6XV.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-C5-YLMmy.js → extension-settings-page-BxdfYQMG.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-BAPnkYbC.js → fetch-B0aeeY0q.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-8p7ucXa1.js → field-primitives-DOLHwowi.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-CpgW2sGp.js → heartbeat-config-api-Bj2INAf5.js} +1 -1
- package/dist/gateway/static/root/assets/index-Bj_l8QDp.css +1 -0
- package/dist/gateway/static/root/assets/{index-Do52EfZK.js → index-DuQ1XPoA.js} +99 -98
- package/dist/gateway/static/root/assets/logs-page-AsOgLNJE.js +2 -0
- package/dist/gateway/static/root/assets/{note-detail-page-WLM6FUIi.js → note-detail-page-24J4mVP-.js} +3 -3
- package/dist/gateway/static/root/assets/{note-time-EFyIVhec.js → note-time-JBszYV3s.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-BYPVYcYn.js → notes-page-BApAirFB.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DX9huWsA.js +1 -0
- package/dist/gateway/static/root/assets/{settings-advanced-gate-CEs8pGh6.js → settings-advanced-gate-DWvhsTuz.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-C6cGTVwK.js → settings-form-section-CxMjaMiy.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-4VmUTzQs.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-tnIfJ4K6.js → share-preview-page-IX0TJvRd.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-CGKGKfwe.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-D6EsNTPr.js → theme-store-Cg_SuBw0.js} +1 -1
- package/dist/gateway/static/root/assets/{url-CTjpm0Uz.js → url-BHHmdJYc.js} +2 -2
- package/dist/gateway/static/root/assets/{utils-C86AVfY-.js → utils-BmlcxR2j.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-DaGm2N4J.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-page.utils-DsEriMFW.js → workflow-page.utils-D0vsIGHD.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-BFCrD3nw.js +27 -0
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +7 -7
- package/dist/src/agent/agent-scope.js +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.js +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +3 -0
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.js +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +2 -2
- package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +18 -5
- package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +11 -4
- package/dist/src/agent/mcp/mcp-transport-config.js.map +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +2 -2
- package/dist/src/agent/mcp/mcp-transport.js.map +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +1 -0
- package/dist/src/agent/service/process-direct-streaming.js +15 -12
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service.d.ts +4 -2
- package/dist/src/agent/service.js +24 -8
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +3 -1
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/search/registry.js +1 -1
- package/dist/src/agent/tools/search/registry.js.map +1 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/session-search-tool.js +1 -1
- package/dist/src/agent/tools/session-search-tool.js.map +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.js +2 -2
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workflow/progress-broker.js +1 -1
- package/dist/src/agent/workflow/progress-broker.js.map +1 -1
- package/dist/src/agent/workflow/subagent-runner.js +1 -1
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/auth/credentials.js +3 -3
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +3 -3
- package/dist/src/browser/providers/cloakbrowser.js +4 -4
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/channels/pipeline.js +3 -2
- package/dist/src/channels/pipeline.js.map +1 -1
- package/dist/src/chat-commands/agent-edit.js +2 -2
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/cli-log-level-preset.d.ts +1 -1
- package/dist/src/cli/cli-log-level-preset.js +2 -2
- package/dist/src/cli/cli-log-level-preset.js.map +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +2 -2
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/image.js +1 -1
- package/dist/src/cli/commands/init.js +4 -4
- package/dist/src/cli/commands/logs.js +3 -3
- package/dist/src/cli/commands/logs.js.map +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/commands/agents.config.js +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/executor.js +9 -6
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/agents-admin.js +3 -3
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/app.js +4 -1
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/route-logger.d.ts +6 -0
- package/dist/src/gateway/hono/lib/route-logger.js +31 -0
- package/dist/src/gateway/hono/lib/route-logger.js.map +1 -0
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/middleware/auth.js +16 -3
- package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
- package/dist/src/gateway/hono/middleware/logger.js +1 -1
- package/dist/src/gateway/hono/middleware/logger.js.map +1 -1
- package/dist/src/gateway/hono/middleware/route-errors.d.ts +5 -0
- package/dist/src/gateway/hono/middleware/route-errors.js +27 -0
- package/dist/src/gateway/hono/middleware/route-errors.js.map +1 -0
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/agent-stream.js +6 -0
- package/dist/src/gateway/hono/routes/agent-stream.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/browser-install.js +2 -4
- package/dist/src/gateway/hono/routes/browser-install.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/config.js +25 -11
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/cron.js +5 -0
- package/dist/src/gateway/hono/routes/cron.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +4 -6
- package/dist/src/gateway/hono/routes/host-fs.js.map +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +14 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/lazy-fallback.js +3 -0
- package/dist/src/gateway/hono/routes/lazy-fallback.js.map +1 -1
- package/dist/src/gateway/hono/routes/logs.js +39 -7
- package/dist/src/gateway/hono/routes/logs.js.map +1 -1
- package/dist/src/gateway/hono/routes/mcp.d.ts +3 -0
- package/dist/src/gateway/hono/routes/mcp.js +107 -0
- package/dist/src/gateway/hono/routes/mcp.js.map +1 -0
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +6 -0
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/update.js +2 -4
- package/dist/src/gateway/hono/routes/update.js.map +1 -1
- package/dist/src/gateway/hono/routes/voice.js +2 -4
- package/dist/src/gateway/hono/routes/voice.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +4 -6
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/hono/sse.js +9 -2
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/service/agent-runner.js +3 -3
- package/dist/src/gateway/service/agent-runner.js.map +1 -1
- package/dist/src/gateway/service/config-coordinator.js +14 -6
- package/dist/src/gateway/service/config-coordinator.js.map +1 -1
- package/dist/src/gateway/service/marketplace-service.js +3 -3
- package/dist/src/gateway/service/marketplace-service.js.map +1 -1
- package/dist/src/gateway/service/run-gateway-agent.js +22 -5
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sse-hub.js +1 -1
- package/dist/src/gateway/service/sse-hub.js.map +1 -1
- package/dist/src/gateway/service.js +13 -6
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/brew.js +1 -1
- package/dist/src/infra/package-json.js +1 -1
- package/dist/src/infra/package-update-steps.js +1 -1
- package/dist/src/infra/path-env.js +2 -2
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/stable-node-path.js +1 -1
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/mcp/channel-bridge.js +26 -2
- package/dist/src/mcp/channel-bridge.js.map +1 -1
- package/dist/src/mcp/gateway-http-client.js +24 -2
- package/dist/src/mcp/gateway-http-client.js.map +1 -1
- package/dist/src/notes/store.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/session/config-store.js +12 -6
- package/dist/src/session/config-store.js.map +1 -1
- package/dist/src/session/index.d.ts +1 -1
- package/dist/src/session/index.js +2 -2
- package/dist/src/session/init-session-turn.js +2 -2
- package/dist/src/session/manager.js +8 -1
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +1 -1
- package/dist/src/session/resolve-session.js +4 -4
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.d.ts +19 -3
- package/dist/src/session/session-title.js +84 -9
- package/dist/src/session/session-title.js.map +1 -1
- package/dist/src/session/store.js +6 -6
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui.js +3 -3
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/index.js +4 -4
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/config.js +2 -6
- package/dist/src/utils/logger/config.js.map +1 -1
- package/dist/src/utils/logger/context.d.ts +3 -22
- package/dist/src/utils/logger/context.js +4 -32
- package/dist/src/utils/logger/context.js.map +1 -1
- package/dist/src/utils/logger/index.d.ts +4 -7
- package/dist/src/utils/logger/index.js +9 -28
- package/dist/src/utils/logger/index.js.map +1 -1
- package/dist/src/utils/logger/log-store.d.ts +14 -32
- package/dist/src/utils/logger/log-store.js +68 -119
- package/dist/src/utils/logger/log-store.js.map +1 -1
- package/dist/src/utils/logger/log-stream.d.ts +5 -70
- package/dist/src/utils/logger/log-stream.js +67 -178
- package/dist/src/utils/logger/log-stream.js.map +1 -1
- package/dist/src/utils/logger/pino-record.d.ts +8 -0
- package/dist/src/utils/logger/pino-record.js +83 -0
- package/dist/src/utils/logger/pino-record.js.map +1 -0
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/logger/stats.d.ts +1 -1
- package/dist/src/utils/logger/stats.js +2 -2
- package/dist/src/utils/logger/stats.js.map +1 -1
- package/dist/src/utils/logger/streams.js +18 -0
- package/dist/src/utils/logger/streams.js.map +1 -1
- package/dist/src/utils/logger/types.d.ts +0 -9
- package/dist/src/utils/logger/types.js.map +1 -1
- package/dist/src/utils/logger.js +4 -4
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/store/event-store.js +1 -1
- package/dist/src/workflows/store/run-store.js +1 -1
- package/package.json +2 -1
- package/dist/gateway/static/root/assets/agents-C7tTJLP9.js +0 -222
- package/dist/gateway/static/root/assets/apps-page-BbzdMyrg.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-B49vG2hE.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-Bjx7IOdR.js +0 -1
- package/dist/gateway/static/root/assets/index-CwDdudZM.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-BxukQ-J-.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BFD2_-Cl.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-BiP5iH46.js +0 -2
- package/dist/gateway/static/root/assets/skills-page-CNDctFIn.js +0 -2
- package/dist/gateway/static/root/assets/voice-api-key-field-CalxUkxm.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-D2fRxXJG.js +0 -27
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
-
import { init_logger } from "../utils/logger.js";
|
|
3
1
|
import { isCronSessionKey } from "../routing/session-key-utils.js";
|
|
4
2
|
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
3
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
4
|
+
import { init_logger } from "../utils/logger.js";
|
|
5
5
|
import { init_providers, resolveModel } from "../providers/index.js";
|
|
6
6
|
import { readAgentMessageContent } from "../agent/memory/agent-message-access.js";
|
|
7
7
|
import { stripSessionStartupContextFromUserText } from "../agent/reply/startup-context.js";
|
|
@@ -63,6 +63,19 @@ function sanitizeSessionTitle(raw) {
|
|
|
63
63
|
if (s.length > MAX_TITLE_LEN) s = s.slice(0, MAX_TITLE_LEN - 1).trimEnd() + "…";
|
|
64
64
|
return s;
|
|
65
65
|
}
|
|
66
|
+
function getSessionTitleSource(meta) {
|
|
67
|
+
const raw = meta?.customData?.titleSource;
|
|
68
|
+
if (raw === "provisional" || raw === "llm" || raw === "user") return raw;
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
/** Title from a single user message (first line), for immediate sidebar labels. */
|
|
72
|
+
function provisionalTitleFromUserText(raw) {
|
|
73
|
+
const text = stripInboundFileMetadataFromText(stripEnvelopeTimestampPrefix(stripSessionStartupContextFromUserText((raw ?? "").trim())));
|
|
74
|
+
if (!text) return null;
|
|
75
|
+
const line = text.split(/\n/)[0]?.trim();
|
|
76
|
+
if (!line) return null;
|
|
77
|
+
return sanitizeSessionTitle(line);
|
|
78
|
+
}
|
|
66
79
|
/** Non-LLM title: first line of first user text, else first assistant line. */
|
|
67
80
|
function fallbackTitleFromMessages(messages) {
|
|
68
81
|
const u = firstUserText(messages);
|
|
@@ -130,11 +143,56 @@ Title:`,
|
|
|
130
143
|
return null;
|
|
131
144
|
}
|
|
132
145
|
}
|
|
146
|
+
/** Whether post-turn LLM refine may run (provisional or still unnamed; not user-locked). */
|
|
147
|
+
function shouldRefineSessionTitleWithLlm(meta) {
|
|
148
|
+
if (!meta) return false;
|
|
149
|
+
const source = getSessionTitleSource(meta);
|
|
150
|
+
if (source === "user") return false;
|
|
151
|
+
if (meta.name?.trim()) return source === "provisional";
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
function canAutoWriteTitle(meta) {
|
|
155
|
+
if (!meta) return false;
|
|
156
|
+
if (getSessionTitleSource(meta) === "user") return false;
|
|
157
|
+
return !meta.name?.trim();
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Set provisional title from first user text when session is still unnamed.
|
|
161
|
+
* Skips cron/heartbeat keys and user-locked titles.
|
|
162
|
+
*/
|
|
163
|
+
async function maybeSetProvisionalSessionTitle(sessionStore, sessionKey, userText, onUpdated) {
|
|
164
|
+
if (!shouldAutoTitleSessionKey(sessionKey)) return;
|
|
165
|
+
let meta = await sessionStore.getMetadata(sessionKey);
|
|
166
|
+
if (!meta) return;
|
|
167
|
+
if (!canAutoWriteTitle(meta)) return;
|
|
168
|
+
let title = null;
|
|
169
|
+
if (userText?.trim()) title = provisionalTitleFromUserText(userText);
|
|
170
|
+
if (!title) {
|
|
171
|
+
const messages = await sessionStore.load(sessionKey);
|
|
172
|
+
if (!messages.length) return;
|
|
173
|
+
title = fallbackTitleFromMessages(messages);
|
|
174
|
+
}
|
|
175
|
+
if (!title) return;
|
|
176
|
+
try {
|
|
177
|
+
await sessionStore.updateMetadata(sessionKey, {
|
|
178
|
+
name: title,
|
|
179
|
+
customData: {
|
|
180
|
+
...meta.customData ?? {},
|
|
181
|
+
titleSource: "provisional"
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
await onUpdated?.(sessionKey, title);
|
|
185
|
+
} catch (err) {
|
|
186
|
+
log.warn({
|
|
187
|
+
err,
|
|
188
|
+
sessionKey
|
|
189
|
+
}, "Session title: provisional updateMetadata failed");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
133
192
|
/**
|
|
134
|
-
*
|
|
135
|
-
* Skips cron/heartbeat keys. Ensures index row exists by re-saving when metadata is missing (fixes index lag).
|
|
193
|
+
* LLM refine when title is empty or still provisional (not user-locked).
|
|
136
194
|
*/
|
|
137
|
-
async function
|
|
195
|
+
async function maybeRefineSessionTitleWithLlm(sessionStore, sessionKey, modelRef, onUpdated) {
|
|
138
196
|
if (!shouldAutoTitleSessionKey(sessionKey)) return;
|
|
139
197
|
let messages = await sessionStore.load(sessionKey);
|
|
140
198
|
if (!messages.length) return;
|
|
@@ -147,7 +205,8 @@ async function maybeAutoTitleSessionStore(sessionStore, sessionKey, modelRef) {
|
|
|
147
205
|
log.warn({ sessionKey }, "Session title: metadata missing after save");
|
|
148
206
|
return;
|
|
149
207
|
}
|
|
150
|
-
if (meta
|
|
208
|
+
if (!shouldRefineSessionTitleWithLlm(meta)) return;
|
|
209
|
+
const source = getSessionTitleSource(meta);
|
|
151
210
|
let title = null;
|
|
152
211
|
const ref = modelRef?.trim();
|
|
153
212
|
if (ref) {
|
|
@@ -161,16 +220,32 @@ async function maybeAutoTitleSessionStore(sessionStore, sessionKey, modelRef) {
|
|
|
161
220
|
}
|
|
162
221
|
if (!title) title = fallbackTitleFromMessages(messages);
|
|
163
222
|
if (!title) return;
|
|
223
|
+
if (meta.name?.trim() === title) {
|
|
224
|
+
if (source !== "llm") try {
|
|
225
|
+
await sessionStore.updateMetadata(sessionKey, { customData: {
|
|
226
|
+
...meta.customData ?? {},
|
|
227
|
+
titleSource: "llm"
|
|
228
|
+
} });
|
|
229
|
+
} catch {}
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
164
232
|
try {
|
|
165
|
-
await sessionStore.updateMetadata(sessionKey, {
|
|
233
|
+
await sessionStore.updateMetadata(sessionKey, {
|
|
234
|
+
name: title,
|
|
235
|
+
customData: {
|
|
236
|
+
...meta.customData ?? {},
|
|
237
|
+
titleSource: "llm"
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
await onUpdated?.(sessionKey, title);
|
|
166
241
|
} catch (err) {
|
|
167
242
|
log.warn({
|
|
168
243
|
err,
|
|
169
244
|
sessionKey
|
|
170
|
-
}, "Session title: updateMetadata failed");
|
|
245
|
+
}, "Session title: refine updateMetadata failed");
|
|
171
246
|
}
|
|
172
247
|
}
|
|
173
248
|
//#endregion
|
|
174
|
-
export { fallbackTitleFromMessages, generateSessionTitleFromMessages, isWebchatSessionKey,
|
|
249
|
+
export { fallbackTitleFromMessages, generateSessionTitleFromMessages, getSessionTitleSource, isWebchatSessionKey, maybeRefineSessionTitleWithLlm, maybeSetProvisionalSessionTitle, provisionalTitleFromUserText, sanitizeSessionTitle, shouldAutoTitleSessionKey, shouldRefineSessionTitleWithLlm };
|
|
175
250
|
|
|
176
251
|
//# sourceMappingURL=session-title.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-title.js","names":[],"sources":["../../../src/session/session-title.ts"],"sourcesContent":["/**\n * LLM-generated session titles (webchat and any path using SessionStore).\n */\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport { complete, type UserMessage } from '@earendil-works/pi-ai';\n\nimport { stripSessionStartupContextFromUserText } from '../agent/reply/startup-context.js';\nimport { stripInboundFileMetadataFromText } from '../channels/attachments/inbound-persist.js';\nimport { stripEnvelopeTimestampPrefix } from '../channels/envelope-timestamp.js';\nimport { isCronSessionKey, parseSessionKey } from '../routing/session-key.js';\nimport { resolveModel } from '../providers/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { readAgentMessageContent } from '../agent/memory/agent-message-access.js';\nimport type { SessionStore } from './store.js';\n\nconst log = createLogger('SessionAutoTitle');\n\nconst MAX_TITLE_LEN = 80;\n\n/** Collect visible text from any content block that exposes `text` (pi-ai / OpenAI / Anthropic shapes). */\nfunction extractTextFromMessage(m: AgentMessage): string {\n const raw = readAgentMessageContent(m);\n if (typeof raw === 'string') return raw.trim();\n if (Array.isArray(raw)) {\n const parts: string[] = [];\n for (const c of raw) {\n if (c && typeof c === 'object') {\n const o = c as unknown as Record<string, unknown>;\n const type = typeof o.type === 'string' ? o.type : '';\n if (type === 'toolCall' || type === 'tool_use' || type === 'tool_result') continue;\n if (typeof o.text === 'string' && o.text.trim()) {\n parts.push(o.text.trim());\n }\n }\n }\n return parts.join(' ').trim();\n }\n return '';\n}\n\nfunction firstUserText(messages: AgentMessage[]): string {\n const u = messages.find((m) => m.role === 'user');\n if (!u) return '';\n const raw = extractTextFromMessage(u);\n // User turns include `formatInboundFileTextBlock` text blocks; do not feed [File:…] into title LLM / fallback.\n // Inbound pipeline / webchat prepends `[YYYY-MM-DD HH:MM TZ]`; strip so titles are not timestamp-led.\n return stripInboundFileMetadataFromText(\n stripEnvelopeTimestampPrefix(stripSessionStartupContextFromUserText(raw)),\n );\n}\n\n/** First assistant message that has visible text (skips tool-only assistant rows). */\nfunction firstAssistantText(messages: AgentMessage[]): string {\n for (const m of messages) {\n if (m.role === 'assistant') {\n const t = extractTextFromMessage(m);\n if (t.length > 0) return t;\n }\n }\n return '';\n}\n\nexport function isWebchatSessionKey(sessionKey: string): boolean {\n const p = parseSessionKey(sessionKey);\n if (p?.source === 'webchat') return true;\n return sessionKey.includes(':webchat:');\n}\n\n/** Whether to run LLM/fallback session naming for this key (excludes cron, heartbeat). */\nexport function shouldAutoTitleSessionKey(sessionKey: string): boolean {\n const raw = (sessionKey ?? '').trim();\n if (!raw) return false;\n if (isCronSessionKey(raw)) return false;\n if (raw.toLowerCase().startsWith('heartbeat:')) return false;\n return true;\n}\n\nexport function sanitizeSessionTitle(raw: string): string {\n let s = raw.trim();\n if ((s.startsWith('\"') && s.endsWith('\"')) || (s.startsWith(\"'\") && s.endsWith(\"'\"))) {\n s = s.slice(1, -1).trim();\n }\n const lineBreak = s.indexOf('\\n');\n if (lineBreak !== -1) s = s.slice(0, lineBreak).trim();\n if (s.length > MAX_TITLE_LEN) s = s.slice(0, MAX_TITLE_LEN - 1).trimEnd() + '…';\n return s;\n}\n\n/** Non-LLM title: first line of first user text, else first assistant line. */\nexport function fallbackTitleFromMessages(messages: AgentMessage[]): string | null {\n const u = firstUserText(messages);\n if (u) {\n const line = u.split(/\\n/)[0]?.trim();\n if (line) return sanitizeSessionTitle(line);\n }\n const a = firstAssistantText(messages);\n if (a) {\n const line = a.split(/\\n/)[0]?.trim();\n if (line) return sanitizeSessionTitle(line);\n }\n return null;\n}\n\n/**\n * Returns a title string, or null if generation should be skipped or failed.\n */\nexport async function generateSessionTitleFromMessages(\n modelRef: string,\n messages: AgentMessage[],\n signal?: AbortSignal,\n): Promise<string | null> {\n const userText = firstUserText(messages);\n const assistantText = firstAssistantText(messages);\n if (!userText && !assistantText) return null;\n\n let model: ReturnType<typeof resolveModel>;\n try {\n model = resolveModel(modelRef);\n } catch (err) {\n log.warn({ err, modelRef }, 'Cannot resolve model for session title');\n return null;\n }\n\n const prompt =\n userText && assistantText\n ? `You label chat sessions. Given the first user message and the start of the assistant reply, output ONE short title (max 8 words). No quotes. No punctuation at the end. Use the same language as the user when possible.\n\nUser: ${userText.slice(0, 2000)}\n\nAssistant: ${assistantText.slice(0, 2000)}\n\nTitle:`\n : userText\n ? `The assistant reply only used tools (no visible text yet). Output ONE short title (max 8 words) based only on the user's first message. No quotes. No punctuation at the end. Use the same language as the user.\n\nUser: ${userText.slice(0, 2000)}\n\nTitle:`\n : `Output ONE short title (max 8 words) for this assistant reply. No quotes. No punctuation at the end.\n\nAssistant: ${assistantText!.slice(0, 2000)}\n\nTitle:`;\n\n const userMsg: UserMessage = { role: 'user', content: prompt, timestamp: Date.now() };\n\n try {\n const result = await complete(\n model,\n { messages: [userMsg] },\n {\n maxTokens: 64,\n temperature: 0.35,\n signal: signal as AbortSignal,\n },\n );\n\n let text = '';\n if (Array.isArray(result.content)) {\n for (const c of result.content) {\n if (c && typeof c === 'object' && (c as { type?: string }).type === 'text') {\n text += String((c as { text?: string }).text || '');\n }\n }\n }\n\n const cleaned = sanitizeSessionTitle(text);\n return cleaned.length > 0 ? cleaned : null;\n } catch (err) {\n log.warn({ err }, 'Session title LLM call failed');\n return null;\n }\n}\n\n/**\n * If the session is still unnamed, set `name` (LLM when possible, else first-line fallback).\n * Skips cron/heartbeat keys. Ensures index row exists by re-saving when metadata is missing (fixes index lag).\n */\nexport async function maybeAutoTitleSessionStore(\n sessionStore: SessionStore,\n sessionKey: string,\n modelRef: string | undefined,\n): Promise<void> {\n if (!shouldAutoTitleSessionKey(sessionKey)) return;\n\n let messages = await sessionStore.load(sessionKey);\n if (!messages.length) return;\n\n let meta = await sessionStore.getMetadata(sessionKey);\n if (!meta) {\n await sessionStore.saveMessages(sessionKey, messages);\n meta = await sessionStore.getMetadata(sessionKey);\n }\n if (!meta) {\n log.warn({ sessionKey }, 'Session title: metadata missing after save');\n return;\n }\n if (meta.name && meta.name.trim().length > 0) return;\n\n let title: string | null = null;\n const ref = modelRef?.trim();\n if (ref) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 25_000);\n try {\n title = await generateSessionTitleFromMessages(ref, messages, controller.signal);\n } finally {\n clearTimeout(timeout);\n }\n }\n if (!title) {\n title = fallbackTitleFromMessages(messages);\n }\n if (!title) return;\n\n try {\n await sessionStore.updateMetadata(sessionKey, { name: title });\n } catch (err) {\n log.warn({ err, sessionKey }, 'Session title: updateMetadata failed');\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session-title.js","names":[],"sources":["../../../src/session/session-title.ts"],"sourcesContent":["/**\n * LLM-generated session titles (webchat and any path using SessionStore).\n */\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport { complete, type UserMessage } from '@earendil-works/pi-ai';\n\nimport { stripSessionStartupContextFromUserText } from '../agent/reply/startup-context.js';\nimport { stripInboundFileMetadataFromText } from '../channels/attachments/inbound-persist.js';\nimport { stripEnvelopeTimestampPrefix } from '../channels/envelope-timestamp.js';\nimport { isCronSessionKey, parseSessionKey } from '../routing/session-key.js';\nimport { resolveModel } from '../providers/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { readAgentMessageContent } from '../agent/memory/agent-message-access.js';\nimport type { SessionStore } from './store.js';\n\nconst log = createLogger('SessionAutoTitle');\n\nconst MAX_TITLE_LEN = 80;\n\n/** Collect visible text from any content block that exposes `text` (pi-ai / OpenAI / Anthropic shapes). */\nfunction extractTextFromMessage(m: AgentMessage): string {\n const raw = readAgentMessageContent(m);\n if (typeof raw === 'string') return raw.trim();\n if (Array.isArray(raw)) {\n const parts: string[] = [];\n for (const c of raw) {\n if (c && typeof c === 'object') {\n const o = c as unknown as Record<string, unknown>;\n const type = typeof o.type === 'string' ? o.type : '';\n if (type === 'toolCall' || type === 'tool_use' || type === 'tool_result') continue;\n if (typeof o.text === 'string' && o.text.trim()) {\n parts.push(o.text.trim());\n }\n }\n }\n return parts.join(' ').trim();\n }\n return '';\n}\n\nfunction firstUserText(messages: AgentMessage[]): string {\n const u = messages.find((m) => m.role === 'user');\n if (!u) return '';\n const raw = extractTextFromMessage(u);\n // User turns include `formatInboundFileTextBlock` text blocks; do not feed [File:…] into title LLM / fallback.\n // Inbound pipeline / webchat prepends `[YYYY-MM-DD HH:MM TZ]`; strip so titles are not timestamp-led.\n return stripInboundFileMetadataFromText(\n stripEnvelopeTimestampPrefix(stripSessionStartupContextFromUserText(raw)),\n );\n}\n\n/** First assistant message that has visible text (skips tool-only assistant rows). */\nfunction firstAssistantText(messages: AgentMessage[]): string {\n for (const m of messages) {\n if (m.role === 'assistant') {\n const t = extractTextFromMessage(m);\n if (t.length > 0) return t;\n }\n }\n return '';\n}\n\nexport function isWebchatSessionKey(sessionKey: string): boolean {\n const p = parseSessionKey(sessionKey);\n if (p?.source === 'webchat') return true;\n return sessionKey.includes(':webchat:');\n}\n\n/** Whether to run LLM/fallback session naming for this key (excludes cron, heartbeat). */\nexport function shouldAutoTitleSessionKey(sessionKey: string): boolean {\n const raw = (sessionKey ?? '').trim();\n if (!raw) return false;\n if (isCronSessionKey(raw)) return false;\n if (raw.toLowerCase().startsWith('heartbeat:')) return false;\n return true;\n}\n\nexport function sanitizeSessionTitle(raw: string): string {\n let s = raw.trim();\n if ((s.startsWith('\"') && s.endsWith('\"')) || (s.startsWith(\"'\") && s.endsWith(\"'\"))) {\n s = s.slice(1, -1).trim();\n }\n const lineBreak = s.indexOf('\\n');\n if (lineBreak !== -1) s = s.slice(0, lineBreak).trim();\n if (s.length > MAX_TITLE_LEN) s = s.slice(0, MAX_TITLE_LEN - 1).trimEnd() + '…';\n return s;\n}\n\nexport type SessionTitleSource = 'provisional' | 'llm' | 'user';\n\nexport function getSessionTitleSource(\n meta: { customData?: Record<string, unknown> } | null | undefined,\n): SessionTitleSource | null {\n const raw = meta?.customData?.titleSource;\n if (raw === 'provisional' || raw === 'llm' || raw === 'user') return raw;\n return null;\n}\n\n/** Title from a single user message (first line), for immediate sidebar labels. */\nexport function provisionalTitleFromUserText(raw: string): string | null {\n const text = stripInboundFileMetadataFromText(\n stripEnvelopeTimestampPrefix(stripSessionStartupContextFromUserText((raw ?? '').trim())),\n );\n if (!text) return null;\n const line = text.split(/\\n/)[0]?.trim();\n if (!line) return null;\n return sanitizeSessionTitle(line);\n}\n\n/** Non-LLM title: first line of first user text, else first assistant line. */\nexport function fallbackTitleFromMessages(messages: AgentMessage[]): string | null {\n const u = firstUserText(messages);\n if (u) {\n const line = u.split(/\\n/)[0]?.trim();\n if (line) return sanitizeSessionTitle(line);\n }\n const a = firstAssistantText(messages);\n if (a) {\n const line = a.split(/\\n/)[0]?.trim();\n if (line) return sanitizeSessionTitle(line);\n }\n return null;\n}\n\n/**\n * Returns a title string, or null if generation should be skipped or failed.\n */\nexport async function generateSessionTitleFromMessages(\n modelRef: string,\n messages: AgentMessage[],\n signal?: AbortSignal,\n): Promise<string | null> {\n const userText = firstUserText(messages);\n const assistantText = firstAssistantText(messages);\n if (!userText && !assistantText) return null;\n\n let model: ReturnType<typeof resolveModel>;\n try {\n model = resolveModel(modelRef);\n } catch (err) {\n log.warn({ err, modelRef }, 'Cannot resolve model for session title');\n return null;\n }\n\n const prompt =\n userText && assistantText\n ? `You label chat sessions. Given the first user message and the start of the assistant reply, output ONE short title (max 8 words). No quotes. No punctuation at the end. Use the same language as the user when possible.\n\nUser: ${userText.slice(0, 2000)}\n\nAssistant: ${assistantText.slice(0, 2000)}\n\nTitle:`\n : userText\n ? `The assistant reply only used tools (no visible text yet). Output ONE short title (max 8 words) based only on the user's first message. No quotes. No punctuation at the end. Use the same language as the user.\n\nUser: ${userText.slice(0, 2000)}\n\nTitle:`\n : `Output ONE short title (max 8 words) for this assistant reply. No quotes. No punctuation at the end.\n\nAssistant: ${assistantText!.slice(0, 2000)}\n\nTitle:`;\n\n const userMsg: UserMessage = { role: 'user', content: prompt, timestamp: Date.now() };\n\n try {\n const result = await complete(\n model,\n { messages: [userMsg] },\n {\n maxTokens: 64,\n temperature: 0.35,\n signal: signal as AbortSignal,\n },\n );\n\n let text = '';\n if (Array.isArray(result.content)) {\n for (const c of result.content) {\n if (c && typeof c === 'object' && (c as { type?: string }).type === 'text') {\n text += String((c as { text?: string }).text || '');\n }\n }\n }\n\n const cleaned = sanitizeSessionTitle(text);\n return cleaned.length > 0 ? cleaned : null;\n } catch (err) {\n log.warn({ err }, 'Session title LLM call failed');\n return null;\n }\n}\n\nexport type SessionTitleUpdatedHook = (sessionKey: string, name: string) => void | Promise<void>;\n\n/** Whether post-turn LLM refine may run (provisional or still unnamed; not user-locked). */\nexport function shouldRefineSessionTitleWithLlm(\n meta: { name?: string; customData?: Record<string, unknown> } | null | undefined,\n): boolean {\n if (!meta) return false;\n const source = getSessionTitleSource(meta);\n if (source === 'user') return false;\n if (meta.name?.trim()) return source === 'provisional';\n return true;\n}\n\nfunction canAutoWriteTitle(meta: { name?: string; customData?: Record<string, unknown> } | null): boolean {\n if (!meta) return false;\n const source = getSessionTitleSource(meta);\n if (source === 'user') return false;\n return !meta.name?.trim();\n}\n\n/**\n * Set provisional title from first user text when session is still unnamed.\n * Skips cron/heartbeat keys and user-locked titles.\n */\nexport async function maybeSetProvisionalSessionTitle(\n sessionStore: SessionStore,\n sessionKey: string,\n userText?: string,\n onUpdated?: SessionTitleUpdatedHook,\n): Promise<void> {\n if (!shouldAutoTitleSessionKey(sessionKey)) return;\n\n let meta = await sessionStore.getMetadata(sessionKey);\n if (!meta) return;\n if (!canAutoWriteTitle(meta)) return;\n\n let title: string | null = null;\n if (userText?.trim()) {\n title = provisionalTitleFromUserText(userText);\n }\n if (!title) {\n const messages = await sessionStore.load(sessionKey);\n if (!messages.length) return;\n title = fallbackTitleFromMessages(messages);\n }\n if (!title) return;\n\n try {\n await sessionStore.updateMetadata(sessionKey, {\n name: title,\n customData: { ...(meta.customData ?? {}), titleSource: 'provisional' },\n });\n await onUpdated?.(sessionKey, title);\n } catch (err) {\n log.warn({ err, sessionKey }, 'Session title: provisional updateMetadata failed');\n }\n}\n\n/**\n * LLM refine when title is empty or still provisional (not user-locked).\n */\nexport async function maybeRefineSessionTitleWithLlm(\n sessionStore: SessionStore,\n sessionKey: string,\n modelRef: string | undefined,\n onUpdated?: SessionTitleUpdatedHook,\n): Promise<void> {\n if (!shouldAutoTitleSessionKey(sessionKey)) return;\n\n let messages = await sessionStore.load(sessionKey);\n if (!messages.length) return;\n\n let meta = await sessionStore.getMetadata(sessionKey);\n if (!meta) {\n await sessionStore.saveMessages(sessionKey, messages);\n meta = await sessionStore.getMetadata(sessionKey);\n }\n if (!meta) {\n log.warn({ sessionKey }, 'Session title: metadata missing after save');\n return;\n }\n if (!shouldRefineSessionTitleWithLlm(meta)) return;\n\n const source = getSessionTitleSource(meta);\n let title: string | null = null;\n const ref = modelRef?.trim();\n if (ref) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 25_000);\n try {\n title = await generateSessionTitleFromMessages(ref, messages, controller.signal);\n } finally {\n clearTimeout(timeout);\n }\n }\n if (!title) {\n title = fallbackTitleFromMessages(messages);\n }\n if (!title) return;\n\n const existing = meta.name?.trim();\n if (existing === title) {\n if (source !== 'llm') {\n try {\n await sessionStore.updateMetadata(sessionKey, {\n customData: { ...(meta.customData ?? {}), titleSource: 'llm' },\n });\n } catch {\n /* ignore */\n }\n }\n return;\n }\n\n try {\n await sessionStore.updateMetadata(sessionKey, {\n name: title,\n customData: { ...(meta.customData ?? {}), titleSource: 'llm' },\n });\n await onUpdated?.(sessionKey, title);\n } catch (err) {\n log.warn({ err, sessionKey }, 'Session title: refine updateMetadata failed');\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
-
import { init_logger } from "../utils/logger.js";
|
|
3
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
4
2
|
import { init_agent_scope, listAgentEntries, resolveDefaultAgentId } from "../agent/agent-scope.js";
|
|
3
|
+
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
4
|
+
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
5
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
6
|
+
import { init_logger } from "../utils/logger.js";
|
|
5
7
|
import { init_artifacts, parseCompactionCheckpointTranscriptFileName } from "./parity/artifacts.js";
|
|
6
8
|
import { init_session_id, validateSessionId } from "./parity/session-id.js";
|
|
7
9
|
import { archiveFileOnDisk, init_transcript_paths, resolveSessionFilePath, resolveSessionTranscriptPathInDir } from "./parity/transcript-paths.js";
|
|
8
10
|
import { FILENAMES, init_paths, resolveSessionsDir } from "../config/paths.js";
|
|
9
|
-
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
10
|
-
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
11
11
|
import { loadEntriesFromFile } from "./parity/load-jsonl-entries.js";
|
|
12
12
|
import { mergeLlmMessagesPreservingContextRows } from "./session-context-for-llm.js";
|
|
13
13
|
import { appendPiTranscriptContextEntry, persistMergedTranscriptRows, readTranscriptRowsFromFile, rowsToLlmMessages, writeTranscriptJsonl } from "./parity/jsonl-transcript-io.js";
|
|
@@ -20,10 +20,10 @@ import "./types.js";
|
|
|
20
20
|
import { readSessionsJsonFile, withSessionsJsonLock } from "./parity/sessions-json-file.js";
|
|
21
21
|
import { buildSessionsJsonStatsPatch, incrementSessionsJsonStatsForAppend, isAppendOnlyLlmTranscriptMessage, patchSessionsJsonEntryStats } from "./parity/sessions-json-patch.js";
|
|
22
22
|
import { countTranscriptMessageRows, readDisplayMessagePageFromTranscriptFile } from "./parity/transcript-pagination.js";
|
|
23
|
-
import { copyFile, mkdir, readdir, stat, unlink } from "fs/promises";
|
|
24
|
-
import { randomUUID } from "node:crypto";
|
|
25
23
|
import { join } from "path";
|
|
26
24
|
import { existsSync } from "fs";
|
|
25
|
+
import { copyFile, mkdir, readdir, stat, unlink } from "fs/promises";
|
|
26
|
+
import { randomUUID } from "node:crypto";
|
|
27
27
|
import { performance } from "node:perf_hooks";
|
|
28
28
|
//#region src/session/store.ts
|
|
29
29
|
init_paths();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { resolveMimeType } from "./share-store.js";
|
|
2
|
-
import {
|
|
2
|
+
import { basename, join, resolve } from "node:path";
|
|
3
3
|
import { readdirSync } from "node:fs";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
4
5
|
import { copyFile, mkdir, rm, stat } from "node:fs/promises";
|
|
5
|
-
import { basename, join, resolve } from "node:path";
|
|
6
6
|
//#region src/share/share-auto.ts
|
|
7
7
|
/**
|
|
8
8
|
* Smart-share decision layer.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
+
import { resolveStateDir } from "../config/paths-state.js";
|
|
1
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { resolveStateDir } from "../config/paths-state.js";
|
|
4
4
|
import { init_paths } from "../config/paths.js";
|
|
5
5
|
import { SHARE_CONFIG_DEFAULTS } from "./share-types.js";
|
|
6
6
|
import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
|
|
7
7
|
import { logShareAudit } from "./share-audit.js";
|
|
8
|
-
import {
|
|
8
|
+
import { join, relative, resolve } from "node:path";
|
|
9
9
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
10
11
|
import { lstat, readdir, realpath, stat } from "node:fs/promises";
|
|
11
|
-
import { join, relative, resolve } from "node:path";
|
|
12
12
|
//#region src/share/share-store.ts
|
|
13
13
|
init_paths();
|
|
14
14
|
init_logger();
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { resolveStateDir } from "../config/paths-state.js";
|
|
1
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { resolveStateDir } from "../config/paths-state.js";
|
|
4
4
|
import { init_paths } from "../config/paths.js";
|
|
5
5
|
import { getShareStore } from "./share-store.js";
|
|
6
6
|
import { getSiteShareStore } from "./site-share-store.js";
|
|
7
7
|
import { loadPlaywrightCoreModule } from "../browser/providers/playwright-doctor.js";
|
|
8
|
-
import { mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
|
|
9
8
|
import { join } from "node:path";
|
|
9
|
+
import { mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
|
|
10
10
|
//#region src/share/share-thumbnail.ts
|
|
11
11
|
/**
|
|
12
12
|
* Thumbnail generator for shares.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
|
|
2
|
+
import { relative, resolve } from "node:path";
|
|
2
3
|
import { createReadStream } from "node:fs";
|
|
3
4
|
import { lstat, readdir, realpath, stat } from "node:fs/promises";
|
|
4
|
-
import { relative, resolve } from "node:path";
|
|
5
5
|
import { Readable, Transform } from "node:stream";
|
|
6
6
|
import { pipeline } from "node:stream/promises";
|
|
7
7
|
import { crc32, createDeflateRaw } from "node:zlib";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { resolveStateDir } from "../config/paths-state.js";
|
|
1
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
3
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { resolveStateDir } from "../config/paths-state.js";
|
|
4
4
|
import { init_paths } from "../config/paths.js";
|
|
5
5
|
import { SITE_SHARE_CONFIG_DEFAULTS } from "./site-share-types.js";
|
|
6
6
|
import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
|
|
7
|
-
import {
|
|
7
|
+
import { join, relative, resolve } from "node:path";
|
|
8
8
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
9
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
9
10
|
import { lstat, readdir, realpath, stat } from "node:fs/promises";
|
|
10
|
-
import { join, relative, resolve } from "node:path";
|
|
11
11
|
//#region src/share/site-share-store.ts
|
|
12
12
|
init_paths();
|
|
13
13
|
init_logger();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
|
|
2
2
|
import { resolveMimeType, shareResponseContentType } from "./share-store.js";
|
|
3
|
+
import { join, relative, resolve } from "node:path";
|
|
3
4
|
import { createReadStream } from "node:fs";
|
|
4
5
|
import { readFile, stat } from "node:fs/promises";
|
|
5
|
-
import { join, relative, resolve } from "node:path";
|
|
6
6
|
import { Readable } from "node:stream";
|
|
7
7
|
//#region src/share/site-static-serve.ts
|
|
8
8
|
const HASHED_ASSET_RE = /\.[a-f0-9]{8,}\.(?:js|mjs|css|woff2?|ttf|otf|svg|png|jpg|jpeg|gif|webp|avif|ico)$/i;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { join } from "node:path";
|
|
4
1
|
import { tmpdir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { spawnSync } from "node:child_process";
|
|
6
6
|
//#region src/tui/clipboard-image.ts
|
|
7
7
|
const SUPPORTED_IMAGE_MIME_TYPES = [
|
|
@@ -2,8 +2,8 @@ import { resolveStateDir } from "../config/paths-state.js";
|
|
|
2
2
|
import { init_paths } from "../config/paths.js";
|
|
3
3
|
import { palette } from "./theme/dark.js";
|
|
4
4
|
import { palette as palette$1 } from "./theme/light.js";
|
|
5
|
-
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
6
5
|
import { join } from "node:path";
|
|
6
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
//#region src/tui/theme-manager.ts
|
|
9
9
|
init_paths();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
2
|
import { init_paths } from "../config/paths.js";
|
|
3
3
|
import { XOPC_TUI_KEYBINDINGS } from "./xopc-tui-keybindings.js";
|
|
4
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
5
4
|
import { join } from "node:path";
|
|
5
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
6
6
|
import { KeybindingsManager } from "@earendil-works/pi-tui";
|
|
7
7
|
//#region src/tui/tui-keybindings-file.ts
|
|
8
8
|
init_paths();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
1
|
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
//#region src/tui/tui-scoped-models.ts
|
|
5
5
|
const STORE_PATH = join(homedir(), ".xopc", "tui-scoped-models.json");
|
|
6
6
|
function normalizeWorkspaceKey(cwd) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
2
|
import { init_paths } from "../config/paths.js";
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
3
|
import { join } from "node:path";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
5
|
//#region src/tui/tui-settings.ts
|
|
6
6
|
init_paths();
|
|
7
7
|
const DEFAULT_TUI_SETTINGS = {
|
package/dist/src/tui/tui.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { version } from "../../package.js";
|
|
2
|
-
import { loadConfig } from "../config/loader.js";
|
|
3
2
|
import { parseAgentSessionKey } from "../routing/session-key-utils.js";
|
|
4
3
|
import { init_agent_session_key } from "../routing/agent-session-key.js";
|
|
4
|
+
import { loadConfig } from "../config/loader.js";
|
|
5
5
|
import "../config/index.js";
|
|
6
6
|
import { resolveTuiSessionKey, resolveTuiStartupSessionKey } from "../routing/resolve-tui-session-key.js";
|
|
7
7
|
import { saveClipboardImageToTempFile } from "./clipboard-image.js";
|
|
@@ -31,9 +31,9 @@ import { TuiBottomBar } from "./components/tui-bottom-bar.js";
|
|
|
31
31
|
import { TuiHeader } from "./components/tui-header.js";
|
|
32
32
|
import { loadExtensionsForTuiLocalMode } from "./extension-host/load-extensions.js";
|
|
33
33
|
import { createTuiExtensionRuntime } from "./extension-host/runtime.js";
|
|
34
|
-
import { mkdtempSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
35
|
-
import { join } from "node:path";
|
|
36
34
|
import { tmpdir } from "node:os";
|
|
35
|
+
import { join } from "node:path";
|
|
36
|
+
import { mkdtempSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
37
37
|
import { spawnSync } from "node:child_process";
|
|
38
38
|
import { Container, Loader, ProcessTerminal, TUI, setKeybindings } from "@earendil-works/pi-tui";
|
|
39
39
|
//#region src/tui/tui.ts
|
|
@@ -2,10 +2,10 @@ import { createLogger } from "../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
3
|
import { init_paths, resolveBinDir } from "../config/paths.js";
|
|
4
4
|
import { extractFrpcFromReleaseArchive, frpcReleaseArchiveExtension, nodePlatformForFrpTarget } from "./frpc-extract.js";
|
|
5
|
-
import { randomBytes } from "node:crypto";
|
|
6
|
-
import { chmodSync, createWriteStream, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
7
|
-
import { join } from "node:path";
|
|
8
5
|
import { tmpdir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { chmodSync, createWriteStream, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
8
|
+
import { randomBytes } from "node:crypto";
|
|
9
9
|
import { Readable } from "node:stream";
|
|
10
10
|
import { pipeline } from "node:stream/promises";
|
|
11
11
|
//#region src/tunnel/frpc-binary.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
2
|
import { init_paths } from "../config/paths.js";
|
|
3
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
3
|
import { join } from "node:path";
|
|
4
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
5
5
|
//#region src/tunnel/frpc-config.ts
|
|
6
6
|
init_paths();
|
|
7
7
|
function resolveFrpcConfigPath(tunnelId) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
4
3
|
import { dirname, join } from "node:path";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import AdmZip from "adm-zip";
|
|
7
7
|
import { gunzipSync } from "node:zlib";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
2
|
import { init_paths } from "../config/paths.js";
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
3
|
import { join } from "node:path";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
5
|
//#region src/tunnel/tunnel-state.ts
|
|
6
6
|
init_paths();
|
|
7
7
|
const TUNNEL_STATE_FILE = "tunnel.json";
|
package/dist/src/utils/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { getLogDir, getLoggerConfig } from "./logger/config.js";
|
|
2
|
-
import {
|
|
2
|
+
import { getRuntimeLogStats } from "./logger/stats.js";
|
|
3
3
|
import { flushAndClose, isLoggerShuttingDown, setShuttingDown } from "./logger/shutdown.js";
|
|
4
4
|
import { cleanOldLogs, rotateLogs } from "./logger/rotation.js";
|
|
5
|
-
import {
|
|
5
|
+
import { getAsyncLogContext, inboundCorrelationMetadataFromAsyncLogContext, runWithLogContext, updateAsyncLogContext } from "./logger/context.js";
|
|
6
6
|
import { isLogRedactionEnabled, redactObject, redactPemBlock, redactSecret, redactSensitiveInfo } from "./logger/redact.js";
|
|
7
7
|
import { exportLog, flushExporters, getExporters, initializeExporters } from "./logger/exporters.js";
|
|
8
8
|
import { configureAuditLog, getAuditConfig, logAuditEvent, logAuthEvent, logConfigChange, logDataAccess, logPermissionChange } from "./logger/audit.js";
|
|
9
|
-
import { Pino as pino, baseLogger as logger, createExtensionLogger, createLogger, createModuleLogger,
|
|
9
|
+
import { Pino as pino, baseLogger as logger, createExtensionLogger, createLogger, createModuleLogger, createServiceLogger, getLogLevel, isLevelEnabled, setLogLevel, withLogLevel } from "./logger/index.js";
|
|
10
10
|
import { init_logger } from "./logger.js";
|
|
11
11
|
import { createPathResolver, getWorkspacePath, resolveToCwd } from "./helpers.js";
|
|
12
12
|
//#region src/utils/index.ts
|
|
13
13
|
init_logger();
|
|
14
14
|
//#endregion
|
|
15
|
-
export { pino as Pino, logger as baseLogger, logger, cleanOldLogs,
|
|
15
|
+
export { pino as Pino, logger as baseLogger, logger, cleanOldLogs, configureAuditLog, createExtensionLogger, createLogger, createModuleLogger, createPathResolver, createServiceLogger, exportLog, flushAndClose, flushExporters, getAsyncLogContext, getAuditConfig, getExporters, getLogDir, getLogLevel, getLoggerConfig, getRuntimeLogStats, getWorkspacePath, inboundCorrelationMetadataFromAsyncLogContext, initializeExporters, isLevelEnabled, isLogRedactionEnabled, isLoggerShuttingDown, logAuditEvent, logAuthEvent, logConfigChange, logDataAccess, logPermissionChange, redactObject, redactPemBlock, redactSecret, redactSensitiveInfo, resolveToCwd, rotateLogs, runWithLogContext, setLogLevel, setShuttingDown, updateAsyncLogContext, withLogLevel };
|
|
16
16
|
|
|
17
17
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { getLogDir, init_config } from "./config.js";
|
|
3
|
-
import { appendFile } from "fs/promises";
|
|
4
3
|
import path from "path";
|
|
5
4
|
import { existsSync, mkdirSync } from "fs";
|
|
5
|
+
import { appendFile } from "fs/promises";
|
|
6
6
|
//#region src/utils/logger/audit.ts
|
|
7
7
|
/**
|
|
8
8
|
* Audit Log
|
|
@@ -10,9 +10,7 @@ import path from "path";
|
|
|
10
10
|
*/
|
|
11
11
|
function loadConfig() {
|
|
12
12
|
const config = { ...DEFAULT_CONFIG };
|
|
13
|
-
|
|
14
|
-
if (logLevel) config.level = logLevel.toLowerCase();
|
|
15
|
-
else if (process.env.DEBUG) config.level = "debug";
|
|
13
|
+
if (process.env.XOPC_LOG_LEVEL) config.level = process.env.XOPC_LOG_LEVEL.toLowerCase();
|
|
16
14
|
if (process.env.XOPC_LOG_DIR) config.logDir = process.env.XOPC_LOG_DIR;
|
|
17
15
|
if (process.env.XOPC_LOG_CONSOLE === "false") config.consoleOutput = false;
|
|
18
16
|
if (process.env.XOPC_LOG_FILE === "false") config.fileOutput = false;
|
|
@@ -42,9 +40,7 @@ var init_config = __esmMin((() => {
|
|
|
42
40
|
errorFileOutput: true,
|
|
43
41
|
retentionDays: 7,
|
|
44
42
|
maxFileSizeMB: 100,
|
|
45
|
-
prettyPrint: false
|
|
46
|
-
async: true,
|
|
47
|
-
debugSampleRate: 1
|
|
43
|
+
prettyPrint: false
|
|
48
44
|
};
|
|
49
45
|
config = loadConfig();
|
|
50
46
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":[],"sources":["../../../../src/utils/logger/config.ts"],"sourcesContent":["/**\n * Logger Configuration\n * Centralized configuration loading from environment variables\n */\n\nimport path from 'path';\nimport type { LoggerConfig, LogLevel } from './types.js';\n\nconst DEFAULT_CONFIG: LoggerConfig = {\n level: 'info',\n logDir: path.join(process.env.HOME || '.', '.xopc', 'logs'),\n consoleOutput: true,\n fileOutput: true,\n errorFileOutput: true,\n retentionDays: 7,\n maxFileSizeMB: 100,\n prettyPrint: false,\n
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../../../../src/utils/logger/config.ts"],"sourcesContent":["/**\n * Logger Configuration\n * Centralized configuration loading from environment variables\n */\n\nimport path from 'path';\nimport type { LoggerConfig, LogLevel } from './types.js';\n\nconst DEFAULT_CONFIG: LoggerConfig = {\n level: 'info',\n logDir: path.join(process.env.HOME || '.', '.xopc', 'logs'),\n consoleOutput: true,\n fileOutput: true,\n errorFileOutput: true,\n retentionDays: 7,\n maxFileSizeMB: 100,\n prettyPrint: false,\n};\n\n/**\n * Load configuration from environment variables\n */\nexport function loadConfig(): LoggerConfig {\n const config: LoggerConfig = { ...DEFAULT_CONFIG };\n\n // Log level\n if (process.env.XOPC_LOG_LEVEL) {\n config.level = process.env.XOPC_LOG_LEVEL.toLowerCase() as LogLevel;\n }\n\n // Log directory\n if (process.env.XOPC_LOG_DIR) {\n config.logDir = process.env.XOPC_LOG_DIR;\n }\n\n // Output options\n if (process.env.XOPC_LOG_CONSOLE === 'false') {\n config.consoleOutput = false;\n }\n if (process.env.XOPC_LOG_FILE === 'false') {\n config.fileOutput = false;\n }\n\n // Retention\n if (process.env.XOPC_LOG_RETENTION_DAYS) {\n config.retentionDays = parseInt(process.env.XOPC_LOG_RETENTION_DAYS, 10);\n }\n\n // Pretty print for development\n if (process.env.NODE_ENV === 'development' || process.env.XOPC_PRETTY_LOGS === 'true') {\n config.prettyPrint = true;\n }\n\n return config;\n}\n\n// Singleton config instance\nexport const config = loadConfig();\n\n/**\n * Get current log directory\n */\nexport function getLogDir(): string {\n return config.logDir;\n}\n\n/**\n * Get logger configuration\n */\nexport function getLoggerConfig(): Readonly<LoggerConfig> {\n return { ...config };\n}\n"],"mappings":";;;;;;;;;;AAsBA,SAAgB,aAA2B;CACzC,MAAM,SAAuB,EAAE,GAAG,gBAAgB;AAGlD,KAAI,QAAQ,IAAI,eACd,QAAO,QAAQ,QAAQ,IAAI,eAAe,aAAa;AAIzD,KAAI,QAAQ,IAAI,aACd,QAAO,SAAS,QAAQ,IAAI;AAI9B,KAAI,QAAQ,IAAI,qBAAqB,QACnC,QAAO,gBAAgB;AAEzB,KAAI,QAAQ,IAAI,kBAAkB,QAChC,QAAO,aAAa;AAItB,KAAI,QAAQ,IAAI,wBACd,QAAO,gBAAgB,SAAS,QAAQ,IAAI,yBAAyB,GAAG;AAI1E,KAA8C,QAAQ,IAAI,qBAAqB,OAC7E,QAAO,cAAc;AAGvB,QAAO;;;;;AAST,SAAgB,YAAoB;AAClC,QAAO,OAAO;;;;;AAMhB,SAAgB,kBAA0C;AACxD,QAAO,EAAE,GAAG,QAAQ;;;;AA9DhB,kBAA+B;EACnC,OAAO;EACP,QAAQ,KAAK,KAAK,QAAQ,IAAI,QAAQ,KAAK,SAAS,OAAO;EAC3D,eAAe;EACf,YAAY;EACZ,iBAAiB;EACjB,eAAe;EACf,eAAe;EACf,aAAa;EACd;AAwCY,UAAS,YAAY"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Logger Context
|
|
3
|
-
*
|
|
3
|
+
* AsyncLocalStorage correlation for structured logging
|
|
4
4
|
*/
|
|
5
|
-
import type { LogContext
|
|
5
|
+
import type { LogContext } from './types.js';
|
|
6
6
|
/** Correlation fields merged into every log line while the store is active (via pino mixin). */
|
|
7
7
|
declare const ASYNC_LOG_CORRELATION_KEYS: readonly ["requestId", "sessionId", "userId", "correlationId"];
|
|
8
8
|
type AsyncLogCorrelationKey = (typeof ASYNC_LOG_CORRELATION_KEYS)[number];
|
|
@@ -21,25 +21,6 @@ export declare function updateAsyncLogContext(partial: LogContext): void;
|
|
|
21
21
|
/** Keys injected from async context into log records (used by logger mixin). */
|
|
22
22
|
export declare function getAsyncLogCorrelationKeys(): readonly AsyncLogCorrelationKey[];
|
|
23
23
|
export declare function inboundCorrelationMetadataFromAsyncLogContext(): Record<string, unknown> | undefined;
|
|
24
|
-
/**
|
|
25
|
-
* Merge two contexts
|
|
26
|
-
*/
|
|
24
|
+
/** Shallow-merge two log context objects. */
|
|
27
25
|
export declare function mergeContext(base: LogContext, additional: LogContext): LogContext;
|
|
28
|
-
/**
|
|
29
|
-
* Store context for a request ID
|
|
30
|
-
*/
|
|
31
|
-
export declare function setRequestContext(requestId: string, context: LogContext): void;
|
|
32
|
-
/**
|
|
33
|
-
* Get context for a request ID
|
|
34
|
-
*/
|
|
35
|
-
export declare function getRequestContext(requestId: string): LogContext | undefined;
|
|
36
|
-
/**
|
|
37
|
-
* Clear context for a request ID
|
|
38
|
-
*/
|
|
39
|
-
export declare function clearRequestContext(requestId: string): void;
|
|
40
|
-
/**
|
|
41
|
-
* Create a child logger with additional context
|
|
42
|
-
* This is a placeholder for the actual implementation
|
|
43
|
-
*/
|
|
44
|
-
export declare function withContext(logger: ContextualLogger, context: LogContext): ContextualLogger;
|
|
45
26
|
export {};
|
|
@@ -3,7 +3,7 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
3
3
|
//#region src/utils/logger/context.ts
|
|
4
4
|
/**
|
|
5
5
|
* Logger Context
|
|
6
|
-
*
|
|
6
|
+
* AsyncLocalStorage correlation for structured logging
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
9
|
* Run *fn* with merged async log context. Propagates through async/await (Node AsyncLocalStorage).
|
|
@@ -40,43 +40,15 @@ function inboundCorrelationMetadataFromAsyncLogContext() {
|
|
|
40
40
|
}
|
|
41
41
|
return Object.keys(meta).length > 0 ? meta : void 0;
|
|
42
42
|
}
|
|
43
|
-
/**
|
|
44
|
-
* Merge two contexts
|
|
45
|
-
*/
|
|
43
|
+
/** Shallow-merge two log context objects. */
|
|
46
44
|
function mergeContext(base, additional) {
|
|
47
45
|
return {
|
|
48
46
|
...base,
|
|
49
47
|
...additional
|
|
50
48
|
};
|
|
51
49
|
}
|
|
52
|
-
|
|
53
|
-
* Store context for a request ID
|
|
54
|
-
*/
|
|
55
|
-
function setRequestContext(requestId, context) {
|
|
56
|
-
contextStore.set(requestId, context);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Get context for a request ID
|
|
60
|
-
*/
|
|
61
|
-
function getRequestContext(requestId) {
|
|
62
|
-
return contextStore.get(requestId);
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Clear context for a request ID
|
|
66
|
-
*/
|
|
67
|
-
function clearRequestContext(requestId) {
|
|
68
|
-
contextStore.delete(requestId);
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Create a child logger with additional context
|
|
72
|
-
* This is a placeholder for the actual implementation
|
|
73
|
-
*/
|
|
74
|
-
function withContext(logger, context) {
|
|
75
|
-
return logger.withContext(context);
|
|
76
|
-
}
|
|
77
|
-
var contextStore, ASYNC_LOG_CORRELATION_KEYS, logContextStorage, INBOUND_METADATA_FROM_ASYNC;
|
|
50
|
+
var ASYNC_LOG_CORRELATION_KEYS, logContextStorage, INBOUND_METADATA_FROM_ASYNC;
|
|
78
51
|
var init_context = __esmMin((() => {
|
|
79
|
-
contextStore = /* @__PURE__ */ new Map();
|
|
80
52
|
ASYNC_LOG_CORRELATION_KEYS = [
|
|
81
53
|
"requestId",
|
|
82
54
|
"sessionId",
|
|
@@ -92,6 +64,6 @@ var init_context = __esmMin((() => {
|
|
|
92
64
|
}));
|
|
93
65
|
//#endregion
|
|
94
66
|
init_context();
|
|
95
|
-
export {
|
|
67
|
+
export { getAsyncLogContext, getAsyncLogCorrelationKeys, inboundCorrelationMetadataFromAsyncLogContext, init_context, mergeContext, runWithLogContext, updateAsyncLogContext };
|
|
96
68
|
|
|
97
69
|
//# sourceMappingURL=context.js.map
|