@poolzin/pool-bot 2026.2.21 → 2026.2.22
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/CHANGELOG.md +17 -0
- package/dist/agents/api-key-rotation.js +47 -0
- package/dist/agents/apply-patch-update.js +19 -9
- package/dist/agents/apply-patch.js +72 -47
- package/dist/agents/bash-tools.exec.js +141 -559
- package/dist/agents/cli-backends.js +49 -6
- package/dist/agents/cli-runner/helpers.js +69 -152
- package/dist/agents/cli-runner.js +70 -19
- package/dist/agents/identity.js +20 -1
- package/dist/agents/image-sanitization.js +9 -0
- package/dist/agents/live-auth-keys.js +123 -26
- package/dist/agents/live-model-filter.js +13 -4
- package/dist/agents/model-catalog.js +40 -9
- package/dist/agents/model-forward-compat.js +60 -23
- package/dist/agents/model-selection.js +134 -41
- package/dist/agents/pi-auth-json.js +2 -2
- package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
- package/dist/agents/pi-embedded-helpers/errors.js +140 -15
- package/dist/agents/pi-embedded-helpers/images.js +22 -12
- package/dist/agents/pi-embedded-helpers.js +2 -2
- package/dist/agents/pi-embedded-runner/abort.js +10 -3
- package/dist/agents/pi-embedded-runner/compact.js +230 -32
- package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
- package/dist/agents/pi-embedded-runner/google.js +109 -19
- package/dist/agents/pi-embedded-runner/history.js +35 -17
- package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
- package/dist/agents/pi-embedded-runner/run/images.js +81 -55
- package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
- package/dist/agents/pi-embedded-runner/run.js +193 -25
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
- package/dist/agents/pi-embedded-runner/runs.js +17 -8
- package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
- package/dist/agents/pi-embedded-runner.js +1 -1
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
- package/dist/agents/pi-embedded-subscribe.js +37 -0
- package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
- package/dist/agents/pi-model-discovery.js +9 -2
- package/dist/agents/pi-tool-definition-adapter.js +60 -8
- package/dist/agents/pi-tools.before-tool-call.js +1 -1
- package/dist/agents/pi-tools.js +113 -94
- package/dist/agents/pi-tools.read.js +337 -38
- package/dist/agents/poolbot-tools.js +14 -5
- package/dist/agents/sandbox/docker.js +10 -5
- package/dist/agents/sandbox/registry.js +96 -46
- package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
- package/dist/agents/sandbox-paths.js +43 -10
- package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
- package/dist/agents/session-tool-result-guard.js +39 -39
- package/dist/agents/session-transcript-repair.js +36 -33
- package/dist/agents/session-write-lock.js +62 -44
- package/dist/agents/skills/frontmatter.js +49 -88
- package/dist/agents/skills/workspace.js +335 -28
- package/dist/agents/subagent-announce.js +508 -174
- package/dist/agents/subagent-registry.js +45 -4
- package/dist/agents/subagent-spawn.js +16 -33
- package/dist/agents/system-prompt-report.js +27 -10
- package/dist/agents/system-prompt.js +26 -32
- package/dist/agents/tool-call-id.js +69 -17
- package/dist/agents/tool-display-common.js +1 -1
- package/dist/agents/tool-images.js +64 -31
- package/dist/agents/tools/canvas-tool.js +17 -11
- package/dist/agents/tools/common.js +37 -19
- package/dist/agents/tools/cron-tool.js +40 -38
- package/dist/agents/tools/gateway.js +70 -2
- package/dist/agents/tools/message-tool.js +181 -40
- package/dist/agents/tools/nodes-tool.js +128 -36
- package/dist/agents/tools/nodes-utils.js +12 -38
- package/dist/agents/tools/session-status-tool.js +24 -71
- package/dist/agents/tools/sessions-helpers.js +38 -210
- package/dist/agents/tools/sessions-spawn-tool.js +28 -198
- package/dist/agents/tools/telegram-actions.js +58 -7
- package/dist/agents/tools/web-fetch-utils.js +112 -7
- package/dist/agents/tools/web-fetch.js +279 -175
- package/dist/agents/tools/web-shared.js +71 -8
- package/dist/agents/usage.js +25 -16
- package/dist/auto-reply/commands-registry.data.js +85 -11
- package/dist/auto-reply/dispatch.js +40 -21
- package/dist/auto-reply/reply/abort.js +102 -33
- package/dist/auto-reply/reply/commands-core.js +82 -33
- package/dist/auto-reply/reply/commands-export-session.js +1 -1
- package/dist/auto-reply/reply/commands-info.js +41 -12
- package/dist/auto-reply/reply/commands-subagents.js +352 -100
- package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
- package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
- package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
- package/dist/auto-reply/reply/inbound-meta.js +12 -1
- package/dist/auto-reply/reply/mentions.js +18 -11
- package/dist/auto-reply/reply/normalize-reply.js +17 -8
- package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
- package/dist/auto-reply/reply/session.js +102 -21
- package/dist/auto-reply/reply/streaming-directives.js +16 -5
- package/dist/auto-reply/status.js +73 -50
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/http-auth.js +1 -1
- package/dist/browser/paths.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/channels/allowlist-match.js +20 -0
- package/dist/channels/allowlists/resolve-utils.js +65 -2
- package/dist/channels/chat-type.js +8 -4
- package/dist/channels/dock.js +127 -35
- package/dist/channels/draft-stream-loop.js +6 -2
- package/dist/channels/plugins/actions/telegram.js +42 -18
- package/dist/channels/plugins/allowlist-match.js +1 -1
- package/dist/channels/plugins/group-mentions.js +51 -41
- package/dist/channels/plugins/message-action-names.js +2 -0
- package/dist/channels/plugins/message-actions.js +24 -5
- package/dist/channels/plugins/normalize/discord.js +26 -4
- package/dist/channels/plugins/normalize/signal.js +35 -22
- package/dist/channels/plugins/onboarding/helpers.js +8 -26
- package/dist/channels/plugins/outbound/imessage.js +15 -14
- package/dist/channels/registry.js +20 -7
- package/dist/cli/acp-cli.js +7 -5
- package/dist/cli/browser-cli-extension.js +25 -12
- package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
- package/dist/cli/browser-cli-state.js +101 -145
- package/dist/cli/command-options.js +28 -0
- package/dist/cli/completion-cli.js +6 -6
- package/dist/cli/cron-cli/register.cron-add.js +25 -1
- package/dist/cli/cron-cli/register.cron-edit.js +44 -0
- package/dist/cli/cron-cli/shared.js +7 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
- package/dist/cli/daemon-cli/lifecycle.js +23 -247
- package/dist/cli/daemon-cli/register-service-commands.js +25 -4
- package/dist/cli/daemon-cli.js +1 -0
- package/dist/cli/devices-cli.js +33 -20
- package/dist/cli/gateway-cli/register.js +37 -105
- package/dist/cli/gateway-cli/run.js +49 -11
- package/dist/cli/nodes-camera.js +59 -4
- package/dist/cli/nodes-cli/register.camera.js +27 -24
- package/dist/cli/nodes-cli/rpc.js +21 -38
- package/dist/cli/qr-cli.js +2 -2
- package/dist/cli/skills-cli.format.js +2 -2
- package/dist/cli/update-cli/progress.js +2 -2
- package/dist/cli/update-cli/restart-helper.js +28 -7
- package/dist/cli/update-cli/shared.js +7 -7
- package/dist/cli/update-cli/status.js +1 -1
- package/dist/cli/update-cli/update-command.js +14 -8
- package/dist/cli/update-cli/wizard.js +2 -2
- package/dist/cli/update-cli.js +21 -1027
- package/dist/commands/auth-choice.apply.anthropic.js +10 -2
- package/dist/commands/channels/add-mutators.js +3 -35
- package/dist/commands/channels/add.js +39 -51
- package/dist/commands/config-validation.js +1 -1
- package/dist/commands/configure.gateway-auth.js +52 -15
- package/dist/commands/configure.gateway.js +84 -40
- package/dist/commands/doctor-completion.js +3 -3
- package/dist/commands/doctor-config-flow.js +536 -16
- package/dist/commands/doctor-gateway-services.js +103 -79
- package/dist/commands/doctor-memory-search.js +9 -9
- package/dist/commands/doctor-platform-notes.js +57 -30
- package/dist/commands/doctor-prompter.js +26 -15
- package/dist/commands/doctor-session-locks.js +1 -1
- package/dist/commands/doctor.js +21 -9
- package/dist/commands/model-picker.js +120 -95
- package/dist/commands/models/set.js +2 -21
- package/dist/commands/models/shared.js +65 -37
- package/dist/commands/onboard-helpers.js +81 -39
- package/dist/commands/openai-codex-oauth.js +1 -1
- package/dist/commands/sessions.js +52 -53
- package/dist/commands/status.summary.js +52 -34
- package/dist/commands/test-wizard-helpers.js +2 -2
- package/dist/config/defaults.js +79 -42
- package/dist/config/group-policy.js +50 -18
- package/dist/config/includes.js +37 -10
- package/dist/config/schema.help.js +5 -4
- package/dist/config/schema.hints.js +2 -2
- package/dist/config/schema.labels.js +1 -0
- package/dist/config/sessions/group.js +12 -11
- package/dist/config/sessions/paths.js +137 -11
- package/dist/config/sessions/store.js +185 -65
- package/dist/config/sessions/types.js +15 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/telegram-custom-commands.js +3 -2
- package/dist/config/types.js +2 -0
- package/dist/config/zod-schema.agent-defaults.js +6 -27
- package/dist/config/zod-schema.agent-runtime.js +171 -79
- package/dist/config/zod-schema.providers-core.js +138 -65
- package/dist/config/zod-schema.session.js +49 -22
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/run.js +224 -57
- package/dist/cron/normalize.js +48 -45
- package/dist/cron/run-log.js +14 -0
- package/dist/cron/service/jobs.js +190 -28
- package/dist/cron/service/normalize.js +29 -11
- package/dist/cron/service/store.js +30 -44
- package/dist/cron/service/timer.js +182 -96
- package/dist/cron/service.js +3 -0
- package/dist/cron/stagger.js +37 -0
- package/dist/daemon/inspect.js +132 -92
- package/dist/daemon/runtime-paths.js +25 -4
- package/dist/daemon/service-audit.js +47 -16
- package/dist/discord/accounts.js +23 -20
- package/dist/discord/monitor/agent-components.js +1115 -219
- package/dist/discord/monitor/allow-list.js +114 -34
- package/dist/discord/monitor/listeners.js +204 -97
- package/dist/discord/monitor/message-handler.js +21 -10
- package/dist/discord/monitor/message-handler.preflight.js +195 -101
- package/dist/discord/monitor/message-handler.process.js +384 -123
- package/dist/discord/monitor/message-utils.js +86 -23
- package/dist/discord/monitor/native-command.js +77 -57
- package/dist/discord/monitor/provider.js +122 -117
- package/dist/discord/monitor/reply-context.js +20 -16
- package/dist/discord/monitor/reply-delivery.js +40 -8
- package/dist/discord/monitor/rest-fetch.js +22 -0
- package/dist/discord/monitor/threading.js +117 -24
- package/dist/discord/send.js +2 -1
- package/dist/discord/send.outbound.js +124 -11
- package/dist/discord/send.shared.js +112 -72
- package/dist/discord/voice-message.js +3 -3
- package/dist/gateway/auth.js +119 -44
- package/dist/gateway/call.js +76 -34
- package/dist/gateway/channel-health-monitor.js +57 -50
- package/dist/gateway/client.js +63 -29
- package/dist/gateway/control-ui-contract.js +1 -1
- package/dist/gateway/gateway-config-prompts.shared.js +2 -2
- package/dist/gateway/net.js +109 -1
- package/dist/gateway/protocol/index.js +5 -8
- package/dist/gateway/protocol/schema/agent.js +19 -1
- package/dist/gateway/protocol/schema/channels.js +21 -0
- package/dist/gateway/protocol/schema/cron.js +43 -30
- package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
- package/dist/gateway/protocol/schema/sessions.js +5 -1
- package/dist/gateway/protocol/schema.js +0 -1
- package/dist/gateway/server/presence-events.js +12 -0
- package/dist/gateway/server/ws-connection/message-handler.js +203 -212
- package/dist/gateway/server/ws-connection.js +58 -21
- package/dist/gateway/server-broadcast.js +18 -13
- package/dist/gateway/server-cron.js +177 -10
- package/dist/gateway/server-methods/agent-job.js +131 -38
- package/dist/gateway/server-methods/send.js +60 -14
- package/dist/gateway/server-methods/sessions.js +160 -96
- package/dist/gateway/server-methods/system.js +5 -7
- package/dist/gateway/server-methods-list.js +8 -0
- package/dist/gateway/server-methods.js +24 -8
- package/dist/gateway/server-node-events.js +278 -68
- package/dist/gateway/session-utils.fs.js +316 -75
- package/dist/gateway/session-utils.js +224 -70
- package/dist/gateway/sessions-patch.js +63 -20
- package/dist/gateway/test-temp-config.js +1 -1
- package/dist/gateway/tools-invoke-http.js +118 -70
- package/dist/gateway/ws-log.js +135 -107
- package/dist/hooks/frontmatter.js +36 -82
- package/dist/hooks/install.js +149 -139
- package/dist/hooks/internal-hooks.js +29 -4
- package/dist/hooks/plugin-hooks.js +2 -1
- package/dist/imessage/monitor/deliver.js +10 -4
- package/dist/imessage/monitor/monitor-provider.js +138 -375
- package/dist/imessage/monitor/runtime.js +4 -8
- package/dist/imessage/send.js +65 -19
- package/dist/infra/exec-approvals-allowlist.js +7 -0
- package/dist/infra/exec-approvals.js +35 -920
- package/dist/infra/exec-safe-bin-trust.js +64 -0
- package/dist/infra/heartbeat-runner.js +207 -134
- package/dist/infra/heartbeat-wake.js +183 -22
- package/dist/infra/install-source-utils.js +47 -0
- package/dist/infra/net/ssrf.js +170 -36
- package/dist/infra/outbound/deliver.js +224 -58
- package/dist/infra/outbound/message-action-spec.js +12 -5
- package/dist/infra/outbound/outbound-session.js +27 -25
- package/dist/infra/poolbot-root.js +32 -22
- package/dist/infra/ports.js +14 -11
- package/dist/infra/skills-remote.js +48 -37
- package/dist/infra/system-events.js +25 -11
- package/dist/infra/system-presence.js +26 -33
- package/dist/infra/tmp-poolbot-dir.js +81 -2
- package/dist/infra/wsl.js +37 -1
- package/dist/line/bot-message-context.js +163 -191
- package/dist/logging/subsystem.js +59 -22
- package/dist/markdown/ir.js +124 -50
- package/dist/media/store.js +1 -1
- package/dist/media-understanding/runner.entries.js +42 -25
- package/dist/media-understanding/runner.js +53 -488
- package/dist/memory/embeddings-gemini.js +53 -38
- package/dist/memory/manager-embedding-ops.js +48 -69
- package/dist/pairing/pairing-store.js +178 -119
- package/dist/plugin-sdk/index.js +34 -6
- package/dist/plugins/hooks.js +135 -14
- package/dist/plugins/install.js +190 -152
- package/dist/polls.js +11 -0
- package/dist/routing/resolve-route.js +190 -56
- package/dist/routing/session-key.js +38 -22
- package/dist/runtime.js +35 -9
- package/dist/security/audit-channel.js +1 -1
- package/dist/sessions/session-key-utils.js +29 -11
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-list-types.js +1 -0
- package/dist/shared/string-normalization.js +15 -0
- package/dist/signal/monitor/event-handler.js +68 -36
- package/dist/signal/send.js +29 -37
- package/dist/slack/monitor/allow-list.js +10 -11
- package/dist/slack/monitor/commands.js +14 -3
- package/dist/slack/monitor/events/interactions.js +4 -4
- package/dist/slack/monitor/media.js +224 -16
- package/dist/slack/monitor/message-handler/dispatch.js +247 -13
- package/dist/slack/monitor/message-handler/prepare.js +128 -45
- package/dist/slack/monitor/slash.js +357 -144
- package/dist/slack/streaming.js +77 -0
- package/dist/telegram/accounts.js +40 -13
- package/dist/telegram/allowed-updates.js +3 -0
- package/dist/telegram/bot/delivery.js +129 -66
- package/dist/telegram/bot/helpers.js +136 -122
- package/dist/telegram/bot-handlers.js +600 -339
- package/dist/telegram/bot-message-context.js +115 -73
- package/dist/telegram/bot-message-dispatch.js +235 -104
- package/dist/telegram/bot-native-command-menu.js +3 -1
- package/dist/telegram/bot-native-commands.js +213 -193
- package/dist/telegram/bot.js +24 -132
- package/dist/telegram/draft-stream.js +84 -75
- package/dist/telegram/format.js +150 -6
- package/dist/telegram/send.js +415 -255
- package/dist/telegram/targets.js +21 -2
- package/dist/telegram/update-offset-store.js +19 -3
- package/dist/terminal/restore.js +5 -2
- package/dist/test-utils/fetch-mock.js +5 -0
- package/dist/version.js +18 -5
- package/dist/web/auto-reply/monitor/broadcast.js +7 -3
- package/dist/web/auto-reply/monitor/on-message.js +6 -3
- package/dist/web/inbound/media.js +34 -8
- package/dist/web/inbound/monitor.js +34 -17
- package/dist/web/inbound/send-api.js +18 -17
- package/dist/web/outbound.js +12 -5
- package/dist/wizard/clack-prompter.js +40 -7
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +5 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +5 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +5 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +5 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +5 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +5 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +5 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
- package/skills/apple-reminders/SKILL.md +100 -49
- package/skills/coding-agent/SKILL.md +34 -28
- package/skills/github/SKILL.md +131 -16
- package/skills/imsg/SKILL.md +112 -15
- package/skills/openhue/SKILL.md +101 -19
- package/skills/tmux/SKILL.md +111 -79
- package/skills/weather/SKILL.md +88 -25
|
@@ -3,15 +3,15 @@ import path from "node:path";
|
|
|
3
3
|
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
|
|
4
4
|
import { lookupContextTokens } from "../agents/context.js";
|
|
5
5
|
import { DEFAULT_CONTEXT_TOKENS, DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
|
|
6
|
-
import { resolveConfiguredModelRef, resolveDefaultModelForAgent, } from "../agents/model-selection.js";
|
|
6
|
+
import { parseModelRef, resolveConfiguredModelRef, resolveDefaultModelForAgent, } from "../agents/model-selection.js";
|
|
7
7
|
import { loadConfig } from "../config/config.js";
|
|
8
8
|
import { resolveStateDir } from "../config/paths.js";
|
|
9
|
-
import { buildGroupDisplayName, canonicalizeMainSessionAlias, loadSessionStore, resolveMainSessionKey, resolveStorePath, } from "../config/sessions.js";
|
|
9
|
+
import { buildGroupDisplayName, canonicalizeMainSessionAlias, loadSessionStore, resolveAgentMainSessionKey, resolveFreshSessionTotalTokens, resolveMainSessionKey, resolveStorePath, } from "../config/sessions.js";
|
|
10
10
|
import { normalizeAgentId, normalizeMainKey, parseAgentSessionKey, } from "../routing/session-key.js";
|
|
11
11
|
import { isCronRunSessionKey } from "../sessions/session-key-utils.js";
|
|
12
12
|
import { normalizeSessionDeliveryFields } from "../utils/delivery-context.js";
|
|
13
|
-
import {
|
|
14
|
-
export { archiveFileOnDisk, capArrayByJsonBytes, readFirstUserMessageFromTranscript, readLastMessagePreviewFromTranscript, readSessionPreviewItemsFromTranscript, readSessionMessages, resolveSessionTranscriptCandidates, } from "./session-utils.fs.js";
|
|
13
|
+
import { readSessionTitleFieldsFromTranscript } from "./session-utils.fs.js";
|
|
14
|
+
export { archiveFileOnDisk, archiveSessionTranscripts, capArrayByJsonBytes, readFirstUserMessageFromTranscript, readLastMessagePreviewFromTranscript, readSessionTitleFieldsFromTranscript, readSessionPreviewItemsFromTranscript, readSessionMessages, resolveSessionTranscriptCandidates, } from "./session-utils.fs.js";
|
|
15
15
|
const DERIVED_TITLE_MAX_LEN = 60;
|
|
16
16
|
const AVATAR_MAX_BYTES = 2 * 1024 * 1024;
|
|
17
17
|
const AVATAR_DATA_RE = /^data:/i;
|
|
@@ -34,34 +34,43 @@ function resolveAvatarMime(filePath) {
|
|
|
34
34
|
return AVATAR_MIME_BY_EXT[ext] ?? "application/octet-stream";
|
|
35
35
|
}
|
|
36
36
|
function isWorkspaceRelativePath(value) {
|
|
37
|
-
if (!value)
|
|
37
|
+
if (!value) {
|
|
38
38
|
return false;
|
|
39
|
-
|
|
39
|
+
}
|
|
40
|
+
if (value.startsWith("~")) {
|
|
40
41
|
return false;
|
|
41
|
-
|
|
42
|
+
}
|
|
43
|
+
if (AVATAR_SCHEME_RE.test(value) && !WINDOWS_ABS_RE.test(value)) {
|
|
42
44
|
return false;
|
|
45
|
+
}
|
|
43
46
|
return true;
|
|
44
47
|
}
|
|
45
48
|
function resolveIdentityAvatarUrl(cfg, agentId, avatar) {
|
|
46
|
-
if (!avatar)
|
|
49
|
+
if (!avatar) {
|
|
47
50
|
return undefined;
|
|
51
|
+
}
|
|
48
52
|
const trimmed = avatar.trim();
|
|
49
|
-
if (!trimmed)
|
|
53
|
+
if (!trimmed) {
|
|
50
54
|
return undefined;
|
|
51
|
-
|
|
55
|
+
}
|
|
56
|
+
if (AVATAR_DATA_RE.test(trimmed) || AVATAR_HTTP_RE.test(trimmed)) {
|
|
52
57
|
return trimmed;
|
|
53
|
-
|
|
58
|
+
}
|
|
59
|
+
if (!isWorkspaceRelativePath(trimmed)) {
|
|
54
60
|
return undefined;
|
|
61
|
+
}
|
|
55
62
|
const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId);
|
|
56
63
|
const workspaceRoot = path.resolve(workspaceDir);
|
|
57
64
|
const resolved = path.resolve(workspaceRoot, trimmed);
|
|
58
65
|
const relative = path.relative(workspaceRoot, resolved);
|
|
59
|
-
if (relative.startsWith("..") || path.isAbsolute(relative))
|
|
66
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
60
67
|
return undefined;
|
|
68
|
+
}
|
|
61
69
|
try {
|
|
62
70
|
const stat = fs.statSync(resolved);
|
|
63
|
-
if (!stat.isFile() || stat.size > AVATAR_MAX_BYTES)
|
|
71
|
+
if (!stat.isFile() || stat.size > AVATAR_MAX_BYTES) {
|
|
64
72
|
return undefined;
|
|
73
|
+
}
|
|
65
74
|
const buffer = fs.readFileSync(resolved);
|
|
66
75
|
const mime = resolveAvatarMime(resolved);
|
|
67
76
|
return `data:${mime};base64,${buffer.toString("base64")}`;
|
|
@@ -80,17 +89,20 @@ function formatSessionIdPrefix(sessionId, updatedAt) {
|
|
|
80
89
|
return prefix;
|
|
81
90
|
}
|
|
82
91
|
function truncateTitle(text, maxLen) {
|
|
83
|
-
if (text.length <= maxLen)
|
|
92
|
+
if (text.length <= maxLen) {
|
|
84
93
|
return text;
|
|
94
|
+
}
|
|
85
95
|
const cut = text.slice(0, maxLen - 1);
|
|
86
96
|
const lastSpace = cut.lastIndexOf(" ");
|
|
87
|
-
if (lastSpace > maxLen * 0.6)
|
|
97
|
+
if (lastSpace > maxLen * 0.6) {
|
|
88
98
|
return cut.slice(0, lastSpace) + "…";
|
|
99
|
+
}
|
|
89
100
|
return cut + "…";
|
|
90
101
|
}
|
|
91
102
|
export function deriveSessionTitle(entry, firstUserMessage) {
|
|
92
|
-
if (!entry)
|
|
103
|
+
if (!entry) {
|
|
93
104
|
return undefined;
|
|
105
|
+
}
|
|
94
106
|
if (entry.displayName?.trim()) {
|
|
95
107
|
return entry.displayName.trim();
|
|
96
108
|
}
|
|
@@ -113,14 +125,76 @@ export function loadSessionEntry(sessionKey) {
|
|
|
113
125
|
const agentId = resolveSessionStoreAgentId(cfg, canonicalKey);
|
|
114
126
|
const storePath = resolveStorePath(sessionCfg?.store, { agentId });
|
|
115
127
|
const store = loadSessionStore(storePath);
|
|
116
|
-
const
|
|
117
|
-
|
|
128
|
+
const match = findStoreMatch(store, canonicalKey, sessionKey.trim());
|
|
129
|
+
const legacyKey = match?.key !== canonicalKey ? match?.key : undefined;
|
|
130
|
+
return { cfg, storePath, store, entry: match?.entry, canonicalKey, legacyKey };
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Find a session entry by exact or case-insensitive key match.
|
|
134
|
+
* Returns both the entry and the actual store key it was found under,
|
|
135
|
+
* so callers can clean up legacy mixed-case keys when they differ from canonicalKey.
|
|
136
|
+
*/
|
|
137
|
+
function findStoreMatch(store, ...candidates) {
|
|
138
|
+
// Exact match first.
|
|
139
|
+
for (const candidate of candidates) {
|
|
140
|
+
if (candidate && store[candidate]) {
|
|
141
|
+
return { entry: store[candidate], key: candidate };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Case-insensitive scan for ALL candidates.
|
|
145
|
+
const loweredSet = new Set(candidates.filter(Boolean).map((c) => c.toLowerCase()));
|
|
146
|
+
for (const key of Object.keys(store)) {
|
|
147
|
+
if (loweredSet.has(key.toLowerCase())) {
|
|
148
|
+
return { entry: store[key], key };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Find all on-disk store keys that match the given key case-insensitively.
|
|
155
|
+
* Returns every key from the store whose lowercased form equals the target's lowercased form.
|
|
156
|
+
*/
|
|
157
|
+
export function findStoreKeysIgnoreCase(store, targetKey) {
|
|
158
|
+
const lowered = targetKey.toLowerCase();
|
|
159
|
+
const matches = [];
|
|
160
|
+
for (const key of Object.keys(store)) {
|
|
161
|
+
if (key.toLowerCase() === lowered) {
|
|
162
|
+
matches.push(key);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return matches;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Remove legacy key variants for one canonical session key.
|
|
169
|
+
* Candidates can include aliases (for example, "agent:ops:main" when canonical is "agent:ops:work").
|
|
170
|
+
*/
|
|
171
|
+
export function pruneLegacyStoreKeys(params) {
|
|
172
|
+
const keysToDelete = new Set();
|
|
173
|
+
for (const candidate of params.candidates) {
|
|
174
|
+
const trimmed = String(candidate ?? "").trim();
|
|
175
|
+
if (!trimmed) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (trimmed !== params.canonicalKey) {
|
|
179
|
+
keysToDelete.add(trimmed);
|
|
180
|
+
}
|
|
181
|
+
for (const match of findStoreKeysIgnoreCase(params.store, trimmed)) {
|
|
182
|
+
if (match !== params.canonicalKey) {
|
|
183
|
+
keysToDelete.add(match);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
for (const key of keysToDelete) {
|
|
188
|
+
delete params.store[key];
|
|
189
|
+
}
|
|
118
190
|
}
|
|
119
191
|
export function classifySessionKey(key, entry) {
|
|
120
|
-
if (key === "global")
|
|
192
|
+
if (key === "global") {
|
|
121
193
|
return "global";
|
|
122
|
-
|
|
194
|
+
}
|
|
195
|
+
if (key === "unknown") {
|
|
123
196
|
return "unknown";
|
|
197
|
+
}
|
|
124
198
|
if (entry?.chatType === "group" || entry?.chatType === "channel") {
|
|
125
199
|
return "group";
|
|
126
200
|
}
|
|
@@ -164,8 +238,9 @@ function listConfiguredAgentIds(cfg) {
|
|
|
164
238
|
if (agents.length > 0) {
|
|
165
239
|
const ids = new Set();
|
|
166
240
|
for (const entry of agents) {
|
|
167
|
-
if (entry?.id)
|
|
241
|
+
if (entry?.id) {
|
|
168
242
|
ids.add(normalizeAgentId(entry.id));
|
|
243
|
+
}
|
|
169
244
|
}
|
|
170
245
|
const defaultId = normalizeAgentId(resolveDefaultAgentId(cfg));
|
|
171
246
|
ids.add(defaultId);
|
|
@@ -178,8 +253,9 @@ function listConfiguredAgentIds(cfg) {
|
|
|
178
253
|
const ids = new Set();
|
|
179
254
|
const defaultId = normalizeAgentId(resolveDefaultAgentId(cfg));
|
|
180
255
|
ids.add(defaultId);
|
|
181
|
-
for (const id of listExistingAgentIdsFromDisk())
|
|
256
|
+
for (const id of listExistingAgentIdsFromDisk()) {
|
|
182
257
|
ids.add(id);
|
|
258
|
+
}
|
|
183
259
|
const sorted = Array.from(ids).filter(Boolean);
|
|
184
260
|
sorted.sort((a, b) => a.localeCompare(b));
|
|
185
261
|
if (sorted.includes(defaultId)) {
|
|
@@ -193,8 +269,9 @@ export function listAgentsForGateway(cfg) {
|
|
|
193
269
|
const scope = cfg.session?.scope ?? "per-sender";
|
|
194
270
|
const configuredById = new Map();
|
|
195
271
|
for (const entry of cfg.agents?.list ?? []) {
|
|
196
|
-
if (!entry?.id)
|
|
272
|
+
if (!entry?.id) {
|
|
197
273
|
continue;
|
|
274
|
+
}
|
|
198
275
|
const identity = entry.identity
|
|
199
276
|
? {
|
|
200
277
|
name: entry.identity.name?.trim() || undefined,
|
|
@@ -214,7 +291,7 @@ export function listAgentsForGateway(cfg) {
|
|
|
214
291
|
.filter(Boolean));
|
|
215
292
|
const allowedIds = explicitIds.size > 0 ? new Set([...explicitIds, defaultId]) : null;
|
|
216
293
|
let agentIds = listConfiguredAgentIds(cfg).filter((id) => allowedIds ? allowedIds.has(id) : true);
|
|
217
|
-
if (mainKey && !agentIds.includes(mainKey)) {
|
|
294
|
+
if (mainKey && !agentIds.includes(mainKey) && (!allowedIds || allowedIds.has(mainKey))) {
|
|
218
295
|
agentIds = [...agentIds, mainKey];
|
|
219
296
|
}
|
|
220
297
|
const agents = agentIds.map((id) => {
|
|
@@ -228,58 +305,79 @@ export function listAgentsForGateway(cfg) {
|
|
|
228
305
|
return { defaultId, mainKey, scope, agents };
|
|
229
306
|
}
|
|
230
307
|
function canonicalizeSessionKeyForAgent(agentId, key) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
308
|
+
const lowered = key.toLowerCase();
|
|
309
|
+
if (lowered === "global" || lowered === "unknown") {
|
|
310
|
+
return lowered;
|
|
311
|
+
}
|
|
312
|
+
if (lowered.startsWith("agent:")) {
|
|
313
|
+
return lowered;
|
|
314
|
+
}
|
|
315
|
+
return `agent:${normalizeAgentId(agentId)}:${lowered}`;
|
|
236
316
|
}
|
|
237
317
|
function resolveDefaultStoreAgentId(cfg) {
|
|
238
318
|
return normalizeAgentId(resolveDefaultAgentId(cfg));
|
|
239
319
|
}
|
|
240
320
|
export function resolveSessionStoreKey(params) {
|
|
241
321
|
const raw = params.sessionKey.trim();
|
|
242
|
-
if (!raw)
|
|
243
|
-
return raw;
|
|
244
|
-
if (raw === "global" || raw === "unknown")
|
|
322
|
+
if (!raw) {
|
|
245
323
|
return raw;
|
|
324
|
+
}
|
|
325
|
+
const rawLower = raw.toLowerCase();
|
|
326
|
+
if (rawLower === "global" || rawLower === "unknown") {
|
|
327
|
+
return rawLower;
|
|
328
|
+
}
|
|
246
329
|
const parsed = parseAgentSessionKey(raw);
|
|
247
330
|
if (parsed) {
|
|
248
331
|
const agentId = normalizeAgentId(parsed.agentId);
|
|
332
|
+
const lowered = raw.toLowerCase();
|
|
249
333
|
const canonical = canonicalizeMainSessionAlias({
|
|
250
334
|
cfg: params.cfg,
|
|
251
335
|
agentId,
|
|
252
|
-
sessionKey:
|
|
336
|
+
sessionKey: lowered,
|
|
253
337
|
});
|
|
254
|
-
if (canonical !==
|
|
338
|
+
if (canonical !== lowered) {
|
|
255
339
|
return canonical;
|
|
256
|
-
|
|
340
|
+
}
|
|
341
|
+
return lowered;
|
|
257
342
|
}
|
|
343
|
+
const lowered = raw.toLowerCase();
|
|
258
344
|
const rawMainKey = normalizeMainKey(params.cfg.session?.mainKey);
|
|
259
|
-
if (
|
|
345
|
+
if (lowered === "main" || lowered === rawMainKey) {
|
|
260
346
|
return resolveMainSessionKey(params.cfg);
|
|
261
347
|
}
|
|
262
348
|
const agentId = resolveDefaultStoreAgentId(params.cfg);
|
|
263
|
-
return canonicalizeSessionKeyForAgent(agentId,
|
|
349
|
+
return canonicalizeSessionKeyForAgent(agentId, lowered);
|
|
264
350
|
}
|
|
265
351
|
function resolveSessionStoreAgentId(cfg, canonicalKey) {
|
|
266
352
|
if (canonicalKey === "global" || canonicalKey === "unknown") {
|
|
267
353
|
return resolveDefaultStoreAgentId(cfg);
|
|
268
354
|
}
|
|
269
355
|
const parsed = parseAgentSessionKey(canonicalKey);
|
|
270
|
-
if (parsed?.agentId)
|
|
356
|
+
if (parsed?.agentId) {
|
|
271
357
|
return normalizeAgentId(parsed.agentId);
|
|
358
|
+
}
|
|
272
359
|
return resolveDefaultStoreAgentId(cfg);
|
|
273
360
|
}
|
|
274
|
-
function canonicalizeSpawnedByForAgent(agentId, spawnedBy) {
|
|
361
|
+
export function canonicalizeSpawnedByForAgent(cfg, agentId, spawnedBy) {
|
|
275
362
|
const raw = spawnedBy?.trim();
|
|
276
|
-
if (!raw)
|
|
363
|
+
if (!raw) {
|
|
277
364
|
return undefined;
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
if (
|
|
281
|
-
return
|
|
282
|
-
|
|
365
|
+
}
|
|
366
|
+
const lower = raw.toLowerCase();
|
|
367
|
+
if (lower === "global" || lower === "unknown") {
|
|
368
|
+
return lower;
|
|
369
|
+
}
|
|
370
|
+
let result;
|
|
371
|
+
if (raw.toLowerCase().startsWith("agent:")) {
|
|
372
|
+
result = raw.toLowerCase();
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
result = `agent:${normalizeAgentId(agentId)}:${lower}`;
|
|
376
|
+
}
|
|
377
|
+
// Resolve main-alias references (e.g. agent:ops:main → configured main key).
|
|
378
|
+
const parsed = parseAgentSessionKey(result);
|
|
379
|
+
const resolvedAgent = parsed?.agentId ? normalizeAgentId(parsed.agentId) : agentId;
|
|
380
|
+
return canonicalizeMainSessionAlias({ cfg, agentId: resolvedAgent, sessionKey: result });
|
|
283
381
|
}
|
|
284
382
|
export function resolveGatewaySessionStoreTarget(params) {
|
|
285
383
|
const key = params.key.trim();
|
|
@@ -296,8 +394,26 @@ export function resolveGatewaySessionStoreTarget(params) {
|
|
|
296
394
|
}
|
|
297
395
|
const storeKeys = new Set();
|
|
298
396
|
storeKeys.add(canonicalKey);
|
|
299
|
-
if (key && key !== canonicalKey)
|
|
397
|
+
if (key && key !== canonicalKey) {
|
|
300
398
|
storeKeys.add(key);
|
|
399
|
+
}
|
|
400
|
+
if (params.scanLegacyKeys !== false) {
|
|
401
|
+
// Build a set of scan targets: all known keys plus the main alias key so we
|
|
402
|
+
// catch legacy entries stored under "agent:{id}:MAIN" when mainKey != "main".
|
|
403
|
+
const scanTargets = new Set(storeKeys);
|
|
404
|
+
const agentMainKey = resolveAgentMainSessionKey({ cfg: params.cfg, agentId });
|
|
405
|
+
if (canonicalKey === agentMainKey) {
|
|
406
|
+
scanTargets.add(`agent:${agentId}:main`);
|
|
407
|
+
}
|
|
408
|
+
// Scan the on-disk store for case variants of every target to find
|
|
409
|
+
// legacy mixed-case entries (e.g. "agent:ops:MAIN" when canonical is "agent:ops:work").
|
|
410
|
+
const store = params.store ?? loadSessionStore(storePath);
|
|
411
|
+
for (const seed of scanTargets) {
|
|
412
|
+
for (const legacyKey of findStoreKeysIgnoreCase(store, seed)) {
|
|
413
|
+
storeKeys.add(legacyKey);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
301
417
|
return {
|
|
302
418
|
agentId,
|
|
303
419
|
storePath,
|
|
@@ -307,20 +423,20 @@ export function resolveGatewaySessionStoreTarget(params) {
|
|
|
307
423
|
}
|
|
308
424
|
// Merge with existing entry based on latest timestamp to ensure data consistency and avoid overwriting with less complete data.
|
|
309
425
|
function mergeSessionEntryIntoCombined(params) {
|
|
310
|
-
const { combined, entry, agentId, canonicalKey } = params;
|
|
426
|
+
const { cfg, combined, entry, agentId, canonicalKey } = params;
|
|
311
427
|
const existing = combined[canonicalKey];
|
|
312
428
|
if (existing && (existing.updatedAt ?? 0) > (entry.updatedAt ?? 0)) {
|
|
313
429
|
combined[canonicalKey] = {
|
|
314
430
|
...entry,
|
|
315
431
|
...existing,
|
|
316
|
-
spawnedBy: canonicalizeSpawnedByForAgent(agentId, existing.spawnedBy ?? entry.spawnedBy),
|
|
432
|
+
spawnedBy: canonicalizeSpawnedByForAgent(cfg, agentId, existing.spawnedBy ?? entry.spawnedBy),
|
|
317
433
|
};
|
|
318
434
|
}
|
|
319
435
|
else {
|
|
320
436
|
combined[canonicalKey] = {
|
|
321
437
|
...existing,
|
|
322
438
|
...entry,
|
|
323
|
-
spawnedBy: canonicalizeSpawnedByForAgent(agentId, entry.spawnedBy ?? existing?.spawnedBy),
|
|
439
|
+
spawnedBy: canonicalizeSpawnedByForAgent(cfg, agentId, entry.spawnedBy ?? existing?.spawnedBy),
|
|
324
440
|
};
|
|
325
441
|
}
|
|
326
442
|
}
|
|
@@ -334,6 +450,7 @@ export function loadCombinedSessionStoreForGateway(cfg) {
|
|
|
334
450
|
for (const [key, entry] of Object.entries(store)) {
|
|
335
451
|
const canonicalKey = canonicalizeSessionKeyForAgent(defaultAgentId, key);
|
|
336
452
|
mergeSessionEntryIntoCombined({
|
|
453
|
+
cfg,
|
|
337
454
|
combined,
|
|
338
455
|
entry,
|
|
339
456
|
agentId: defaultAgentId,
|
|
@@ -350,6 +467,7 @@ export function loadCombinedSessionStoreForGateway(cfg) {
|
|
|
350
467
|
for (const [key, entry] of Object.entries(store)) {
|
|
351
468
|
const canonicalKey = canonicalizeSessionKeyForAgent(agentId, key);
|
|
352
469
|
mergeSessionEntryIntoCombined({
|
|
470
|
+
cfg,
|
|
353
471
|
combined,
|
|
354
472
|
entry,
|
|
355
473
|
agentId,
|
|
@@ -383,12 +501,38 @@ export function resolveSessionModelRef(cfg, entry, agentId) {
|
|
|
383
501
|
defaultProvider: DEFAULT_PROVIDER,
|
|
384
502
|
defaultModel: DEFAULT_MODEL,
|
|
385
503
|
});
|
|
504
|
+
// Prefer the last runtime model recorded on the session entry.
|
|
505
|
+
// This is the actual model used by the latest run and must win over defaults.
|
|
386
506
|
let provider = resolved.provider;
|
|
387
507
|
let model = resolved.model;
|
|
508
|
+
const runtimeModel = entry?.model?.trim();
|
|
509
|
+
const runtimeProvider = entry?.modelProvider?.trim();
|
|
510
|
+
if (runtimeModel) {
|
|
511
|
+
const parsedRuntime = parseModelRef(runtimeModel, runtimeProvider || provider || DEFAULT_PROVIDER);
|
|
512
|
+
if (parsedRuntime) {
|
|
513
|
+
provider = parsedRuntime.provider;
|
|
514
|
+
model = parsedRuntime.model;
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
provider = runtimeProvider || provider;
|
|
518
|
+
model = runtimeModel;
|
|
519
|
+
}
|
|
520
|
+
return { provider, model };
|
|
521
|
+
}
|
|
522
|
+
// Fall back to explicit per-session override (set at spawn/model-patch time),
|
|
523
|
+
// then finally to configured defaults.
|
|
388
524
|
const storedModelOverride = entry?.modelOverride?.trim();
|
|
389
525
|
if (storedModelOverride) {
|
|
390
|
-
|
|
391
|
-
|
|
526
|
+
const overrideProvider = entry?.providerOverride?.trim() || provider || DEFAULT_PROVIDER;
|
|
527
|
+
const parsedOverride = parseModelRef(storedModelOverride, overrideProvider);
|
|
528
|
+
if (parsedOverride) {
|
|
529
|
+
provider = parsedOverride.provider;
|
|
530
|
+
model = parsedOverride.model;
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
provider = overrideProvider;
|
|
534
|
+
model = storedModelOverride;
|
|
535
|
+
}
|
|
392
536
|
}
|
|
393
537
|
return { provider, model };
|
|
394
538
|
}
|
|
@@ -408,39 +552,46 @@ export function listSessionsFromStore(params) {
|
|
|
408
552
|
: undefined;
|
|
409
553
|
let sessions = Object.entries(store)
|
|
410
554
|
.filter(([key]) => {
|
|
411
|
-
if (isCronRunSessionKey(key))
|
|
555
|
+
if (isCronRunSessionKey(key)) {
|
|
412
556
|
return false;
|
|
413
|
-
|
|
557
|
+
}
|
|
558
|
+
if (!includeGlobal && key === "global") {
|
|
414
559
|
return false;
|
|
415
|
-
|
|
560
|
+
}
|
|
561
|
+
if (!includeUnknown && key === "unknown") {
|
|
416
562
|
return false;
|
|
563
|
+
}
|
|
417
564
|
if (agentId) {
|
|
418
|
-
if (key === "global" || key === "unknown")
|
|
565
|
+
if (key === "global" || key === "unknown") {
|
|
419
566
|
return false;
|
|
567
|
+
}
|
|
420
568
|
const parsed = parseAgentSessionKey(key);
|
|
421
|
-
if (!parsed)
|
|
569
|
+
if (!parsed) {
|
|
422
570
|
return false;
|
|
571
|
+
}
|
|
423
572
|
return normalizeAgentId(parsed.agentId) === agentId;
|
|
424
573
|
}
|
|
425
574
|
return true;
|
|
426
575
|
})
|
|
427
576
|
.filter(([key, entry]) => {
|
|
428
|
-
if (!spawnedBy)
|
|
577
|
+
if (!spawnedBy) {
|
|
429
578
|
return true;
|
|
430
|
-
|
|
579
|
+
}
|
|
580
|
+
if (key === "unknown" || key === "global") {
|
|
431
581
|
return false;
|
|
582
|
+
}
|
|
432
583
|
return entry?.spawnedBy === spawnedBy;
|
|
433
584
|
})
|
|
434
585
|
.filter(([, entry]) => {
|
|
435
|
-
if (!label)
|
|
586
|
+
if (!label) {
|
|
436
587
|
return true;
|
|
588
|
+
}
|
|
437
589
|
return entry?.label === label;
|
|
438
590
|
})
|
|
439
591
|
.map(([key, entry]) => {
|
|
440
592
|
const updatedAt = entry?.updatedAt ?? null;
|
|
441
|
-
const
|
|
442
|
-
const
|
|
443
|
-
const total = entry?.totalTokens ?? input + output;
|
|
593
|
+
const total = resolveFreshSessionTotalTokens(entry);
|
|
594
|
+
const totalTokensFresh = typeof entry?.totalTokens === "number" ? entry?.totalTokensFresh !== false : false;
|
|
444
595
|
const parsed = parseGroupKey(key);
|
|
445
596
|
const channel = entry?.channel ?? parsed?.channel;
|
|
446
597
|
const subject = entry?.subject;
|
|
@@ -492,6 +643,7 @@ export function listSessionsFromStore(params) {
|
|
|
492
643
|
inputTokens: entry?.inputTokens,
|
|
493
644
|
outputTokens: entry?.outputTokens,
|
|
494
645
|
totalTokens: total,
|
|
646
|
+
totalTokensFresh,
|
|
495
647
|
responseUsage: entry?.responseUsage,
|
|
496
648
|
modelProvider,
|
|
497
649
|
model,
|
|
@@ -522,14 +674,16 @@ export function listSessionsFromStore(params) {
|
|
|
522
674
|
let derivedTitle;
|
|
523
675
|
let lastMessagePreview;
|
|
524
676
|
if (entry?.sessionId) {
|
|
525
|
-
if (includeDerivedTitles) {
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
677
|
+
if (includeDerivedTitles || includeLastMessage) {
|
|
678
|
+
const parsed = parseAgentSessionKey(s.key);
|
|
679
|
+
const agentId = parsed && parsed.agentId ? normalizeAgentId(parsed.agentId) : resolveDefaultAgentId(cfg);
|
|
680
|
+
const fields = readSessionTitleFieldsFromTranscript(entry.sessionId, storePath, entry.sessionFile, agentId);
|
|
681
|
+
if (includeDerivedTitles) {
|
|
682
|
+
derivedTitle = deriveSessionTitle(entry, fields.firstUserMessage);
|
|
683
|
+
}
|
|
684
|
+
if (includeLastMessage && fields.lastMessagePreview) {
|
|
685
|
+
lastMessagePreview = fields.lastMessagePreview;
|
|
686
|
+
}
|
|
533
687
|
}
|
|
534
688
|
}
|
|
535
689
|
return { ...rest, derivedTitle, lastMessagePreview };
|