switchroom 0.20.11 → 0.20.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-scheduler/index.js +5 -2
- package/dist/auth-broker/index.js +32 -25
- package/dist/cli/notion-write-pretool.mjs +5 -2
- package/dist/cli/self-improve-stop.mjs +13 -1
- package/dist/cli/switchroom.js +3069 -1146
- package/dist/host-control/main.js +33 -26
- package/dist/vault/approvals/kernel-server.js +32 -25
- package/dist/vault/broker/server.js +32 -25
- package/examples/personal-google-workspace-mcp/compose.yaml +1 -1
- package/package.json +7 -4
- package/skills/switchroom-architecture/telegram.md +0 -1
- package/skills/switchroom-cli/SKILL.md +0 -1
- package/skills/switchroom-release/SKILL.md +3 -2
- package/telegram-plugin/README.md +2 -11
- package/telegram-plugin/bridge/bridge.ts +0 -12
- package/telegram-plugin/bunfig.toml +9 -5
- package/telegram-plugin/chat-lock.ts +1 -1
- package/telegram-plugin/dist/bridge/bridge.js +0 -12
- package/telegram-plugin/dist/gateway/gateway.js +219 -127
- package/telegram-plugin/dist/server.js +0 -12
- package/telegram-plugin/gateway/captured-answer-resume.ts +23 -1
- package/telegram-plugin/gateway/gateway.ts +25 -59
- package/telegram-plugin/gateway/liveness-wiring.ts +6 -1
- package/telegram-plugin/gateway/outbound-send-path.ts +111 -6
- package/telegram-plugin/gateway/outbox-sweep.ts +69 -0
- package/telegram-plugin/gateway/stale-pin-sweep.ts +4 -3
- package/telegram-plugin/gateway/status-pin-store.ts +10 -9
- package/telegram-plugin/gateway/stream-render.ts +8 -4
- package/telegram-plugin/gateway/turn-record-status.ts +32 -1
- package/telegram-plugin/hooks/audience-classify.d.mts +26 -0
- package/telegram-plugin/hooks/audience-classify.mjs +193 -0
- package/telegram-plugin/hooks/hooks.json +13 -12
- package/telegram-plugin/hooks/narration-classify.mjs +1 -2
- package/telegram-plugin/hooks/silent-end-interrupt-stop.mjs +31 -1
- package/telegram-plugin/hooks/silent-end-scan.mjs +9 -2
- package/telegram-plugin/outbox.ts +69 -3
- package/telegram-plugin/silent-end.ts +48 -5
- package/telegram-plugin/status-pin.ts +2 -5
- package/telegram-plugin/tests/backstop-exactly-once.test.ts +8 -2
- package/telegram-plugin/tests/captured-answer-resume.test.ts +26 -11
- package/telegram-plugin/tests/framework-fallback-duration-guard.test.ts +125 -0
- package/telegram-plugin/tests/hindsight-bank-preload.test.ts +50 -0
- package/telegram-plugin/tests/outbox-live-path-review-4490.test.ts +613 -0
- package/telegram-plugin/tests/outbox-self-improve-review.test.ts +401 -0
- package/telegram-plugin/tests/pin-message-tool-retired.test.ts +64 -0
- package/telegram-plugin/tests/status-pin-boot-recovery.test.ts +38 -0
- package/telegram-plugin/tests/worker-activity-feed.test.ts +40 -1
- package/telegram-plugin/worker-activity-feed.ts +1 -1
- package/vendor/hindsight-memory/scripts/recall.py +140 -0
- package/vendor/hindsight-memory/scripts/tests/test_recall_latency_instrumentation.py +277 -0
|
@@ -11433,6 +11433,7 @@ var init_schema = __esm(() => {
|
|
|
11433
11433
|
}).describe("Per-operation LLM override. Every field optional; an unset field (or " + "an omitted op block) inherits the global `hindsight.llm.*`, which is " + "already the engine's fallback — switchroom emits only the vars set.");
|
|
11434
11434
|
HindsightConfigSchema = exports_external.object({
|
|
11435
11435
|
gpu: exports_external.boolean().optional().describe("Force GPU passthrough for the hindsight container on (`true`) or off " + "(`false`), overriding host autodetection in BOTH directions. Absent " + "(the default) → autodetect from the persisted host-capabilities " + "verdict (`~/.switchroom/host-capabilities.json`), which enables " + "`--gpus all` only when that file proves BOTH a GPU and the nvidia " + "container toolkit. Set `true` when that verdict is wrong or unreadable " + "and you know the host has a working toolkit — switchroom cannot verify " + "it for you, and `docker run --gpus all` hard-fails container create on " + "a host without one. Set `false` to pin the container to CPU on a GPU " + "host. This is also the declarative opt-out for the recreate-time GPU " + "drop guard (`switchroom memory setup --recreate` refuses to silently " + "turn a GPU container into a CPU one). `--gpu`/`--no-gpu` on `memory " + "setup` override this for a single run."),
|
|
11436
|
+
mem_limit: exports_external.string().regex(/^\d+(\.\d+)?\s*[bkmgt]?b?$/i, "hindsight.mem_limit must be a docker memory size, e.g. `24g` or `16384m`").optional().describe("Hard memory cap for the hindsight container — docker `--memory` on the " + "`memory setup` path and `mem_limit:` in the emitted compose snippet. A " + "docker size string (`24g`, `16384m`). Absent → switchroom's default " + "(`HINDSIGHT_DEFAULT_MEM_LIMIT`, 16g). This is a docker HostConfig flag, " + "not a container env var, which is why it is a first-class field here " + "rather than an `env:` key. **Move it together with " + "`env.SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS`**: Postgres pins the " + "buffer pool as unreclaimable shared memory inside this cap, so a cap " + "that does not clear `shared_buffers` by the container's app working " + "set plus its page-cache floor puts Postgres in a near-OOM " + "configuration. switchroom warns, naming both numbers, when it does " + "not. A value below the container's memory RESERVATION (4g) is " + "rejected outright — docker will not create such a container."),
|
|
11436
11437
|
cp_access_key: exports_external.string().min(1).optional().describe("Access key for the hindsight control-plane DASHBOARD (upstream " + "`HINDSIGHT_CP_ACCESS_KEY`, port 9999). Literal or — strongly preferred " + "— a `vault:` reference such as `vault:hindsight_cp_access_key`, read " + "through the broker at container-launch time. This is the ONLY thing " + "that arms the dashboard's login: upstream's middleware short-circuits " + "to `next()` when the var is unset, so an unset key means the dashboard " + "has no authentication at all, not weak authentication. Because of that, " + "leaving it unset is FAIL-CLOSED: switchroom pins " + "`HINDSIGHT_CP_HOSTNAME=127.0.0.1` so the loginless dashboard is " + "reachable only from the host, and warns. Set this to serve the " + "dashboard on the LAN/tailnet."),
|
|
11437
11438
|
llm: exports_external.object({
|
|
11438
11439
|
provider: exports_external.string().min(1).optional().describe("Hindsight LLM provider (upstream `HINDSIGHT_API_LLM_PROVIDER`). " + "Defaults to `claude-code` (subscription-honest, broker-fed OAuth). " + "Any litellm-routable provider the upstream image supports is valid. " + "Serves as the GLOBAL default for every op absent a per-op override."),
|
|
@@ -11444,7 +11445,7 @@ var init_schema = __esm(() => {
|
|
|
11444
11445
|
reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent → uses global."),
|
|
11445
11446
|
consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent → global.")
|
|
11446
11447
|
}).optional().describe("LLM knob for the hindsight container. The flat `provider`/`model` set " + "the global default (backward-compatible); optional `retain`/`reflect`/" + "`consolidation` blocks override individual ops. All fields optional; " + "unset fields fall back to the hard-coded defaults."),
|
|
11447
|
-
env: exports_external.record(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()])).optional().describe("Operator overrides for switchroom's capability-gated Hindsight " + "performance defaults. Only the keys switchroom actually manages are " + "honoured (`HINDSIGHT_PERF_ENV_KEYS` in " + "src/setup/hindsight-perf-defaults.ts: RERANKER_LOCAL_FP16, " + "RERANKER_LOCAL_BATCH_SIZE, LLM_MAX_CONCURRENT, " + "RETAIN/CONSOLIDATION_LLM_MAX_CONCURRENT, LLM_STRICT_SCHEMA, " + "LLM_MAX_RETRIES, CONSOLIDATION_LLM_PARALLELISM, " + "MAX_OBSERVATIONS_PER_SCOPE, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT, " + "RERANKER_LOCAL_BUCKET_BATCHING, RERANKER_MAX_CANDIDATES, " + "RERANKER_LOCAL_MAX_CONCURRENT, RECALL_MAX_CONCURRENT, " + "REFLECT_WALL_TIMEOUT, WORKER_CONSOLIDATION_RESERVED_SLOTS, " + "WORKER_CONSOLIDATION_SLOT_LIMIT, " + "CONSOLIDATION_MAX_MEMORIES_PER_ROUND, GRAPH_SEED_MIN_SIMILARITY, " + "LLM_SUPPORTS_MAX_ITEMS, RECENCY_DECAY_FUNCTION, " + "RECENCY_DECAY_HALFLIFE_DAYS — switchroom defaults recall's recency " + "curve to `exponential` with a 30-day half-life so a fact retained " + "today outranks a stale one, instead of upstream's near-flat " + "linear/365-day window), the override-only keys " + "switchroom manages but ships NO default for " + "(`HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS`: " + "HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY — a per-deployment " + "`bank-pattern:priority,...` map; unset means upstream's flat " + "created_at FIFO across banks; and " + "HINDSIGHT_CE_DECISIVE_RELATIVE_GAP — the rollback knob for " + "switchroom's CE-saturation damping patch, a float; >= ~0.65 backs the " + "damping out entirely, unset means the patch's own derived gap; and " + "HINDSIGHT_API_RECENCY_DECAY_LINEAR_WINDOW_DAYS — only read when the " + "decay function is `linear`, so switchroom ships no default for it but " + "still honours an operator who flips the function back; and " + "HINDSIGHT_API_WORKER_MAX_SLOTS — the worker poller's TOTAL in-flight " + "task budget, the pool WORKER_CONSOLIDATION_RESERVED_SLOTS reserves out of; " + "unset means upstream's own default; and " + "HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS — the reserved slot FLOOR for the " + "retain (memory write) lane, carved from that same total; unset means " + "upstream's own 0, i.e. no floor and retain competes for the shared " + "pool; and " + "the pre-0.8.6 name HINDSIGHT_API_WORKER_<TYPE>_MAX_SLOTS is still " + "accepted for every operation type and normalised to " + "..._RESERVED_SLOTS on the way in, because setting both names for " + "one type is a hard boot failure in the engine and switchroom " + "therefore emits only the canonical name; and " + "HINDSIGHT_API_SEMANTIC_MIN_SIMILARITY — the cosine-similarity floor a " + "candidate must reach to be returned by the semantic retrieval arm at " + "all (0..1); unset means upstream's own 0.3, and where it should sit " + "depends on the bank's embedding model and phrasing diversity, so " + "switchroom ships no opinion; and " + "HINDSIGHT_MCP_RECALL_BUDGET_MODE — the rollback knob for switchroom's " + "mcp-recall-token-budget image patch; `legacy` restores upstream's " + "exact pre-patch recall returns, anything else or unset is the " + "honest-envelope mode; and " + "HINDSIGHT_API_LLM_TEMPERATURE_REFLECT — upstream's own per-op reflect " + "temperature knob, made live by switchroom's reflect-temperature image " + "patch; a float, or `none` to omit the kwarg (provider default, " + "upstream's accidental pre-patch behaviour); unset means the image's " + "baked default 0.1; and " + "HINDSIGHT_API_CONSOLIDATION_RECALL_MAX_CONCURRENT — the background " + "half of switchroom's recall-admission split (#3660): of the " + "RECALL_MAX_CONCURRENT admission slots, at most this many may be held " + "by background consolidation recalls at once, so foreground per-turn " + "recall always keeps the remainder; must be >= 1 and strictly less " + "than RECALL_MAX_CONCURRENT or the engine refuses to boot; unset " + "means the image's derived default min(2, RECALL_MAX_CONCURRENT - 1); " + "1 biases hard toward the interactive lane while a consolidation " + "backlog drains; and " + "HINDSIGHT_MM_REFRESH_MIN_INTERVAL_S — the rollback/tuning knob for " + "switchroom's MM-refresh-debounce image patch: the minimum seconds " + "between consolidation-triggered refreshes of one mental model; unset " + "means the image's baked 3600, 0 restores upstream's " + "refresh-every-round behaviour; explicit and cron-scheduled refreshes " + "are never debounced; and " + "HINDSIGHT_API_TEMPORAL_LANGUAGES — the language set dateparser is " + "restricted to during temporal query analysis, made live by switchroom's " + "temporal-language image patch (which ended a 200+-locale auto-detection " + "pass that blocked the shared asyncio loop on every recall); " + "comma-separated, unset means the image's baked `en`, set e.g. `en,es` to " + "restore i18n parsing; and " + "HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS — the max chars of query text " + "dateparser.search_dates() is handed during temporal analysis (0 = " + "unlimited), made live by switchroom's temporal-offload image patch " + "(which moved the synchronous extraction off the shared asyncio loop onto " + "a single-worker thread and bounds its input, ending multi-second loop " + "stalls on multi-KB consolidation queries); unset means the image's baked " + "2000, set 0 to restore an unbounded full scan), plus the " + "embedded-PostgreSQL (pg0) sizing keys switchroom manages in " + "src/setup/hindsight-pg-defaults.ts (`HINDSIGHT_PG_ENV_KEYS`: " + "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE, " + "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS — a postgres size string such " + "as `4GB`, or the sentinel `off` to leave pg0's own default for that " + "one knob). A value set here " + "REPLACES switchroom's default and is emitted even when the gating " + "capability is absent, so an operator can always force a knob. Other " + "`HINDSIGHT_API_*` keys are deliberately IGNORED — a blanket " + "passthrough would collide with the vars startHindsight() derives " + "itself (HINDSIGHT_API_PORT, the retain token/deadline budget).")
|
|
11448
|
+
env: exports_external.record(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()])).optional().describe("Operator overrides for switchroom's capability-gated Hindsight " + "performance defaults. Only the keys switchroom actually manages are " + "honoured (`HINDSIGHT_PERF_ENV_KEYS` in " + "src/setup/hindsight-perf-defaults.ts: RERANKER_LOCAL_FP16, " + "RERANKER_LOCAL_BATCH_SIZE, LLM_MAX_CONCURRENT, " + "RETAIN/CONSOLIDATION_LLM_MAX_CONCURRENT, LLM_STRICT_SCHEMA, " + "LLM_MAX_RETRIES, CONSOLIDATION_LLM_PARALLELISM, " + "MAX_OBSERVATIONS_PER_SCOPE, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT, " + "RERANKER_LOCAL_BUCKET_BATCHING, RERANKER_MAX_CANDIDATES, " + "RERANKER_LOCAL_MAX_CONCURRENT, RECALL_MAX_CONCURRENT, " + "REFLECT_WALL_TIMEOUT, WORKER_CONSOLIDATION_RESERVED_SLOTS, " + "WORKER_CONSOLIDATION_SLOT_LIMIT, " + "CONSOLIDATION_MAX_MEMORIES_PER_ROUND, GRAPH_SEED_MIN_SIMILARITY, " + "LLM_SUPPORTS_MAX_ITEMS, RECENCY_DECAY_FUNCTION, " + "RECENCY_DECAY_HALFLIFE_DAYS — switchroom defaults recall's recency " + "curve to `exponential` with a 30-day half-life so a fact retained " + "today outranks a stale one, instead of upstream's near-flat " + "linear/365-day window), the override-only keys " + "switchroom manages but ships NO default for " + "(`HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS`: " + "HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY — a per-deployment " + "`bank-pattern:priority,...` map; unset means upstream's flat " + "created_at FIFO across banks; and " + "HINDSIGHT_CE_DECISIVE_RELATIVE_GAP — the rollback knob for " + "switchroom's CE-saturation damping patch, a float; >= ~0.65 backs the " + "damping out entirely, unset means the patch's own derived gap; and " + "HINDSIGHT_API_RECENCY_DECAY_LINEAR_WINDOW_DAYS — only read when the " + "decay function is `linear`, so switchroom ships no default for it but " + "still honours an operator who flips the function back; and " + "HINDSIGHT_API_WORKER_MAX_SLOTS — the worker poller's TOTAL in-flight " + "task budget, the pool WORKER_CONSOLIDATION_RESERVED_SLOTS reserves out of; " + "unset means upstream's own default; and " + "HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS — the reserved slot FLOOR for the " + "retain (memory write) lane, carved from that same total; unset means " + "upstream's own 0, i.e. no floor and retain competes for the shared " + "pool; and " + "the pre-0.8.6 name HINDSIGHT_API_WORKER_<TYPE>_MAX_SLOTS is still " + "accepted for every operation type and normalised to " + "..._RESERVED_SLOTS on the way in, because setting both names for " + "one type is a hard boot failure in the engine and switchroom " + "therefore emits only the canonical name; and " + "HINDSIGHT_API_SEMANTIC_MIN_SIMILARITY — the cosine-similarity floor a " + "candidate must reach to be returned by the semantic retrieval arm at " + "all (0..1); unset means upstream's own 0.3, and where it should sit " + "depends on the bank's embedding model and phrasing diversity, so " + "switchroom ships no opinion; and " + "HINDSIGHT_MCP_RECALL_BUDGET_MODE — the rollback knob for switchroom's " + "mcp-recall-token-budget image patch; `legacy` restores upstream's " + "exact pre-patch recall returns, anything else or unset is the " + "honest-envelope mode; and " + "HINDSIGHT_API_LLM_TEMPERATURE_REFLECT — upstream's own per-op reflect " + "temperature knob, made live by switchroom's reflect-temperature image " + "patch; a float, or `none` to omit the kwarg (provider default, " + "upstream's accidental pre-patch behaviour); unset means the image's " + "baked default 0.1; and " + "HINDSIGHT_API_CONSOLIDATION_RECALL_MAX_CONCURRENT — the background " + "half of switchroom's recall-admission split (#3660): of the " + "RECALL_MAX_CONCURRENT admission slots, at most this many may be held " + "by background consolidation recalls at once, so foreground per-turn " + "recall always keeps the remainder; must be >= 1 and strictly less " + "than RECALL_MAX_CONCURRENT or the engine refuses to boot; unset " + "means the image's derived default min(2, RECALL_MAX_CONCURRENT - 1); " + "1 biases hard toward the interactive lane while a consolidation " + "backlog drains; and " + "HINDSIGHT_MM_REFRESH_MIN_INTERVAL_S — the rollback/tuning knob for " + "switchroom's MM-refresh-debounce image patch: the minimum seconds " + "between consolidation-triggered refreshes of one mental model; unset " + "means the image's baked 3600, 0 restores upstream's " + "refresh-every-round behaviour; explicit and cron-scheduled refreshes " + "are never debounced; and " + "HINDSIGHT_API_TEMPORAL_LANGUAGES — the language set dateparser is " + "restricted to during temporal query analysis, made live by switchroom's " + "temporal-language image patch (which ended a 200+-locale auto-detection " + "pass that blocked the shared asyncio loop on every recall); " + "comma-separated, unset means the image's baked `en`, set e.g. `en,es` to " + "restore i18n parsing; and " + "HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS — the max chars of query text " + "dateparser.search_dates() is handed during temporal analysis (0 = " + "unlimited), made live by switchroom's temporal-offload image patch " + "(which moved the synchronous extraction off the shared asyncio loop onto " + "a single-worker thread and bounds its input, ending multi-second loop " + "stalls on multi-KB consolidation queries); unset means the image's baked " + "2000, set 0 to restore an unbounded full scan); and " + "HINDSIGHT_API_TEXT_SEARCH_EXTENSION_NATIVE_LANGUAGE — the Postgres " + "text-search regconfig the native BM25 arms and the search_vector index " + "write run to_tsvector/to_tsquery against; unset means upstream's " + "always-safe `english`, set `hindsight_english` to use switchroom's " + "junk-stopping config (dict + stopword file provisioned durably by the " + "image entrypoint, recall degrading to semantic-only if it is ever " + "missing); plus the " + "embedded-PostgreSQL (pg0) sizing keys switchroom manages in " + "src/setup/hindsight-pg-defaults.ts (`HINDSIGHT_PG_ENV_KEYS`: " + "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE, " + "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS — a postgres size string such " + "as `4GB`, or the sentinel `off` to leave pg0's own default for that " + "one knob). A value set here " + "REPLACES switchroom's default and is emitted even when the gating " + "capability is absent, so an operator can always force a knob. Other " + "`HINDSIGHT_API_*` keys are deliberately IGNORED — a blanket " + "passthrough would collide with the vars startHindsight() derives " + "itself (HINDSIGHT_API_PORT, the retain token/deadline budget).")
|
|
11448
11449
|
});
|
|
11449
11450
|
MicrosoftWorkspaceConfigSchema = exports_external.object({
|
|
11450
11451
|
microsoft_client_id: exports_external.string().min(1).optional().describe("Microsoft OAuth application (client) ID from Entra portal " + "(literal string or vault reference e.g. " + "'vault:microsoft-oauth-client-id'). OPTIONAL — omit it to use " + "switchroom's shipped default Microsoft app (zero-config). " + "Set it only to bring your own Entra app (BYO)."),
|
|
@@ -11897,7 +11898,9 @@ var init_schema = __esm(() => {
|
|
|
11897
11898
|
path: exports_external.string().regex(/^[a-zA-Z0-9~._\-/]+$/, "config_repo.path must not contain shell-special characters ($, `, \", ', \\, etc.)").default("~/.switchroom-config").describe("Filesystem path to the operator's private config repo. Must be a git " + "repo (else `switchroom doctor` FAILs). Tilde-expanded at read time."),
|
|
11898
11899
|
push: exports_external.boolean().default(true).describe("When true, `config-repo sync` pushes after committing (subject to the " + "`require_private` gate). When false, it commits locally only — useful " + "for offline hosts or a review-before-push workflow."),
|
|
11899
11900
|
remote: exports_external.string().min(1).default("origin").describe("Git remote name to push to. Default `origin`."),
|
|
11900
|
-
require_private: exports_external.boolean().default(true).describe("Refuse to PUSH unless the GitHub API confirms the remote repo is " + "private. On a public remote — or when the API is unreachable — the " + "push is skipped (commits still land locally) and a WARN is emitted. " + "Fail-safe against exfiltrating memory files / workspace state to a " + "repo that has been flipped public. Default true.")
|
|
11901
|
+
require_private: exports_external.boolean().default(true).describe("Refuse to PUSH unless the GitHub API confirms the remote repo is " + "private. On a public remote — or when the API is unreachable — the " + "push is skipped (commits still land locally) and a WARN is emitted. " + "Fail-safe against exfiltrating memory files / workspace state to a " + "repo that has been flipped public. Default true."),
|
|
11902
|
+
interval_minutes: exports_external.number().int().min(5).max(59).default(30).describe("Cadence (minutes) of the scheduled `config-repo sync` tick installed " + "by `switchroom config-repo --install-cron`. Rendered as a cron " + "`*/N * * * *` minute field, so it must be 5..59 (the 5-min floor " + "matches the rest of the fleet's cron floor). Default 30 (Ken's " + "approved cadence). Changing it takes effect on the next " + "`--install-cron` / `switchroom update` reconcile."),
|
|
11903
|
+
include_vault_backup: exports_external.enum(["off", "daily", "every_tick"]).default("daily").describe("Whether the scheduled tick also runs `switchroom vault backup` " + "(an encrypted vault/memory snapshot into <path>/vault-backups/) " + "before the sync. `off`: sync only. `daily`: an extra once-per-day " + "cron leg runs `vault backup && config-repo sync` (the 30-min legs " + "stay sync-only). `every_tick`: every tick runs the backup first. " + "Default `daily` — the first automated vault backup on this host.")
|
|
11901
11904
|
});
|
|
11902
11905
|
SwitchroomConfigSchema = exports_external.object({
|
|
11903
11906
|
switchroom: exports_external.object({
|
|
@@ -21556,7 +21559,28 @@ function allocateAgentUid(name) {
|
|
|
21556
21559
|
}
|
|
21557
21560
|
|
|
21558
21561
|
// src/build-info.ts
|
|
21559
|
-
var VERSION = "0.20.
|
|
21562
|
+
var VERSION = "0.20.13";
|
|
21563
|
+
|
|
21564
|
+
// src/setup/hindsight-recall-passthrough.ts
|
|
21565
|
+
var HINDSIGHT_RECALL_TAG_WEIGHT_SEED = Object.freeze({ sidechain: 0.8 });
|
|
21566
|
+
var HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT = "Relevant memories from past conversations (prioritize recent when " + "conflicting). Only use memories that are directly useful to continue " + "this conversation; ignore the rest:";
|
|
21567
|
+
var RECALL_PASSTHROUGH_DEFAULTS = Object.freeze({
|
|
21568
|
+
budget: "low",
|
|
21569
|
+
maxTokens: 1024,
|
|
21570
|
+
preferObservations: true,
|
|
21571
|
+
contextTurns: 2,
|
|
21572
|
+
roles: ["user", "assistant"],
|
|
21573
|
+
promptPreamble: HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT,
|
|
21574
|
+
tags: [],
|
|
21575
|
+
tagsMatch: "any",
|
|
21576
|
+
tagGroups: {},
|
|
21577
|
+
tagWeights: HINDSIGHT_RECALL_TAG_WEIGHT_SEED,
|
|
21578
|
+
additionalBankFilters: {},
|
|
21579
|
+
transcriptFallback: true,
|
|
21580
|
+
transcriptTailBytes: 262144,
|
|
21581
|
+
maxQueryChars: 800,
|
|
21582
|
+
parallel: true
|
|
21583
|
+
});
|
|
21560
21584
|
|
|
21561
21585
|
// src/setup/hindsight-recall-tunables.ts
|
|
21562
21586
|
var RECALL_DEADLINE_HEADROOM_SECONDS = 2;
|
|
@@ -21685,6 +21709,7 @@ var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB = 12288;
|
|
|
21685
21709
|
function pgMib(mib) {
|
|
21686
21710
|
return `${mib}MB`;
|
|
21687
21711
|
}
|
|
21712
|
+
var HINDSIGHT_PG_MIN_NON_BUFFER_MIB = HINDSIGHT_PG_APP_ANON_MIB + HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB;
|
|
21688
21713
|
var HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE_ENV = "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE";
|
|
21689
21714
|
var HINDSIGHT_PG_SHARED_BUFFERS_ENV = "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS";
|
|
21690
21715
|
var HINDSIGHT_PG_FSYNC_ENV = "SWITCHROOM_HINDSIGHT_PG_FSYNC";
|
|
@@ -21732,6 +21757,7 @@ var HINDSIGHT_DEFAULT_GRAPH_SEED_MIN_SIMILARITY = 0.3;
|
|
|
21732
21757
|
var HINDSIGHT_DEFAULT_LLM_SUPPORTS_MAX_ITEMS = "false";
|
|
21733
21758
|
var HINDSIGHT_DEFAULT_RECENCY_DECAY_FUNCTION = "exponential";
|
|
21734
21759
|
var HINDSIGHT_DEFAULT_RECENCY_DECAY_HALFLIFE_DAYS = 30;
|
|
21760
|
+
var HINDSIGHT_DEFAULT_TEXT_SEARCH_EXTENSION = "pg_search";
|
|
21735
21761
|
var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
21736
21762
|
[
|
|
21737
21763
|
"HINDSIGHT_API_RECALL_MAX_CANDIDATES_PER_SOURCE",
|
|
@@ -21797,7 +21823,8 @@ var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
|
21797
21823
|
[
|
|
21798
21824
|
"HINDSIGHT_API_GRAPH_SEED_MIN_SIMILARITY",
|
|
21799
21825
|
String(HINDSIGHT_DEFAULT_GRAPH_SEED_MIN_SIMILARITY)
|
|
21800
|
-
]
|
|
21826
|
+
],
|
|
21827
|
+
["HINDSIGHT_API_TEXT_SEARCH_EXTENSION", HINDSIGHT_DEFAULT_TEXT_SEARCH_EXTENSION]
|
|
21801
21828
|
];
|
|
21802
21829
|
var HINDSIGHT_PERF_DEFAULTS_GPU = [
|
|
21803
21830
|
["HINDSIGHT_API_RERANKER_LOCAL_FP16", HINDSIGHT_DEFAULT_RERANKER_LOCAL_FP16],
|
|
@@ -21833,7 +21860,8 @@ var HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS = new Set([
|
|
|
21833
21860
|
"HINDSIGHT_API_CONSOLIDATION_RECALL_MAX_CONCURRENT",
|
|
21834
21861
|
"HINDSIGHT_MM_REFRESH_MIN_INTERVAL_S",
|
|
21835
21862
|
"HINDSIGHT_API_TEMPORAL_LANGUAGES",
|
|
21836
|
-
"HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS"
|
|
21863
|
+
"HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS",
|
|
21864
|
+
"HINDSIGHT_API_TEXT_SEARCH_EXTENSION_NATIVE_LANGUAGE"
|
|
21837
21865
|
]);
|
|
21838
21866
|
var HINDSIGHT_WORKER_SLOT_TYPES = [
|
|
21839
21867
|
"consolidation",
|
|
@@ -22255,27 +22283,6 @@ init_vault();
|
|
|
22255
22283
|
// src/setup/onboarding.ts
|
|
22256
22284
|
init_paths();
|
|
22257
22285
|
|
|
22258
|
-
// src/setup/hindsight-recall-passthrough.ts
|
|
22259
|
-
var HINDSIGHT_RECALL_TAG_WEIGHT_SEED = Object.freeze({ sidechain: 0.8 });
|
|
22260
|
-
var HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT = "Relevant memories from past conversations (prioritize recent when " + "conflicting). Only use memories that are directly useful to continue " + "this conversation; ignore the rest:";
|
|
22261
|
-
var RECALL_PASSTHROUGH_DEFAULTS = Object.freeze({
|
|
22262
|
-
budget: "low",
|
|
22263
|
-
maxTokens: 1024,
|
|
22264
|
-
preferObservations: true,
|
|
22265
|
-
contextTurns: 2,
|
|
22266
|
-
roles: ["user", "assistant"],
|
|
22267
|
-
promptPreamble: HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT,
|
|
22268
|
-
tags: [],
|
|
22269
|
-
tagsMatch: "any",
|
|
22270
|
-
tagGroups: {},
|
|
22271
|
-
tagWeights: HINDSIGHT_RECALL_TAG_WEIGHT_SEED,
|
|
22272
|
-
additionalBankFilters: {},
|
|
22273
|
-
transcriptFallback: true,
|
|
22274
|
-
transcriptTailBytes: 262144,
|
|
22275
|
-
maxQueryChars: 800,
|
|
22276
|
-
parallel: true
|
|
22277
|
-
});
|
|
22278
|
-
|
|
22279
22286
|
// src/repos/bare-clone.ts
|
|
22280
22287
|
init_paths();
|
|
22281
22288
|
|
|
@@ -4873,6 +4873,7 @@ var init_schema = __esm(() => {
|
|
|
4873
4873
|
}).describe("Per-operation LLM override. Every field optional; an unset field (or " + "an omitted op block) inherits the global `hindsight.llm.*`, which is " + "already the engine's fallback — switchroom emits only the vars set.");
|
|
4874
4874
|
HindsightConfigSchema = exports_external.object({
|
|
4875
4875
|
gpu: exports_external.boolean().optional().describe("Force GPU passthrough for the hindsight container on (`true`) or off " + "(`false`), overriding host autodetection in BOTH directions. Absent " + "(the default) → autodetect from the persisted host-capabilities " + "verdict (`~/.switchroom/host-capabilities.json`), which enables " + "`--gpus all` only when that file proves BOTH a GPU and the nvidia " + "container toolkit. Set `true` when that verdict is wrong or unreadable " + "and you know the host has a working toolkit — switchroom cannot verify " + "it for you, and `docker run --gpus all` hard-fails container create on " + "a host without one. Set `false` to pin the container to CPU on a GPU " + "host. This is also the declarative opt-out for the recreate-time GPU " + "drop guard (`switchroom memory setup --recreate` refuses to silently " + "turn a GPU container into a CPU one). `--gpu`/`--no-gpu` on `memory " + "setup` override this for a single run."),
|
|
4876
|
+
mem_limit: exports_external.string().regex(/^\d+(\.\d+)?\s*[bkmgt]?b?$/i, "hindsight.mem_limit must be a docker memory size, e.g. `24g` or `16384m`").optional().describe("Hard memory cap for the hindsight container — docker `--memory` on the " + "`memory setup` path and `mem_limit:` in the emitted compose snippet. A " + "docker size string (`24g`, `16384m`). Absent → switchroom's default " + "(`HINDSIGHT_DEFAULT_MEM_LIMIT`, 16g). This is a docker HostConfig flag, " + "not a container env var, which is why it is a first-class field here " + "rather than an `env:` key. **Move it together with " + "`env.SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS`**: Postgres pins the " + "buffer pool as unreclaimable shared memory inside this cap, so a cap " + "that does not clear `shared_buffers` by the container's app working " + "set plus its page-cache floor puts Postgres in a near-OOM " + "configuration. switchroom warns, naming both numbers, when it does " + "not. A value below the container's memory RESERVATION (4g) is " + "rejected outright — docker will not create such a container."),
|
|
4876
4877
|
cp_access_key: exports_external.string().min(1).optional().describe("Access key for the hindsight control-plane DASHBOARD (upstream " + "`HINDSIGHT_CP_ACCESS_KEY`, port 9999). Literal or — strongly preferred " + "— a `vault:` reference such as `vault:hindsight_cp_access_key`, read " + "through the broker at container-launch time. This is the ONLY thing " + "that arms the dashboard's login: upstream's middleware short-circuits " + "to `next()` when the var is unset, so an unset key means the dashboard " + "has no authentication at all, not weak authentication. Because of that, " + "leaving it unset is FAIL-CLOSED: switchroom pins " + "`HINDSIGHT_CP_HOSTNAME=127.0.0.1` so the loginless dashboard is " + "reachable only from the host, and warns. Set this to serve the " + "dashboard on the LAN/tailnet."),
|
|
4877
4878
|
llm: exports_external.object({
|
|
4878
4879
|
provider: exports_external.string().min(1).optional().describe("Hindsight LLM provider (upstream `HINDSIGHT_API_LLM_PROVIDER`). " + "Defaults to `claude-code` (subscription-honest, broker-fed OAuth). " + "Any litellm-routable provider the upstream image supports is valid. " + "Serves as the GLOBAL default for every op absent a per-op override."),
|
|
@@ -4884,7 +4885,7 @@ var init_schema = __esm(() => {
|
|
|
4884
4885
|
reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent → uses global."),
|
|
4885
4886
|
consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent → global.")
|
|
4886
4887
|
}).optional().describe("LLM knob for the hindsight container. The flat `provider`/`model` set " + "the global default (backward-compatible); optional `retain`/`reflect`/" + "`consolidation` blocks override individual ops. All fields optional; " + "unset fields fall back to the hard-coded defaults."),
|
|
4887
|
-
env: exports_external.record(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()])).optional().describe("Operator overrides for switchroom's capability-gated Hindsight " + "performance defaults. Only the keys switchroom actually manages are " + "honoured (`HINDSIGHT_PERF_ENV_KEYS` in " + "src/setup/hindsight-perf-defaults.ts: RERANKER_LOCAL_FP16, " + "RERANKER_LOCAL_BATCH_SIZE, LLM_MAX_CONCURRENT, " + "RETAIN/CONSOLIDATION_LLM_MAX_CONCURRENT, LLM_STRICT_SCHEMA, " + "LLM_MAX_RETRIES, CONSOLIDATION_LLM_PARALLELISM, " + "MAX_OBSERVATIONS_PER_SCOPE, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT, " + "RERANKER_LOCAL_BUCKET_BATCHING, RERANKER_MAX_CANDIDATES, " + "RERANKER_LOCAL_MAX_CONCURRENT, RECALL_MAX_CONCURRENT, " + "REFLECT_WALL_TIMEOUT, WORKER_CONSOLIDATION_RESERVED_SLOTS, " + "WORKER_CONSOLIDATION_SLOT_LIMIT, " + "CONSOLIDATION_MAX_MEMORIES_PER_ROUND, GRAPH_SEED_MIN_SIMILARITY, " + "LLM_SUPPORTS_MAX_ITEMS, RECENCY_DECAY_FUNCTION, " + "RECENCY_DECAY_HALFLIFE_DAYS — switchroom defaults recall's recency " + "curve to `exponential` with a 30-day half-life so a fact retained " + "today outranks a stale one, instead of upstream's near-flat " + "linear/365-day window), the override-only keys " + "switchroom manages but ships NO default for " + "(`HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS`: " + "HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY — a per-deployment " + "`bank-pattern:priority,...` map; unset means upstream's flat " + "created_at FIFO across banks; and " + "HINDSIGHT_CE_DECISIVE_RELATIVE_GAP — the rollback knob for " + "switchroom's CE-saturation damping patch, a float; >= ~0.65 backs the " + "damping out entirely, unset means the patch's own derived gap; and " + "HINDSIGHT_API_RECENCY_DECAY_LINEAR_WINDOW_DAYS — only read when the " + "decay function is `linear`, so switchroom ships no default for it but " + "still honours an operator who flips the function back; and " + "HINDSIGHT_API_WORKER_MAX_SLOTS — the worker poller's TOTAL in-flight " + "task budget, the pool WORKER_CONSOLIDATION_RESERVED_SLOTS reserves out of; " + "unset means upstream's own default; and " + "HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS — the reserved slot FLOOR for the " + "retain (memory write) lane, carved from that same total; unset means " + "upstream's own 0, i.e. no floor and retain competes for the shared " + "pool; and " + "the pre-0.8.6 name HINDSIGHT_API_WORKER_<TYPE>_MAX_SLOTS is still " + "accepted for every operation type and normalised to " + "..._RESERVED_SLOTS on the way in, because setting both names for " + "one type is a hard boot failure in the engine and switchroom " + "therefore emits only the canonical name; and " + "HINDSIGHT_API_SEMANTIC_MIN_SIMILARITY — the cosine-similarity floor a " + "candidate must reach to be returned by the semantic retrieval arm at " + "all (0..1); unset means upstream's own 0.3, and where it should sit " + "depends on the bank's embedding model and phrasing diversity, so " + "switchroom ships no opinion; and " + "HINDSIGHT_MCP_RECALL_BUDGET_MODE — the rollback knob for switchroom's " + "mcp-recall-token-budget image patch; `legacy` restores upstream's " + "exact pre-patch recall returns, anything else or unset is the " + "honest-envelope mode; and " + "HINDSIGHT_API_LLM_TEMPERATURE_REFLECT — upstream's own per-op reflect " + "temperature knob, made live by switchroom's reflect-temperature image " + "patch; a float, or `none` to omit the kwarg (provider default, " + "upstream's accidental pre-patch behaviour); unset means the image's " + "baked default 0.1; and " + "HINDSIGHT_API_CONSOLIDATION_RECALL_MAX_CONCURRENT — the background " + "half of switchroom's recall-admission split (#3660): of the " + "RECALL_MAX_CONCURRENT admission slots, at most this many may be held " + "by background consolidation recalls at once, so foreground per-turn " + "recall always keeps the remainder; must be >= 1 and strictly less " + "than RECALL_MAX_CONCURRENT or the engine refuses to boot; unset " + "means the image's derived default min(2, RECALL_MAX_CONCURRENT - 1); " + "1 biases hard toward the interactive lane while a consolidation " + "backlog drains; and " + "HINDSIGHT_MM_REFRESH_MIN_INTERVAL_S — the rollback/tuning knob for " + "switchroom's MM-refresh-debounce image patch: the minimum seconds " + "between consolidation-triggered refreshes of one mental model; unset " + "means the image's baked 3600, 0 restores upstream's " + "refresh-every-round behaviour; explicit and cron-scheduled refreshes " + "are never debounced; and " + "HINDSIGHT_API_TEMPORAL_LANGUAGES — the language set dateparser is " + "restricted to during temporal query analysis, made live by switchroom's " + "temporal-language image patch (which ended a 200+-locale auto-detection " + "pass that blocked the shared asyncio loop on every recall); " + "comma-separated, unset means the image's baked `en`, set e.g. `en,es` to " + "restore i18n parsing; and " + "HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS — the max chars of query text " + "dateparser.search_dates() is handed during temporal analysis (0 = " + "unlimited), made live by switchroom's temporal-offload image patch " + "(which moved the synchronous extraction off the shared asyncio loop onto " + "a single-worker thread and bounds its input, ending multi-second loop " + "stalls on multi-KB consolidation queries); unset means the image's baked " + "2000, set 0 to restore an unbounded full scan), plus the " + "embedded-PostgreSQL (pg0) sizing keys switchroom manages in " + "src/setup/hindsight-pg-defaults.ts (`HINDSIGHT_PG_ENV_KEYS`: " + "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE, " + "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS — a postgres size string such " + "as `4GB`, or the sentinel `off` to leave pg0's own default for that " + "one knob). A value set here " + "REPLACES switchroom's default and is emitted even when the gating " + "capability is absent, so an operator can always force a knob. Other " + "`HINDSIGHT_API_*` keys are deliberately IGNORED — a blanket " + "passthrough would collide with the vars startHindsight() derives " + "itself (HINDSIGHT_API_PORT, the retain token/deadline budget).")
|
|
4888
|
+
env: exports_external.record(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()])).optional().describe("Operator overrides for switchroom's capability-gated Hindsight " + "performance defaults. Only the keys switchroom actually manages are " + "honoured (`HINDSIGHT_PERF_ENV_KEYS` in " + "src/setup/hindsight-perf-defaults.ts: RERANKER_LOCAL_FP16, " + "RERANKER_LOCAL_BATCH_SIZE, LLM_MAX_CONCURRENT, " + "RETAIN/CONSOLIDATION_LLM_MAX_CONCURRENT, LLM_STRICT_SCHEMA, " + "LLM_MAX_RETRIES, CONSOLIDATION_LLM_PARALLELISM, " + "MAX_OBSERVATIONS_PER_SCOPE, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT, " + "RERANKER_LOCAL_BUCKET_BATCHING, RERANKER_MAX_CANDIDATES, " + "RERANKER_LOCAL_MAX_CONCURRENT, RECALL_MAX_CONCURRENT, " + "REFLECT_WALL_TIMEOUT, WORKER_CONSOLIDATION_RESERVED_SLOTS, " + "WORKER_CONSOLIDATION_SLOT_LIMIT, " + "CONSOLIDATION_MAX_MEMORIES_PER_ROUND, GRAPH_SEED_MIN_SIMILARITY, " + "LLM_SUPPORTS_MAX_ITEMS, RECENCY_DECAY_FUNCTION, " + "RECENCY_DECAY_HALFLIFE_DAYS — switchroom defaults recall's recency " + "curve to `exponential` with a 30-day half-life so a fact retained " + "today outranks a stale one, instead of upstream's near-flat " + "linear/365-day window), the override-only keys " + "switchroom manages but ships NO default for " + "(`HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS`: " + "HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY — a per-deployment " + "`bank-pattern:priority,...` map; unset means upstream's flat " + "created_at FIFO across banks; and " + "HINDSIGHT_CE_DECISIVE_RELATIVE_GAP — the rollback knob for " + "switchroom's CE-saturation damping patch, a float; >= ~0.65 backs the " + "damping out entirely, unset means the patch's own derived gap; and " + "HINDSIGHT_API_RECENCY_DECAY_LINEAR_WINDOW_DAYS — only read when the " + "decay function is `linear`, so switchroom ships no default for it but " + "still honours an operator who flips the function back; and " + "HINDSIGHT_API_WORKER_MAX_SLOTS — the worker poller's TOTAL in-flight " + "task budget, the pool WORKER_CONSOLIDATION_RESERVED_SLOTS reserves out of; " + "unset means upstream's own default; and " + "HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS — the reserved slot FLOOR for the " + "retain (memory write) lane, carved from that same total; unset means " + "upstream's own 0, i.e. no floor and retain competes for the shared " + "pool; and " + "the pre-0.8.6 name HINDSIGHT_API_WORKER_<TYPE>_MAX_SLOTS is still " + "accepted for every operation type and normalised to " + "..._RESERVED_SLOTS on the way in, because setting both names for " + "one type is a hard boot failure in the engine and switchroom " + "therefore emits only the canonical name; and " + "HINDSIGHT_API_SEMANTIC_MIN_SIMILARITY — the cosine-similarity floor a " + "candidate must reach to be returned by the semantic retrieval arm at " + "all (0..1); unset means upstream's own 0.3, and where it should sit " + "depends on the bank's embedding model and phrasing diversity, so " + "switchroom ships no opinion; and " + "HINDSIGHT_MCP_RECALL_BUDGET_MODE — the rollback knob for switchroom's " + "mcp-recall-token-budget image patch; `legacy` restores upstream's " + "exact pre-patch recall returns, anything else or unset is the " + "honest-envelope mode; and " + "HINDSIGHT_API_LLM_TEMPERATURE_REFLECT — upstream's own per-op reflect " + "temperature knob, made live by switchroom's reflect-temperature image " + "patch; a float, or `none` to omit the kwarg (provider default, " + "upstream's accidental pre-patch behaviour); unset means the image's " + "baked default 0.1; and " + "HINDSIGHT_API_CONSOLIDATION_RECALL_MAX_CONCURRENT — the background " + "half of switchroom's recall-admission split (#3660): of the " + "RECALL_MAX_CONCURRENT admission slots, at most this many may be held " + "by background consolidation recalls at once, so foreground per-turn " + "recall always keeps the remainder; must be >= 1 and strictly less " + "than RECALL_MAX_CONCURRENT or the engine refuses to boot; unset " + "means the image's derived default min(2, RECALL_MAX_CONCURRENT - 1); " + "1 biases hard toward the interactive lane while a consolidation " + "backlog drains; and " + "HINDSIGHT_MM_REFRESH_MIN_INTERVAL_S — the rollback/tuning knob for " + "switchroom's MM-refresh-debounce image patch: the minimum seconds " + "between consolidation-triggered refreshes of one mental model; unset " + "means the image's baked 3600, 0 restores upstream's " + "refresh-every-round behaviour; explicit and cron-scheduled refreshes " + "are never debounced; and " + "HINDSIGHT_API_TEMPORAL_LANGUAGES — the language set dateparser is " + "restricted to during temporal query analysis, made live by switchroom's " + "temporal-language image patch (which ended a 200+-locale auto-detection " + "pass that blocked the shared asyncio loop on every recall); " + "comma-separated, unset means the image's baked `en`, set e.g. `en,es` to " + "restore i18n parsing; and " + "HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS — the max chars of query text " + "dateparser.search_dates() is handed during temporal analysis (0 = " + "unlimited), made live by switchroom's temporal-offload image patch " + "(which moved the synchronous extraction off the shared asyncio loop onto " + "a single-worker thread and bounds its input, ending multi-second loop " + "stalls on multi-KB consolidation queries); unset means the image's baked " + "2000, set 0 to restore an unbounded full scan); and " + "HINDSIGHT_API_TEXT_SEARCH_EXTENSION_NATIVE_LANGUAGE — the Postgres " + "text-search regconfig the native BM25 arms and the search_vector index " + "write run to_tsvector/to_tsquery against; unset means upstream's " + "always-safe `english`, set `hindsight_english` to use switchroom's " + "junk-stopping config (dict + stopword file provisioned durably by the " + "image entrypoint, recall degrading to semantic-only if it is ever " + "missing); plus the " + "embedded-PostgreSQL (pg0) sizing keys switchroom manages in " + "src/setup/hindsight-pg-defaults.ts (`HINDSIGHT_PG_ENV_KEYS`: " + "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE, " + "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS — a postgres size string such " + "as `4GB`, or the sentinel `off` to leave pg0's own default for that " + "one knob). A value set here " + "REPLACES switchroom's default and is emitted even when the gating " + "capability is absent, so an operator can always force a knob. Other " + "`HINDSIGHT_API_*` keys are deliberately IGNORED — a blanket " + "passthrough would collide with the vars startHindsight() derives " + "itself (HINDSIGHT_API_PORT, the retain token/deadline budget).")
|
|
4888
4889
|
});
|
|
4889
4890
|
MicrosoftWorkspaceConfigSchema = exports_external.object({
|
|
4890
4891
|
microsoft_client_id: exports_external.string().min(1).optional().describe("Microsoft OAuth application (client) ID from Entra portal " + "(literal string or vault reference e.g. " + "'vault:microsoft-oauth-client-id'). OPTIONAL — omit it to use " + "switchroom's shipped default Microsoft app (zero-config). " + "Set it only to bring your own Entra app (BYO)."),
|
|
@@ -5337,7 +5338,9 @@ var init_schema = __esm(() => {
|
|
|
5337
5338
|
path: exports_external.string().regex(/^[a-zA-Z0-9~._\-/]+$/, "config_repo.path must not contain shell-special characters ($, `, \", ', \\, etc.)").default("~/.switchroom-config").describe("Filesystem path to the operator's private config repo. Must be a git " + "repo (else `switchroom doctor` FAILs). Tilde-expanded at read time."),
|
|
5338
5339
|
push: exports_external.boolean().default(true).describe("When true, `config-repo sync` pushes after committing (subject to the " + "`require_private` gate). When false, it commits locally only — useful " + "for offline hosts or a review-before-push workflow."),
|
|
5339
5340
|
remote: exports_external.string().min(1).default("origin").describe("Git remote name to push to. Default `origin`."),
|
|
5340
|
-
require_private: exports_external.boolean().default(true).describe("Refuse to PUSH unless the GitHub API confirms the remote repo is " + "private. On a public remote — or when the API is unreachable — the " + "push is skipped (commits still land locally) and a WARN is emitted. " + "Fail-safe against exfiltrating memory files / workspace state to a " + "repo that has been flipped public. Default true.")
|
|
5341
|
+
require_private: exports_external.boolean().default(true).describe("Refuse to PUSH unless the GitHub API confirms the remote repo is " + "private. On a public remote — or when the API is unreachable — the " + "push is skipped (commits still land locally) and a WARN is emitted. " + "Fail-safe against exfiltrating memory files / workspace state to a " + "repo that has been flipped public. Default true."),
|
|
5342
|
+
interval_minutes: exports_external.number().int().min(5).max(59).default(30).describe("Cadence (minutes) of the scheduled `config-repo sync` tick installed " + "by `switchroom config-repo --install-cron`. Rendered as a cron " + "`*/N * * * *` minute field, so it must be 5..59 (the 5-min floor " + "matches the rest of the fleet's cron floor). Default 30 (Ken's " + "approved cadence). Changing it takes effect on the next " + "`--install-cron` / `switchroom update` reconcile."),
|
|
5343
|
+
include_vault_backup: exports_external.enum(["off", "daily", "every_tick"]).default("daily").describe("Whether the scheduled tick also runs `switchroom vault backup` " + "(an encrypted vault/memory snapshot into <path>/vault-backups/) " + "before the sync. `off`: sync only. `daily`: an extra once-per-day " + "cron leg runs `vault backup && config-repo sync` (the 30-min legs " + "stay sync-only). `every_tick`: every tick runs the backup first. " + "Default `daily` — the first automated vault backup on this host.")
|
|
5341
5344
|
});
|
|
5342
5345
|
SwitchroomConfigSchema = exports_external.object({
|
|
5343
5346
|
switchroom: exports_external.object({
|
|
@@ -19453,6 +19456,27 @@ function allocateAgentUid(name) {
|
|
|
19453
19456
|
return AGENT_UID_MIN + u32 % range;
|
|
19454
19457
|
}
|
|
19455
19458
|
|
|
19459
|
+
// src/setup/hindsight-recall-passthrough.ts
|
|
19460
|
+
var HINDSIGHT_RECALL_TAG_WEIGHT_SEED = Object.freeze({ sidechain: 0.8 });
|
|
19461
|
+
var HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT = "Relevant memories from past conversations (prioritize recent when " + "conflicting). Only use memories that are directly useful to continue " + "this conversation; ignore the rest:";
|
|
19462
|
+
var RECALL_PASSTHROUGH_DEFAULTS = Object.freeze({
|
|
19463
|
+
budget: "low",
|
|
19464
|
+
maxTokens: 1024,
|
|
19465
|
+
preferObservations: true,
|
|
19466
|
+
contextTurns: 2,
|
|
19467
|
+
roles: ["user", "assistant"],
|
|
19468
|
+
promptPreamble: HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT,
|
|
19469
|
+
tags: [],
|
|
19470
|
+
tagsMatch: "any",
|
|
19471
|
+
tagGroups: {},
|
|
19472
|
+
tagWeights: HINDSIGHT_RECALL_TAG_WEIGHT_SEED,
|
|
19473
|
+
additionalBankFilters: {},
|
|
19474
|
+
transcriptFallback: true,
|
|
19475
|
+
transcriptTailBytes: 262144,
|
|
19476
|
+
maxQueryChars: 800,
|
|
19477
|
+
parallel: true
|
|
19478
|
+
});
|
|
19479
|
+
|
|
19456
19480
|
// src/setup/hindsight-recall-tunables.ts
|
|
19457
19481
|
var RECALL_DEADLINE_HEADROOM_SECONDS = 2;
|
|
19458
19482
|
var MIN_RECALL_HOOK_TIMEOUT_SECONDS = RECALL_DEADLINE_HEADROOM_SECONDS + 1;
|
|
@@ -19580,6 +19604,7 @@ var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB = 12288;
|
|
|
19580
19604
|
function pgMib(mib) {
|
|
19581
19605
|
return `${mib}MB`;
|
|
19582
19606
|
}
|
|
19607
|
+
var HINDSIGHT_PG_MIN_NON_BUFFER_MIB = HINDSIGHT_PG_APP_ANON_MIB + HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB;
|
|
19583
19608
|
var HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE_ENV = "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE";
|
|
19584
19609
|
var HINDSIGHT_PG_SHARED_BUFFERS_ENV = "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS";
|
|
19585
19610
|
var HINDSIGHT_PG_FSYNC_ENV = "SWITCHROOM_HINDSIGHT_PG_FSYNC";
|
|
@@ -19627,6 +19652,7 @@ var HINDSIGHT_DEFAULT_GRAPH_SEED_MIN_SIMILARITY = 0.3;
|
|
|
19627
19652
|
var HINDSIGHT_DEFAULT_LLM_SUPPORTS_MAX_ITEMS = "false";
|
|
19628
19653
|
var HINDSIGHT_DEFAULT_RECENCY_DECAY_FUNCTION = "exponential";
|
|
19629
19654
|
var HINDSIGHT_DEFAULT_RECENCY_DECAY_HALFLIFE_DAYS = 30;
|
|
19655
|
+
var HINDSIGHT_DEFAULT_TEXT_SEARCH_EXTENSION = "pg_search";
|
|
19630
19656
|
var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
19631
19657
|
[
|
|
19632
19658
|
"HINDSIGHT_API_RECALL_MAX_CANDIDATES_PER_SOURCE",
|
|
@@ -19692,7 +19718,8 @@ var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
|
19692
19718
|
[
|
|
19693
19719
|
"HINDSIGHT_API_GRAPH_SEED_MIN_SIMILARITY",
|
|
19694
19720
|
String(HINDSIGHT_DEFAULT_GRAPH_SEED_MIN_SIMILARITY)
|
|
19695
|
-
]
|
|
19721
|
+
],
|
|
19722
|
+
["HINDSIGHT_API_TEXT_SEARCH_EXTENSION", HINDSIGHT_DEFAULT_TEXT_SEARCH_EXTENSION]
|
|
19696
19723
|
];
|
|
19697
19724
|
var HINDSIGHT_PERF_DEFAULTS_GPU = [
|
|
19698
19725
|
["HINDSIGHT_API_RERANKER_LOCAL_FP16", HINDSIGHT_DEFAULT_RERANKER_LOCAL_FP16],
|
|
@@ -19728,7 +19755,8 @@ var HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS = new Set([
|
|
|
19728
19755
|
"HINDSIGHT_API_CONSOLIDATION_RECALL_MAX_CONCURRENT",
|
|
19729
19756
|
"HINDSIGHT_MM_REFRESH_MIN_INTERVAL_S",
|
|
19730
19757
|
"HINDSIGHT_API_TEMPORAL_LANGUAGES",
|
|
19731
|
-
"HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS"
|
|
19758
|
+
"HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS",
|
|
19759
|
+
"HINDSIGHT_API_TEXT_SEARCH_EXTENSION_NATIVE_LANGUAGE"
|
|
19732
19760
|
]);
|
|
19733
19761
|
var HINDSIGHT_WORKER_SLOT_TYPES = [
|
|
19734
19762
|
"consolidation",
|
|
@@ -20150,27 +20178,6 @@ init_vault();
|
|
|
20150
20178
|
// src/setup/onboarding.ts
|
|
20151
20179
|
init_paths();
|
|
20152
20180
|
|
|
20153
|
-
// src/setup/hindsight-recall-passthrough.ts
|
|
20154
|
-
var HINDSIGHT_RECALL_TAG_WEIGHT_SEED = Object.freeze({ sidechain: 0.8 });
|
|
20155
|
-
var HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT = "Relevant memories from past conversations (prioritize recent when " + "conflicting). Only use memories that are directly useful to continue " + "this conversation; ignore the rest:";
|
|
20156
|
-
var RECALL_PASSTHROUGH_DEFAULTS = Object.freeze({
|
|
20157
|
-
budget: "low",
|
|
20158
|
-
maxTokens: 1024,
|
|
20159
|
-
preferObservations: true,
|
|
20160
|
-
contextTurns: 2,
|
|
20161
|
-
roles: ["user", "assistant"],
|
|
20162
|
-
promptPreamble: HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT,
|
|
20163
|
-
tags: [],
|
|
20164
|
-
tagsMatch: "any",
|
|
20165
|
-
tagGroups: {},
|
|
20166
|
-
tagWeights: HINDSIGHT_RECALL_TAG_WEIGHT_SEED,
|
|
20167
|
-
additionalBankFilters: {},
|
|
20168
|
-
transcriptFallback: true,
|
|
20169
|
-
transcriptTailBytes: 262144,
|
|
20170
|
-
maxQueryChars: 800,
|
|
20171
|
-
parallel: true
|
|
20172
|
-
});
|
|
20173
|
-
|
|
20174
20181
|
// src/repos/bare-clone.ts
|
|
20175
20182
|
init_paths();
|
|
20176
20183
|
|
|
@@ -4469,6 +4469,7 @@ var init_schema = __esm(() => {
|
|
|
4469
4469
|
}).describe("Per-operation LLM override. Every field optional; an unset field (or " + "an omitted op block) inherits the global `hindsight.llm.*`, which is " + "already the engine's fallback — switchroom emits only the vars set.");
|
|
4470
4470
|
HindsightConfigSchema = exports_external.object({
|
|
4471
4471
|
gpu: exports_external.boolean().optional().describe("Force GPU passthrough for the hindsight container on (`true`) or off " + "(`false`), overriding host autodetection in BOTH directions. Absent " + "(the default) → autodetect from the persisted host-capabilities " + "verdict (`~/.switchroom/host-capabilities.json`), which enables " + "`--gpus all` only when that file proves BOTH a GPU and the nvidia " + "container toolkit. Set `true` when that verdict is wrong or unreadable " + "and you know the host has a working toolkit — switchroom cannot verify " + "it for you, and `docker run --gpus all` hard-fails container create on " + "a host without one. Set `false` to pin the container to CPU on a GPU " + "host. This is also the declarative opt-out for the recreate-time GPU " + "drop guard (`switchroom memory setup --recreate` refuses to silently " + "turn a GPU container into a CPU one). `--gpu`/`--no-gpu` on `memory " + "setup` override this for a single run."),
|
|
4472
|
+
mem_limit: exports_external.string().regex(/^\d+(\.\d+)?\s*[bkmgt]?b?$/i, "hindsight.mem_limit must be a docker memory size, e.g. `24g` or `16384m`").optional().describe("Hard memory cap for the hindsight container — docker `--memory` on the " + "`memory setup` path and `mem_limit:` in the emitted compose snippet. A " + "docker size string (`24g`, `16384m`). Absent → switchroom's default " + "(`HINDSIGHT_DEFAULT_MEM_LIMIT`, 16g). This is a docker HostConfig flag, " + "not a container env var, which is why it is a first-class field here " + "rather than an `env:` key. **Move it together with " + "`env.SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS`**: Postgres pins the " + "buffer pool as unreclaimable shared memory inside this cap, so a cap " + "that does not clear `shared_buffers` by the container's app working " + "set plus its page-cache floor puts Postgres in a near-OOM " + "configuration. switchroom warns, naming both numbers, when it does " + "not. A value below the container's memory RESERVATION (4g) is " + "rejected outright — docker will not create such a container."),
|
|
4472
4473
|
cp_access_key: exports_external.string().min(1).optional().describe("Access key for the hindsight control-plane DASHBOARD (upstream " + "`HINDSIGHT_CP_ACCESS_KEY`, port 9999). Literal or — strongly preferred " + "— a `vault:` reference such as `vault:hindsight_cp_access_key`, read " + "through the broker at container-launch time. This is the ONLY thing " + "that arms the dashboard's login: upstream's middleware short-circuits " + "to `next()` when the var is unset, so an unset key means the dashboard " + "has no authentication at all, not weak authentication. Because of that, " + "leaving it unset is FAIL-CLOSED: switchroom pins " + "`HINDSIGHT_CP_HOSTNAME=127.0.0.1` so the loginless dashboard is " + "reachable only from the host, and warns. Set this to serve the " + "dashboard on the LAN/tailnet."),
|
|
4473
4474
|
llm: exports_external.object({
|
|
4474
4475
|
provider: exports_external.string().min(1).optional().describe("Hindsight LLM provider (upstream `HINDSIGHT_API_LLM_PROVIDER`). " + "Defaults to `claude-code` (subscription-honest, broker-fed OAuth). " + "Any litellm-routable provider the upstream image supports is valid. " + "Serves as the GLOBAL default for every op absent a per-op override."),
|
|
@@ -4480,7 +4481,7 @@ var init_schema = __esm(() => {
|
|
|
4480
4481
|
reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent → uses global."),
|
|
4481
4482
|
consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent → global.")
|
|
4482
4483
|
}).optional().describe("LLM knob for the hindsight container. The flat `provider`/`model` set " + "the global default (backward-compatible); optional `retain`/`reflect`/" + "`consolidation` blocks override individual ops. All fields optional; " + "unset fields fall back to the hard-coded defaults."),
|
|
4483
|
-
env: exports_external.record(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()])).optional().describe("Operator overrides for switchroom's capability-gated Hindsight " + "performance defaults. Only the keys switchroom actually manages are " + "honoured (`HINDSIGHT_PERF_ENV_KEYS` in " + "src/setup/hindsight-perf-defaults.ts: RERANKER_LOCAL_FP16, " + "RERANKER_LOCAL_BATCH_SIZE, LLM_MAX_CONCURRENT, " + "RETAIN/CONSOLIDATION_LLM_MAX_CONCURRENT, LLM_STRICT_SCHEMA, " + "LLM_MAX_RETRIES, CONSOLIDATION_LLM_PARALLELISM, " + "MAX_OBSERVATIONS_PER_SCOPE, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT, " + "RERANKER_LOCAL_BUCKET_BATCHING, RERANKER_MAX_CANDIDATES, " + "RERANKER_LOCAL_MAX_CONCURRENT, RECALL_MAX_CONCURRENT, " + "REFLECT_WALL_TIMEOUT, WORKER_CONSOLIDATION_RESERVED_SLOTS, " + "WORKER_CONSOLIDATION_SLOT_LIMIT, " + "CONSOLIDATION_MAX_MEMORIES_PER_ROUND, GRAPH_SEED_MIN_SIMILARITY, " + "LLM_SUPPORTS_MAX_ITEMS, RECENCY_DECAY_FUNCTION, " + "RECENCY_DECAY_HALFLIFE_DAYS — switchroom defaults recall's recency " + "curve to `exponential` with a 30-day half-life so a fact retained " + "today outranks a stale one, instead of upstream's near-flat " + "linear/365-day window), the override-only keys " + "switchroom manages but ships NO default for " + "(`HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS`: " + "HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY — a per-deployment " + "`bank-pattern:priority,...` map; unset means upstream's flat " + "created_at FIFO across banks; and " + "HINDSIGHT_CE_DECISIVE_RELATIVE_GAP — the rollback knob for " + "switchroom's CE-saturation damping patch, a float; >= ~0.65 backs the " + "damping out entirely, unset means the patch's own derived gap; and " + "HINDSIGHT_API_RECENCY_DECAY_LINEAR_WINDOW_DAYS — only read when the " + "decay function is `linear`, so switchroom ships no default for it but " + "still honours an operator who flips the function back; and " + "HINDSIGHT_API_WORKER_MAX_SLOTS — the worker poller's TOTAL in-flight " + "task budget, the pool WORKER_CONSOLIDATION_RESERVED_SLOTS reserves out of; " + "unset means upstream's own default; and " + "HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS — the reserved slot FLOOR for the " + "retain (memory write) lane, carved from that same total; unset means " + "upstream's own 0, i.e. no floor and retain competes for the shared " + "pool; and " + "the pre-0.8.6 name HINDSIGHT_API_WORKER_<TYPE>_MAX_SLOTS is still " + "accepted for every operation type and normalised to " + "..._RESERVED_SLOTS on the way in, because setting both names for " + "one type is a hard boot failure in the engine and switchroom " + "therefore emits only the canonical name; and " + "HINDSIGHT_API_SEMANTIC_MIN_SIMILARITY — the cosine-similarity floor a " + "candidate must reach to be returned by the semantic retrieval arm at " + "all (0..1); unset means upstream's own 0.3, and where it should sit " + "depends on the bank's embedding model and phrasing diversity, so " + "switchroom ships no opinion; and " + "HINDSIGHT_MCP_RECALL_BUDGET_MODE — the rollback knob for switchroom's " + "mcp-recall-token-budget image patch; `legacy` restores upstream's " + "exact pre-patch recall returns, anything else or unset is the " + "honest-envelope mode; and " + "HINDSIGHT_API_LLM_TEMPERATURE_REFLECT — upstream's own per-op reflect " + "temperature knob, made live by switchroom's reflect-temperature image " + "patch; a float, or `none` to omit the kwarg (provider default, " + "upstream's accidental pre-patch behaviour); unset means the image's " + "baked default 0.1; and " + "HINDSIGHT_API_CONSOLIDATION_RECALL_MAX_CONCURRENT — the background " + "half of switchroom's recall-admission split (#3660): of the " + "RECALL_MAX_CONCURRENT admission slots, at most this many may be held " + "by background consolidation recalls at once, so foreground per-turn " + "recall always keeps the remainder; must be >= 1 and strictly less " + "than RECALL_MAX_CONCURRENT or the engine refuses to boot; unset " + "means the image's derived default min(2, RECALL_MAX_CONCURRENT - 1); " + "1 biases hard toward the interactive lane while a consolidation " + "backlog drains; and " + "HINDSIGHT_MM_REFRESH_MIN_INTERVAL_S — the rollback/tuning knob for " + "switchroom's MM-refresh-debounce image patch: the minimum seconds " + "between consolidation-triggered refreshes of one mental model; unset " + "means the image's baked 3600, 0 restores upstream's " + "refresh-every-round behaviour; explicit and cron-scheduled refreshes " + "are never debounced; and " + "HINDSIGHT_API_TEMPORAL_LANGUAGES — the language set dateparser is " + "restricted to during temporal query analysis, made live by switchroom's " + "temporal-language image patch (which ended a 200+-locale auto-detection " + "pass that blocked the shared asyncio loop on every recall); " + "comma-separated, unset means the image's baked `en`, set e.g. `en,es` to " + "restore i18n parsing; and " + "HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS — the max chars of query text " + "dateparser.search_dates() is handed during temporal analysis (0 = " + "unlimited), made live by switchroom's temporal-offload image patch " + "(which moved the synchronous extraction off the shared asyncio loop onto " + "a single-worker thread and bounds its input, ending multi-second loop " + "stalls on multi-KB consolidation queries); unset means the image's baked " + "2000, set 0 to restore an unbounded full scan), plus the " + "embedded-PostgreSQL (pg0) sizing keys switchroom manages in " + "src/setup/hindsight-pg-defaults.ts (`HINDSIGHT_PG_ENV_KEYS`: " + "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE, " + "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS — a postgres size string such " + "as `4GB`, or the sentinel `off` to leave pg0's own default for that " + "one knob). A value set here " + "REPLACES switchroom's default and is emitted even when the gating " + "capability is absent, so an operator can always force a knob. Other " + "`HINDSIGHT_API_*` keys are deliberately IGNORED — a blanket " + "passthrough would collide with the vars startHindsight() derives " + "itself (HINDSIGHT_API_PORT, the retain token/deadline budget).")
|
|
4484
|
+
env: exports_external.record(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()])).optional().describe("Operator overrides for switchroom's capability-gated Hindsight " + "performance defaults. Only the keys switchroom actually manages are " + "honoured (`HINDSIGHT_PERF_ENV_KEYS` in " + "src/setup/hindsight-perf-defaults.ts: RERANKER_LOCAL_FP16, " + "RERANKER_LOCAL_BATCH_SIZE, LLM_MAX_CONCURRENT, " + "RETAIN/CONSOLIDATION_LLM_MAX_CONCURRENT, LLM_STRICT_SCHEMA, " + "LLM_MAX_RETRIES, CONSOLIDATION_LLM_PARALLELISM, " + "MAX_OBSERVATIONS_PER_SCOPE, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT, " + "RERANKER_LOCAL_BUCKET_BATCHING, RERANKER_MAX_CANDIDATES, " + "RERANKER_LOCAL_MAX_CONCURRENT, RECALL_MAX_CONCURRENT, " + "REFLECT_WALL_TIMEOUT, WORKER_CONSOLIDATION_RESERVED_SLOTS, " + "WORKER_CONSOLIDATION_SLOT_LIMIT, " + "CONSOLIDATION_MAX_MEMORIES_PER_ROUND, GRAPH_SEED_MIN_SIMILARITY, " + "LLM_SUPPORTS_MAX_ITEMS, RECENCY_DECAY_FUNCTION, " + "RECENCY_DECAY_HALFLIFE_DAYS — switchroom defaults recall's recency " + "curve to `exponential` with a 30-day half-life so a fact retained " + "today outranks a stale one, instead of upstream's near-flat " + "linear/365-day window), the override-only keys " + "switchroom manages but ships NO default for " + "(`HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS`: " + "HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY — a per-deployment " + "`bank-pattern:priority,...` map; unset means upstream's flat " + "created_at FIFO across banks; and " + "HINDSIGHT_CE_DECISIVE_RELATIVE_GAP — the rollback knob for " + "switchroom's CE-saturation damping patch, a float; >= ~0.65 backs the " + "damping out entirely, unset means the patch's own derived gap; and " + "HINDSIGHT_API_RECENCY_DECAY_LINEAR_WINDOW_DAYS — only read when the " + "decay function is `linear`, so switchroom ships no default for it but " + "still honours an operator who flips the function back; and " + "HINDSIGHT_API_WORKER_MAX_SLOTS — the worker poller's TOTAL in-flight " + "task budget, the pool WORKER_CONSOLIDATION_RESERVED_SLOTS reserves out of; " + "unset means upstream's own default; and " + "HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS — the reserved slot FLOOR for the " + "retain (memory write) lane, carved from that same total; unset means " + "upstream's own 0, i.e. no floor and retain competes for the shared " + "pool; and " + "the pre-0.8.6 name HINDSIGHT_API_WORKER_<TYPE>_MAX_SLOTS is still " + "accepted for every operation type and normalised to " + "..._RESERVED_SLOTS on the way in, because setting both names for " + "one type is a hard boot failure in the engine and switchroom " + "therefore emits only the canonical name; and " + "HINDSIGHT_API_SEMANTIC_MIN_SIMILARITY — the cosine-similarity floor a " + "candidate must reach to be returned by the semantic retrieval arm at " + "all (0..1); unset means upstream's own 0.3, and where it should sit " + "depends on the bank's embedding model and phrasing diversity, so " + "switchroom ships no opinion; and " + "HINDSIGHT_MCP_RECALL_BUDGET_MODE — the rollback knob for switchroom's " + "mcp-recall-token-budget image patch; `legacy` restores upstream's " + "exact pre-patch recall returns, anything else or unset is the " + "honest-envelope mode; and " + "HINDSIGHT_API_LLM_TEMPERATURE_REFLECT — upstream's own per-op reflect " + "temperature knob, made live by switchroom's reflect-temperature image " + "patch; a float, or `none` to omit the kwarg (provider default, " + "upstream's accidental pre-patch behaviour); unset means the image's " + "baked default 0.1; and " + "HINDSIGHT_API_CONSOLIDATION_RECALL_MAX_CONCURRENT — the background " + "half of switchroom's recall-admission split (#3660): of the " + "RECALL_MAX_CONCURRENT admission slots, at most this many may be held " + "by background consolidation recalls at once, so foreground per-turn " + "recall always keeps the remainder; must be >= 1 and strictly less " + "than RECALL_MAX_CONCURRENT or the engine refuses to boot; unset " + "means the image's derived default min(2, RECALL_MAX_CONCURRENT - 1); " + "1 biases hard toward the interactive lane while a consolidation " + "backlog drains; and " + "HINDSIGHT_MM_REFRESH_MIN_INTERVAL_S — the rollback/tuning knob for " + "switchroom's MM-refresh-debounce image patch: the minimum seconds " + "between consolidation-triggered refreshes of one mental model; unset " + "means the image's baked 3600, 0 restores upstream's " + "refresh-every-round behaviour; explicit and cron-scheduled refreshes " + "are never debounced; and " + "HINDSIGHT_API_TEMPORAL_LANGUAGES — the language set dateparser is " + "restricted to during temporal query analysis, made live by switchroom's " + "temporal-language image patch (which ended a 200+-locale auto-detection " + "pass that blocked the shared asyncio loop on every recall); " + "comma-separated, unset means the image's baked `en`, set e.g. `en,es` to " + "restore i18n parsing; and " + "HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS — the max chars of query text " + "dateparser.search_dates() is handed during temporal analysis (0 = " + "unlimited), made live by switchroom's temporal-offload image patch " + "(which moved the synchronous extraction off the shared asyncio loop onto " + "a single-worker thread and bounds its input, ending multi-second loop " + "stalls on multi-KB consolidation queries); unset means the image's baked " + "2000, set 0 to restore an unbounded full scan); and " + "HINDSIGHT_API_TEXT_SEARCH_EXTENSION_NATIVE_LANGUAGE — the Postgres " + "text-search regconfig the native BM25 arms and the search_vector index " + "write run to_tsvector/to_tsquery against; unset means upstream's " + "always-safe `english`, set `hindsight_english` to use switchroom's " + "junk-stopping config (dict + stopword file provisioned durably by the " + "image entrypoint, recall degrading to semantic-only if it is ever " + "missing); plus the " + "embedded-PostgreSQL (pg0) sizing keys switchroom manages in " + "src/setup/hindsight-pg-defaults.ts (`HINDSIGHT_PG_ENV_KEYS`: " + "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE, " + "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS — a postgres size string such " + "as `4GB`, or the sentinel `off` to leave pg0's own default for that " + "one knob). A value set here " + "REPLACES switchroom's default and is emitted even when the gating " + "capability is absent, so an operator can always force a knob. Other " + "`HINDSIGHT_API_*` keys are deliberately IGNORED — a blanket " + "passthrough would collide with the vars startHindsight() derives " + "itself (HINDSIGHT_API_PORT, the retain token/deadline budget).")
|
|
4484
4485
|
});
|
|
4485
4486
|
MicrosoftWorkspaceConfigSchema = exports_external.object({
|
|
4486
4487
|
microsoft_client_id: exports_external.string().min(1).optional().describe("Microsoft OAuth application (client) ID from Entra portal " + "(literal string or vault reference e.g. " + "'vault:microsoft-oauth-client-id'). OPTIONAL — omit it to use " + "switchroom's shipped default Microsoft app (zero-config). " + "Set it only to bring your own Entra app (BYO)."),
|
|
@@ -4933,7 +4934,9 @@ var init_schema = __esm(() => {
|
|
|
4933
4934
|
path: exports_external.string().regex(/^[a-zA-Z0-9~._\-/]+$/, "config_repo.path must not contain shell-special characters ($, `, \", ', \\, etc.)").default("~/.switchroom-config").describe("Filesystem path to the operator's private config repo. Must be a git " + "repo (else `switchroom doctor` FAILs). Tilde-expanded at read time."),
|
|
4934
4935
|
push: exports_external.boolean().default(true).describe("When true, `config-repo sync` pushes after committing (subject to the " + "`require_private` gate). When false, it commits locally only — useful " + "for offline hosts or a review-before-push workflow."),
|
|
4935
4936
|
remote: exports_external.string().min(1).default("origin").describe("Git remote name to push to. Default `origin`."),
|
|
4936
|
-
require_private: exports_external.boolean().default(true).describe("Refuse to PUSH unless the GitHub API confirms the remote repo is " + "private. On a public remote — or when the API is unreachable — the " + "push is skipped (commits still land locally) and a WARN is emitted. " + "Fail-safe against exfiltrating memory files / workspace state to a " + "repo that has been flipped public. Default true.")
|
|
4937
|
+
require_private: exports_external.boolean().default(true).describe("Refuse to PUSH unless the GitHub API confirms the remote repo is " + "private. On a public remote — or when the API is unreachable — the " + "push is skipped (commits still land locally) and a WARN is emitted. " + "Fail-safe against exfiltrating memory files / workspace state to a " + "repo that has been flipped public. Default true."),
|
|
4938
|
+
interval_minutes: exports_external.number().int().min(5).max(59).default(30).describe("Cadence (minutes) of the scheduled `config-repo sync` tick installed " + "by `switchroom config-repo --install-cron`. Rendered as a cron " + "`*/N * * * *` minute field, so it must be 5..59 (the 5-min floor " + "matches the rest of the fleet's cron floor). Default 30 (Ken's " + "approved cadence). Changing it takes effect on the next " + "`--install-cron` / `switchroom update` reconcile."),
|
|
4939
|
+
include_vault_backup: exports_external.enum(["off", "daily", "every_tick"]).default("daily").describe("Whether the scheduled tick also runs `switchroom vault backup` " + "(an encrypted vault/memory snapshot into <path>/vault-backups/) " + "before the sync. `off`: sync only. `daily`: an extra once-per-day " + "cron leg runs `vault backup && config-repo sync` (the 30-min legs " + "stay sync-only). `every_tick`: every tick runs the backup first. " + "Default `daily` — the first automated vault backup on this host.")
|
|
4937
4940
|
});
|
|
4938
4941
|
SwitchroomConfigSchema = exports_external.object({
|
|
4939
4942
|
switchroom: exports_external.object({
|
|
@@ -19694,6 +19697,27 @@ function allocateAgentUid(name) {
|
|
|
19694
19697
|
return AGENT_UID_MIN + u32 % range;
|
|
19695
19698
|
}
|
|
19696
19699
|
|
|
19700
|
+
// src/setup/hindsight-recall-passthrough.ts
|
|
19701
|
+
var HINDSIGHT_RECALL_TAG_WEIGHT_SEED = Object.freeze({ sidechain: 0.8 });
|
|
19702
|
+
var HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT = "Relevant memories from past conversations (prioritize recent when " + "conflicting). Only use memories that are directly useful to continue " + "this conversation; ignore the rest:";
|
|
19703
|
+
var RECALL_PASSTHROUGH_DEFAULTS = Object.freeze({
|
|
19704
|
+
budget: "low",
|
|
19705
|
+
maxTokens: 1024,
|
|
19706
|
+
preferObservations: true,
|
|
19707
|
+
contextTurns: 2,
|
|
19708
|
+
roles: ["user", "assistant"],
|
|
19709
|
+
promptPreamble: HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT,
|
|
19710
|
+
tags: [],
|
|
19711
|
+
tagsMatch: "any",
|
|
19712
|
+
tagGroups: {},
|
|
19713
|
+
tagWeights: HINDSIGHT_RECALL_TAG_WEIGHT_SEED,
|
|
19714
|
+
additionalBankFilters: {},
|
|
19715
|
+
transcriptFallback: true,
|
|
19716
|
+
transcriptTailBytes: 262144,
|
|
19717
|
+
maxQueryChars: 800,
|
|
19718
|
+
parallel: true
|
|
19719
|
+
});
|
|
19720
|
+
|
|
19697
19721
|
// src/setup/hindsight-recall-tunables.ts
|
|
19698
19722
|
var RECALL_DEADLINE_HEADROOM_SECONDS = 2;
|
|
19699
19723
|
var MIN_RECALL_HOOK_TIMEOUT_SECONDS = RECALL_DEADLINE_HEADROOM_SECONDS + 1;
|
|
@@ -19993,6 +20017,7 @@ var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB = 12288;
|
|
|
19993
20017
|
function pgMib(mib) {
|
|
19994
20018
|
return `${mib}MB`;
|
|
19995
20019
|
}
|
|
20020
|
+
var HINDSIGHT_PG_MIN_NON_BUFFER_MIB = HINDSIGHT_PG_APP_ANON_MIB + HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB;
|
|
19996
20021
|
var HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE_ENV = "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE";
|
|
19997
20022
|
var HINDSIGHT_PG_SHARED_BUFFERS_ENV = "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS";
|
|
19998
20023
|
var HINDSIGHT_PG_FSYNC_ENV = "SWITCHROOM_HINDSIGHT_PG_FSYNC";
|
|
@@ -20040,6 +20065,7 @@ var HINDSIGHT_DEFAULT_GRAPH_SEED_MIN_SIMILARITY = 0.3;
|
|
|
20040
20065
|
var HINDSIGHT_DEFAULT_LLM_SUPPORTS_MAX_ITEMS = "false";
|
|
20041
20066
|
var HINDSIGHT_DEFAULT_RECENCY_DECAY_FUNCTION = "exponential";
|
|
20042
20067
|
var HINDSIGHT_DEFAULT_RECENCY_DECAY_HALFLIFE_DAYS = 30;
|
|
20068
|
+
var HINDSIGHT_DEFAULT_TEXT_SEARCH_EXTENSION = "pg_search";
|
|
20043
20069
|
var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
20044
20070
|
[
|
|
20045
20071
|
"HINDSIGHT_API_RECALL_MAX_CANDIDATES_PER_SOURCE",
|
|
@@ -20105,7 +20131,8 @@ var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
|
20105
20131
|
[
|
|
20106
20132
|
"HINDSIGHT_API_GRAPH_SEED_MIN_SIMILARITY",
|
|
20107
20133
|
String(HINDSIGHT_DEFAULT_GRAPH_SEED_MIN_SIMILARITY)
|
|
20108
|
-
]
|
|
20134
|
+
],
|
|
20135
|
+
["HINDSIGHT_API_TEXT_SEARCH_EXTENSION", HINDSIGHT_DEFAULT_TEXT_SEARCH_EXTENSION]
|
|
20109
20136
|
];
|
|
20110
20137
|
var HINDSIGHT_PERF_DEFAULTS_GPU = [
|
|
20111
20138
|
["HINDSIGHT_API_RERANKER_LOCAL_FP16", HINDSIGHT_DEFAULT_RERANKER_LOCAL_FP16],
|
|
@@ -20141,7 +20168,8 @@ var HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS = new Set([
|
|
|
20141
20168
|
"HINDSIGHT_API_CONSOLIDATION_RECALL_MAX_CONCURRENT",
|
|
20142
20169
|
"HINDSIGHT_MM_REFRESH_MIN_INTERVAL_S",
|
|
20143
20170
|
"HINDSIGHT_API_TEMPORAL_LANGUAGES",
|
|
20144
|
-
"HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS"
|
|
20171
|
+
"HINDSIGHT_API_TEMPORAL_MAX_QUERY_CHARS",
|
|
20172
|
+
"HINDSIGHT_API_TEXT_SEARCH_EXTENSION_NATIVE_LANGUAGE"
|
|
20145
20173
|
]);
|
|
20146
20174
|
var HINDSIGHT_WORKER_SLOT_TYPES = [
|
|
20147
20175
|
"consolidation",
|
|
@@ -20563,27 +20591,6 @@ init_vault();
|
|
|
20563
20591
|
// src/setup/onboarding.ts
|
|
20564
20592
|
init_paths();
|
|
20565
20593
|
|
|
20566
|
-
// src/setup/hindsight-recall-passthrough.ts
|
|
20567
|
-
var HINDSIGHT_RECALL_TAG_WEIGHT_SEED = Object.freeze({ sidechain: 0.8 });
|
|
20568
|
-
var HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT = "Relevant memories from past conversations (prioritize recent when " + "conflicting). Only use memories that are directly useful to continue " + "this conversation; ignore the rest:";
|
|
20569
|
-
var RECALL_PASSTHROUGH_DEFAULTS = Object.freeze({
|
|
20570
|
-
budget: "low",
|
|
20571
|
-
maxTokens: 1024,
|
|
20572
|
-
preferObservations: true,
|
|
20573
|
-
contextTurns: 2,
|
|
20574
|
-
roles: ["user", "assistant"],
|
|
20575
|
-
promptPreamble: HINDSIGHT_RECALL_PROMPT_PREAMBLE_DEFAULT,
|
|
20576
|
-
tags: [],
|
|
20577
|
-
tagsMatch: "any",
|
|
20578
|
-
tagGroups: {},
|
|
20579
|
-
tagWeights: HINDSIGHT_RECALL_TAG_WEIGHT_SEED,
|
|
20580
|
-
additionalBankFilters: {},
|
|
20581
|
-
transcriptFallback: true,
|
|
20582
|
-
transcriptTailBytes: 262144,
|
|
20583
|
-
maxQueryChars: 800,
|
|
20584
|
-
parallel: true
|
|
20585
|
-
});
|
|
20586
|
-
|
|
20587
20594
|
// src/repos/bare-clone.ts
|
|
20588
20595
|
init_paths();
|
|
20589
20596
|
|
|
@@ -38,7 +38,7 @@ services:
|
|
|
38
38
|
# Pinned: bumping is a deliberate operator decision, not a silent
|
|
39
39
|
# surprise. Bump in lockstep with retesting the OAuth flow.
|
|
40
40
|
- --from
|
|
41
|
-
- workspace-mcp==1.
|
|
41
|
+
- workspace-mcp==1.23.1
|
|
42
42
|
- workspace-mcp
|
|
43
43
|
# streamable-http (not stdio) is required for OAuth 2.1 PKCE per
|
|
44
44
|
# upstream README.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchroom",
|
|
3
3
|
"//version": "NOT the release version — source of truth is the git tag, resolved by scripts/build.mjs:resolveVersion() (see CLAUDE.md > Standard release process). This field is stale by design and only the Layer-4 dev/non-tag fallback for build.mjs + src/cli/resolve-version.ts; do NOT bump it expecting a release to pick it up. npm-pack tarball naming needs a real version — do that as an UNCOMMITTED pack-time bump (see release step 6), never a committed one.",
|
|
4
|
-
"version": "0.20.
|
|
4
|
+
"version": "0.20.13",
|
|
5
5
|
"description": "Run Claude Code 24/7 on your Claude Pro/Max subscription over Telegram. Open-source alternative to OpenClaw and NanoClaw — no API keys.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
"build": "node scripts/build.mjs",
|
|
25
25
|
"build:cli": "node scripts/build.mjs && bun build --compile --target=bun-linux-x64 --minify bin/switchroom.ts --outfile switchroom-linux-amd64",
|
|
26
26
|
"pretest": "npm run build",
|
|
27
|
-
"test": "vitest run && bun test telegram-plugin/tests/agent-state-dir-preload.test.ts telegram-plugin/tests/catch-all-forwarded-history.test.ts telegram-plugin/tests/history.test.ts telegram-plugin/tests/boot-briefing-builder.test.ts telegram-plugin/tests/cross-turn-card-gate.test.ts telegram-plugin/tests/emission-authority-open-gate.test.ts telegram-plugin/tests/emission-authority-ping-gate.test.ts telegram-plugin/tests/emission-authority-card-drain-gate.test.ts telegram-plugin/tests/per-topic-current-turn.test.ts telegram-plugin/tests/history-reaper.test.ts telegram-plugin/tests/ipc-server-client.test.ts telegram-plugin/tests/ipc-server-race.test.ts telegram-plugin/tests/ipc-server-buzz-dedup.test.ts telegram-plugin/tests/ipc-server-query-pending-permission.test.ts telegram-plugin/tests/ipc-server-check-pre-approved.test.ts telegram-plugin/tests/rollout-narration-edit-socket.test.ts telegram-plugin/tests/gateway-bridge.test.ts telegram-plugin/tests/gateway-startup-mutex.test.ts telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts telegram-plugin/tests/boot-card-dedupe.test.ts telegram-plugin/tests/boot-card-reason.test.ts telegram-plugin/tests/progress-update.test.ts telegram-plugin/tests/progress-fallback-cap.test.ts telegram-plugin/tests/progress-cap.test.ts telegram-plugin/tests/quota-cache.test.ts telegram-plugin/tests/unhandled-rejection-policy.test.ts telegram-plugin/tests/registry-turns.test.ts telegram-plugin/registry/subagents.test.ts telegram-plugin/registry/subagents-bugs.test.ts telegram-plugin/tests/subagent-watcher-parent-turn-key.test.ts telegram-plugin/tests/worker-origin-gap-dispatch.test.ts telegram-plugin/tests/subagent-nested-dispatch.test.ts telegram-plugin/tests/nested-worker-visibility-harness.test.ts telegram-plugin/tests/turns-writer.test.ts telegram-plugin/tests/resume-inbound-builder.test.ts telegram-plugin/registry/api-registry.test.ts telegram-plugin/registry/turns-schema.test.ts telegram-plugin/tests/idle-footer-wiring.test.ts telegram-plugin/tests/subagent-tracker-hooks.test.ts telegram-plugin/tests/gateway-update-placeholder-dispatch.test.ts telegram-plugin/tests/status-query-telemetry.test.ts telegram-plugin/tests/reaction-trigger.test.ts telegram-plugin/tests/reaction-trigger-flow.test.ts telegram-plugin/gateway/webhook-ingest-server.test.ts telegram-plugin/tests/skill-proposal-card.test.ts",
|
|
27
|
+
"test": "vitest run && bun test telegram-plugin/tests/agent-state-dir-preload.test.ts telegram-plugin/tests/hindsight-bank-preload.test.ts telegram-plugin/tests/catch-all-forwarded-history.test.ts telegram-plugin/tests/history.test.ts telegram-plugin/tests/boot-briefing-builder.test.ts telegram-plugin/tests/cross-turn-card-gate.test.ts telegram-plugin/tests/emission-authority-open-gate.test.ts telegram-plugin/tests/emission-authority-ping-gate.test.ts telegram-plugin/tests/emission-authority-card-drain-gate.test.ts telegram-plugin/tests/per-topic-current-turn.test.ts telegram-plugin/tests/history-reaper.test.ts telegram-plugin/tests/ipc-server-client.test.ts telegram-plugin/tests/ipc-server-race.test.ts telegram-plugin/tests/ipc-server-buzz-dedup.test.ts telegram-plugin/tests/ipc-server-query-pending-permission.test.ts telegram-plugin/tests/ipc-server-check-pre-approved.test.ts telegram-plugin/tests/rollout-narration-edit-socket.test.ts telegram-plugin/tests/gateway-bridge.test.ts telegram-plugin/tests/gateway-startup-mutex.test.ts telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts telegram-plugin/tests/boot-card-dedupe.test.ts telegram-plugin/tests/boot-card-reason.test.ts telegram-plugin/tests/progress-update.test.ts telegram-plugin/tests/progress-fallback-cap.test.ts telegram-plugin/tests/progress-cap.test.ts telegram-plugin/tests/quota-cache.test.ts telegram-plugin/tests/unhandled-rejection-policy.test.ts telegram-plugin/tests/registry-turns.test.ts telegram-plugin/registry/subagents.test.ts telegram-plugin/registry/subagents-bugs.test.ts telegram-plugin/tests/subagent-watcher-parent-turn-key.test.ts telegram-plugin/tests/worker-origin-gap-dispatch.test.ts telegram-plugin/tests/subagent-nested-dispatch.test.ts telegram-plugin/tests/nested-worker-visibility-harness.test.ts telegram-plugin/tests/turns-writer.test.ts telegram-plugin/tests/resume-inbound-builder.test.ts telegram-plugin/registry/api-registry.test.ts telegram-plugin/registry/turns-schema.test.ts telegram-plugin/tests/idle-footer-wiring.test.ts telegram-plugin/tests/subagent-tracker-hooks.test.ts telegram-plugin/tests/gateway-update-placeholder-dispatch.test.ts telegram-plugin/tests/status-query-telemetry.test.ts telegram-plugin/tests/reaction-trigger.test.ts telegram-plugin/tests/reaction-trigger-flow.test.ts telegram-plugin/gateway/webhook-ingest-server.test.ts telegram-plugin/tests/skill-proposal-card.test.ts",
|
|
28
28
|
"test:vitest": "vitest run",
|
|
29
|
-
"test:bun": "bun test telegram-plugin/tests/agent-state-dir-preload.test.ts telegram-plugin/tests/catch-all-forwarded-history.test.ts src/vault/grants.test.ts src/vault/grants-db.test.ts src/vault/write-grants.test.ts src/vault/broker/server-grants.test.ts src/vault/broker/server-write-grants.test.ts src/vault/broker/server-scope-persist.test.ts src/vault/broker/server-tokenless-scope.test.ts src/vault/broker/server-mint-grant-passphrase-attest.test.ts src/vault/broker/server-passphrase-attest.test.ts src/vault/broker/server-mint-grant-posture-attest.test.ts src/vault/broker/server-admin-only-keys.test.ts src/vault/broker/client-token.test.ts src/vault/broker/server-unlock.test.ts src/vault/broker/auto-unlock.test.ts src/vault/broker/drift-detection.test.ts tests/vault-broker-passphrase.test.ts src/cli/vault-get-broker.test.ts src/vault/resolver-via-broker.test.ts src/vault/broker/scope.test.ts src/vault/broker/server.test.ts src/litellm/provision-apply-e2e.test.ts src/drive/disconnect.test.ts src/drive/grants.test.ts src/drive/oauth.test.ts src/drive/onboarding.test.ts src/drive/reconciler.test.ts src/drive/vault-slots.test.ts src/drive/wrapper.test.ts src/vault/approvals/kernel.test.ts src/vault/approvals/approval-origin.test.ts src/vault/approvals/self-approval-bypass.test.ts src/vault/approvals/schema-idempotent.test.ts src/vault/broker/server-approvals.test.ts telegram-plugin/tests/boot-probes.test.ts telegram-plugin/tests/boot-version-string.test.ts telegram-plugin/tests/history.test.ts telegram-plugin/tests/boot-briefing-builder.test.ts telegram-plugin/tests/cross-turn-card-gate.test.ts telegram-plugin/tests/emission-authority-open-gate.test.ts telegram-plugin/tests/emission-authority-ping-gate.test.ts telegram-plugin/tests/emission-authority-card-drain-gate.test.ts telegram-plugin/tests/per-topic-current-turn.test.ts telegram-plugin/tests/history-reaper.test.ts telegram-plugin/tests/ipc-server-client.test.ts telegram-plugin/tests/ipc-server-race.test.ts telegram-plugin/tests/ipc-server-buzz-dedup.test.ts telegram-plugin/tests/ipc-server-query-pending-permission.test.ts telegram-plugin/tests/ipc-server-check-pre-approved.test.ts telegram-plugin/tests/rollout-narration-edit-socket.test.ts telegram-plugin/tests/gateway-bridge.test.ts telegram-plugin/tests/gateway-startup-mutex.test.ts telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts telegram-plugin/tests/boot-card-dedupe.test.ts telegram-plugin/tests/boot-card-reason.test.ts telegram-plugin/tests/progress-update.test.ts telegram-plugin/tests/progress-fallback-cap.test.ts telegram-plugin/tests/progress-cap.test.ts telegram-plugin/tests/quota-cache.test.ts telegram-plugin/tests/silent-reply-guard.test.ts telegram-plugin/tests/unhandled-rejection-policy.test.ts telegram-plugin/tests/registry-turns.test.ts telegram-plugin/registry/subagents.test.ts telegram-plugin/registry/subagents-bugs.test.ts telegram-plugin/tests/subagent-watcher-parent-turn-key.test.ts telegram-plugin/tests/worker-origin-gap-dispatch.test.ts telegram-plugin/tests/subagent-nested-dispatch.test.ts telegram-plugin/tests/nested-worker-visibility-harness.test.ts telegram-plugin/tests/turns-writer.test.ts telegram-plugin/tests/resume-inbound-builder.test.ts telegram-plugin/tests/subagent-tracker-hooks.test.ts telegram-plugin/tests/resolve-calling-subagent.test.ts telegram-plugin/tests/gateway-update-placeholder-dispatch.test.ts telegram-plugin/tests/status-query-telemetry.test.ts telegram-plugin/tests/reaction-trigger.test.ts telegram-plugin/tests/reaction-trigger-flow.test.ts telegram-plugin/tests/subagent-watcher-workflow-visibility.test.ts telegram-plugin/uat/load-env.test.ts telegram-plugin/uat/feed-matcher.test.ts telegram-plugin/uat/uat-driver.test.ts telegram-plugin/gateway/webhook-ingest-server.test.ts telegram-plugin/tests/skill-proposal-card.test.ts",
|
|
29
|
+
"test:bun": "bun test telegram-plugin/tests/agent-state-dir-preload.test.ts telegram-plugin/tests/hindsight-bank-preload.test.ts telegram-plugin/tests/catch-all-forwarded-history.test.ts src/vault/grants.test.ts src/vault/grants-db.test.ts src/vault/write-grants.test.ts src/vault/broker/server-grants.test.ts src/vault/broker/server-write-grants.test.ts src/vault/broker/server-scope-persist.test.ts src/vault/broker/server-tokenless-scope.test.ts src/vault/broker/server-mint-grant-passphrase-attest.test.ts src/vault/broker/server-passphrase-attest.test.ts src/vault/broker/server-mint-grant-posture-attest.test.ts src/vault/broker/server-admin-only-keys.test.ts src/vault/broker/client-token.test.ts src/vault/broker/server-unlock.test.ts src/vault/broker/auto-unlock.test.ts src/vault/broker/drift-detection.test.ts tests/vault-broker-passphrase.test.ts src/cli/vault-get-broker.test.ts src/vault/resolver-via-broker.test.ts src/vault/broker/scope.test.ts src/vault/broker/server.test.ts src/litellm/provision-apply-e2e.test.ts src/drive/disconnect.test.ts src/drive/grants.test.ts src/drive/oauth.test.ts src/drive/onboarding.test.ts src/drive/reconciler.test.ts src/drive/vault-slots.test.ts src/drive/wrapper.test.ts src/vault/approvals/kernel.test.ts src/vault/approvals/approval-origin.test.ts src/vault/approvals/self-approval-bypass.test.ts src/vault/approvals/schema-idempotent.test.ts src/vault/broker/server-approvals.test.ts telegram-plugin/tests/boot-probes.test.ts telegram-plugin/tests/boot-version-string.test.ts telegram-plugin/tests/history.test.ts telegram-plugin/tests/boot-briefing-builder.test.ts telegram-plugin/tests/cross-turn-card-gate.test.ts telegram-plugin/tests/emission-authority-open-gate.test.ts telegram-plugin/tests/emission-authority-ping-gate.test.ts telegram-plugin/tests/emission-authority-card-drain-gate.test.ts telegram-plugin/tests/per-topic-current-turn.test.ts telegram-plugin/tests/history-reaper.test.ts telegram-plugin/tests/ipc-server-client.test.ts telegram-plugin/tests/ipc-server-race.test.ts telegram-plugin/tests/ipc-server-buzz-dedup.test.ts telegram-plugin/tests/ipc-server-query-pending-permission.test.ts telegram-plugin/tests/ipc-server-check-pre-approved.test.ts telegram-plugin/tests/rollout-narration-edit-socket.test.ts telegram-plugin/tests/gateway-bridge.test.ts telegram-plugin/tests/gateway-startup-mutex.test.ts telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts telegram-plugin/tests/boot-card-dedupe.test.ts telegram-plugin/tests/boot-card-reason.test.ts telegram-plugin/tests/progress-update.test.ts telegram-plugin/tests/progress-fallback-cap.test.ts telegram-plugin/tests/progress-cap.test.ts telegram-plugin/tests/quota-cache.test.ts telegram-plugin/tests/silent-reply-guard.test.ts telegram-plugin/tests/unhandled-rejection-policy.test.ts telegram-plugin/tests/registry-turns.test.ts telegram-plugin/registry/subagents.test.ts telegram-plugin/registry/subagents-bugs.test.ts telegram-plugin/tests/subagent-watcher-parent-turn-key.test.ts telegram-plugin/tests/worker-origin-gap-dispatch.test.ts telegram-plugin/tests/subagent-nested-dispatch.test.ts telegram-plugin/tests/nested-worker-visibility-harness.test.ts telegram-plugin/tests/turns-writer.test.ts telegram-plugin/tests/resume-inbound-builder.test.ts telegram-plugin/tests/subagent-tracker-hooks.test.ts telegram-plugin/tests/resolve-calling-subagent.test.ts telegram-plugin/tests/gateway-update-placeholder-dispatch.test.ts telegram-plugin/tests/status-query-telemetry.test.ts telegram-plugin/tests/reaction-trigger.test.ts telegram-plugin/tests/reaction-trigger-flow.test.ts telegram-plugin/tests/subagent-watcher-workflow-visibility.test.ts telegram-plugin/uat/load-env.test.ts telegram-plugin/uat/feed-matcher.test.ts telegram-plugin/uat/uat-driver.test.ts telegram-plugin/gateway/webhook-ingest-server.test.ts telegram-plugin/tests/skill-proposal-card.test.ts",
|
|
30
30
|
"test:watch": "vitest",
|
|
31
|
-
"lint": "tsc --noEmit && node scripts/check-plugin-references.mjs && bash scripts/check-bot-api-wrapping.sh && node scripts/check-bun-test-imports.mjs && node scripts/check-test-runner-coverage.mjs && node scripts/check-bun-module-mock-scope.mjs && node scripts/check-no-pii-secrets.mjs && node scripts/check-vault-test-hermeticity.mjs && node scripts/check-auth-test-hermeticity.mjs && node scripts/check-agent-state-dir-hermeticity.mjs && node scripts/check-no-broadcast-delivery.mjs && node scripts/check-stale-tool-descriptions.mjs && node scripts/check-mcp-instructions-budget.mjs && node scripts/check-web-subscription-honest.mjs && node scripts/check-no-unpinned-npx-playwright.mjs && node scripts/check-gateway-line-ratchet.mjs && node scripts/check-retry-flood-hooks.mjs && node scripts/check-callback-ctx-wrapping.mjs && node scripts/check-status-pin-single-path.mjs && node scripts/check-litellm-config-guard.mjs && node scripts/check-release-asset-names.mjs && node scripts/check-agent-attribution-trailers.mjs && node scripts/check-hindsight-write-redaction.mjs && bun scripts/check-secret-pattern-parity.ts && bun scripts/check-hostd-template-guard.ts",
|
|
31
|
+
"lint": "tsc --noEmit && node scripts/check-plugin-references.mjs && bash scripts/check-bot-api-wrapping.sh && node scripts/check-bun-test-imports.mjs && node scripts/check-test-runner-coverage.mjs && node scripts/check-bun-module-mock-scope.mjs && node scripts/check-no-pii-secrets.mjs && node scripts/check-bench-baseline-anonymised.mjs && node scripts/check-vault-test-hermeticity.mjs && node scripts/check-auth-test-hermeticity.mjs && node scripts/check-agent-state-dir-hermeticity.mjs && node scripts/check-hindsight-bank-hermeticity.mjs && node scripts/check-no-broadcast-delivery.mjs && node scripts/check-stale-tool-descriptions.mjs && node scripts/check-mcp-instructions-budget.mjs && node scripts/check-web-subscription-honest.mjs && node scripts/check-no-unpinned-npx-playwright.mjs && node scripts/check-gateway-line-ratchet.mjs && node scripts/check-retry-flood-hooks.mjs && node scripts/check-callback-ctx-wrapping.mjs && node scripts/check-status-pin-single-path.mjs && node scripts/check-litellm-config-guard.mjs && node scripts/check-release-asset-names.mjs && node scripts/check-changelog-entry.mjs && node scripts/check-agent-attribution-trailers.mjs && node scripts/check-hindsight-write-redaction.mjs && bun scripts/check-secret-pattern-parity.ts && bun scripts/check-hostd-template-guard.ts",
|
|
32
32
|
"lint:tsc": "tsc --noEmit",
|
|
33
33
|
"lint:hindsight-write-redaction": "node scripts/check-hindsight-write-redaction.mjs",
|
|
34
34
|
"lint:secret-pattern-parity": "bun scripts/check-secret-pattern-parity.ts",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"lint:no-pii": "node scripts/check-no-pii-secrets.mjs",
|
|
41
41
|
"lint:auth-test-hermeticity": "node scripts/check-auth-test-hermeticity.mjs",
|
|
42
42
|
"lint:agent-state-dir-hermeticity": "node scripts/check-agent-state-dir-hermeticity.mjs",
|
|
43
|
+
"lint:hindsight-bank-hermeticity": "node scripts/check-hindsight-bank-hermeticity.mjs",
|
|
43
44
|
"lint:web-subscription-honest": "node scripts/check-web-subscription-honest.mjs",
|
|
44
45
|
"lint:no-broadcast-delivery": "node scripts/check-no-broadcast-delivery.mjs",
|
|
45
46
|
"lint:gateway-line-ratchet": "node scripts/check-gateway-line-ratchet.mjs",
|
|
@@ -49,8 +50,10 @@
|
|
|
49
50
|
"lint:mcp-instructions-budget": "node scripts/check-mcp-instructions-budget.mjs",
|
|
50
51
|
"lint:litellm-config-guard": "node scripts/check-litellm-config-guard.mjs",
|
|
51
52
|
"lint:release-asset-contract": "node scripts/check-release-asset-names.mjs",
|
|
53
|
+
"lint:changelog-entry": "node scripts/check-changelog-entry.mjs",
|
|
52
54
|
"lint:agent-attribution-trailers": "node scripts/check-agent-attribution-trailers.mjs",
|
|
53
55
|
"lint:hostd-template-guard": "bun scripts/check-hostd-template-guard.ts",
|
|
56
|
+
"lint:bench-baseline-anonymised": "node scripts/check-bench-baseline-anonymised.mjs",
|
|
54
57
|
"prepublishOnly": "npm run build && npm run lint && npm test"
|
|
55
58
|
},
|
|
56
59
|
"dependencies": {
|
|
@@ -11,7 +11,6 @@ Switchroom ships an enhanced `switchroom-telegram` MCP plugin that replaces the
|
|
|
11
11
|
| `edit_message` | Update a previously sent message. Edits are silent (no push notification). |
|
|
12
12
|
| `delete_message` | Remove a bot-sent message (48h Telegram API limit). |
|
|
13
13
|
| `forward_message` | Quote/resurface earlier messages with thread support. |
|
|
14
|
-
| `pin_message` | Pin important outputs (requires bot admin). |
|
|
15
14
|
| `send_typing` | Show typing indicator (5s auto-expire). Use during long operations. |
|
|
16
15
|
| `download_attachment` | Fetch files attached to inbound messages. |
|
|
17
16
|
| `get_recent_messages` | Query SQLite history buffer with pagination and thread filtering. |
|
|
@@ -299,7 +299,6 @@ The `switchroom-telegram` plugin is an enhanced fork of the official Telegram MC
|
|
|
299
299
|
| `edit_message` | Modify an earlier bot message's text |
|
|
300
300
|
| `delete_message` | Remove an earlier bot message |
|
|
301
301
|
| `forward_message` | Forward a message from another chat |
|
|
302
|
-
| `pin_message` | Pin a message in the current chat |
|
|
303
302
|
| `send_typing` | Show the "typing…" indicator |
|
|
304
303
|
| `download_attachment` | Save a Telegram file attachment to the agent's inbox |
|
|
305
304
|
| `get_recent_messages` | Fetch recent history for context |
|