switchroom 0.19.22 → 0.19.24
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 +95 -2
- package/dist/cli/notion-write-pretool.mjs +5 -2
- package/dist/cli/switchroom.js +749 -357
- package/dist/host-control/main.js +96 -3
- package/dist/vault/approvals/kernel-server.js +98 -5
- package/dist/vault/broker/server.js +98 -5
- package/package.json +5 -4
- package/profiles/_base/start.sh.hbs +101 -0
- package/profiles/_shared/agent-self-service.md.hbs +64 -109
- package/profiles/_shared/delegation-golden-rule.md.hbs +5 -5
- package/profiles/_shared/dev-protocol.md.hbs +12 -42
- package/profiles/_shared/execution-discipline.md.hbs +7 -14
- package/profiles/coding/CLAUDE.md.hbs +0 -6
- package/profiles/default/CLAUDE.md.hbs +21 -50
- package/skills/dev-protocol/SKILL.md +97 -107
- package/skills/switchroom-release/SKILL.md +2 -1
- package/telegram-plugin/bunfig.toml +10 -0
- package/telegram-plugin/dist/gateway/gateway.js +267 -52
- package/telegram-plugin/gateway/backstop-delivery.ts +97 -16
- package/telegram-plugin/gateway/captured-answer-resume.ts +46 -17
- package/telegram-plugin/gateway/gateway.ts +43 -42
- package/telegram-plugin/gateway/latest-turn-lookup.ts +60 -0
- package/telegram-plugin/gateway/outbound-send-path.ts +61 -22
- package/telegram-plugin/gateway/stream-render.ts +6 -0
- package/telegram-plugin/gateway/subagent-handback-marker.ts +1 -1
- package/telegram-plugin/gateway/turn-end.ts +1 -1
- package/telegram-plugin/gateway/turn-record-status.ts +19 -0
- package/telegram-plugin/gateway/turns-jsonl-rotate.ts +65 -0
- package/telegram-plugin/reply-owner-resolve.ts +110 -9
- package/telegram-plugin/send-gate-degraded.test.ts +45 -16
- package/telegram-plugin/send-gate.ts +185 -24
- package/telegram-plugin/tests/activity-card-send-gate.test.ts +9 -9
- package/telegram-plugin/tests/agent-state-dir-preload.test.ts +33 -0
- package/telegram-plugin/tests/backstop-delivery.test.ts +204 -7
- package/telegram-plugin/tests/backstop-readback-probe.test.ts +12 -0
- package/telegram-plugin/tests/captured-answer-resume.test.ts +104 -0
- package/telegram-plugin/tests/latest-turn-lookup.test.ts +77 -0
- package/telegram-plugin/tests/narrative-lane-golden.test.ts +23 -1
- package/telegram-plugin/tests/reply-owner-resolve.test.ts +531 -0
- package/telegram-plugin/tests/send-reply-golden.test.ts +296 -28
- package/telegram-plugin/tests/stream-controller-send-gate.test.ts +134 -28
- package/telegram-plugin/tests/stream-render-golden.test.ts +25 -3
- package/telegram-plugin/tests/turns-jsonl-rotate.test.ts +92 -1
- package/vendor/hindsight-memory/scripts/drain_pending.py +113 -11
- package/vendor/hindsight-memory/scripts/lib/pending.py +802 -65
- package/vendor/hindsight-memory/scripts/lib/retain_split.py +54 -7
- package/vendor/hindsight-memory/scripts/tests/test_pending_drops.py +1445 -11
- package/vendor/hindsight-memory/scripts/tests/test_retain_split.py +78 -6
- package/vendor/hindsight-memory/tests/test_drain_pending.py +17 -2
- package/vendor/hindsight-memory/tests/test_pending.py +12 -4
|
@@ -19434,16 +19434,19 @@ var HindsightPerOpLlmSchema = exports_external.object({
|
|
|
19434
19434
|
model: exports_external.string().min(1).optional().describe("Per-op model (upstream `HINDSIGHT_API_<OP>_LLM_MODEL`). Absent → " + "inherit the global `hindsight.llm.model`."),
|
|
19435
19435
|
provider: exports_external.string().min(1).optional().describe("Per-op provider (upstream `HINDSIGHT_API_<OP>_LLM_PROVIDER`). " + "Absent → inherit the global `hindsight.llm.provider`."),
|
|
19436
19436
|
base_url: exports_external.string().min(1).optional().describe("Per-op base URL (upstream `HINDSIGHT_API_<OP>_LLM_BASE_URL`). " + "Optional passthrough; absent → inherit the global."),
|
|
19437
|
-
api_key: exports_external.string().min(1).optional().describe("Per-op API key (upstream `HINDSIGHT_API_<OP>_LLM_API_KEY`). Literal " + "or `vault:` reference. Optional passthrough; absent → inherit global.")
|
|
19437
|
+
api_key: exports_external.string().min(1).optional().describe("Per-op API key (upstream `HINDSIGHT_API_<OP>_LLM_API_KEY`). Literal " + "or `vault:` reference. Optional passthrough; absent → inherit global."),
|
|
19438
|
+
context_window: exports_external.number().int().positive().optional().describe("Context window (tokens) of the backend serving THIS op. NOT an " + "upstream env var — switchroom derives the op's token budget " + "(consolidation batch size / max-completion caps / reflect " + "max-context cap) from it so a single call can never overflow the " + "window. Absent → inherit " + "`hindsight.llm.context_window`, else a per-provider default " + "(conservative for non-`claude-code` providers, which usually mean " + "a local llama.cpp/Ollama slot; a self-hosted `base_url` — loopback, " + "RFC1918, `.local`/`.internal` — forces the conservative default too, " + "regardless of the provider NAME, since the endpoint is where the " + "traffic actually terminates). All three lanes (`retain`, " + "`reflect`, `consolidation`) are budgeted independently.")
|
|
19438
19439
|
}).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.");
|
|
19439
19440
|
var HindsightConfigSchema = exports_external.object({
|
|
19440
19441
|
llm: exports_external.object({
|
|
19441
19442
|
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."),
|
|
19442
19443
|
model: exports_external.string().min(1).optional().describe("Hindsight LLM model (upstream `HINDSIGHT_API_LLM_MODEL`). Defaults " + "to HINDSIGHT_DEFAULT_MODEL. Any model your LiteLLM proxy can route " + "is valid, e.g. `openrouter/z-ai/glm-5.2` when routing through the " + "fleet proxy. With provider=claude-code this value is ALSO exported " + "as `ANTHROPIC_MODEL` to the claude subprocess. Serves as the GLOBAL " + "default for every op absent a per-op override."),
|
|
19444
|
+
context_window: exports_external.number().int().positive().optional().describe("GLOBAL context window (tokens) of the backend serving hindsight's " + "LLM ops — the declared size switchroom derives every token budget " + "from. Set this to the real window of whatever you point " + "`hindsight.llm` at (e.g. 32768 for a llama.cpp slot launched with " + "`-c 65536 -np 2`, 131072 for a large-window OpenRouter model). " + "Absent → a per-provider default: 200000 for `claude-code`, a " + "conservative 32768 for everything else. Overflowing a local " + "backend's window does NOT error — llama.cpp context-shift silently " + "drops the system prompt and the model answers conversationally " + "with HTTP 200 — so this value is what makes the failure " + "detectable at setup time instead of never."),
|
|
19443
19445
|
retain: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `retain` LLM op (memory ingestion). Emits " + "`HINDSIGHT_API_RETAIN_LLM_*`. Absent → uses the global model/provider."),
|
|
19444
19446
|
reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent → uses global."),
|
|
19445
19447
|
consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent → global.")
|
|
19446
|
-
}).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.")
|
|
19448
|
+
}).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."),
|
|
19449
|
+
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, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT), 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), 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).")
|
|
19447
19450
|
});
|
|
19448
19451
|
var MicrosoftWorkspaceConfigSchema = exports_external.object({
|
|
19449
19452
|
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)."),
|
|
@@ -21120,7 +21123,7 @@ function allocateAgentUid(name) {
|
|
|
21120
21123
|
}
|
|
21121
21124
|
|
|
21122
21125
|
// src/build-info.ts
|
|
21123
|
-
var VERSION = "0.19.
|
|
21126
|
+
var VERSION = "0.19.24";
|
|
21124
21127
|
|
|
21125
21128
|
// src/cli/agent-config.ts
|
|
21126
21129
|
import { join as join2 } from "node:path";
|
|
@@ -21213,6 +21216,96 @@ function assertPositive(value, label) {
|
|
|
21213
21216
|
}
|
|
21214
21217
|
}
|
|
21215
21218
|
|
|
21219
|
+
// src/setup/hindsight-perf-defaults.ts
|
|
21220
|
+
var HINDSIGHT_RERANKER_MAX_CANDIDATES_FOR_DERIVATION = 150;
|
|
21221
|
+
var HINDSIGHT_DEFAULT_RECALL_MAX_CANDIDATES_PER_SOURCE = Math.ceil(HINDSIGHT_RERANKER_MAX_CANDIDATES_FOR_DERIVATION * 0.4);
|
|
21222
|
+
var HINDSIGHT_DEFAULT_LINK_EXPANSION_PER_ENTITY_LIMIT = 50;
|
|
21223
|
+
var HINDSIGHT_DEFAULT_LINK_EXPANSION_TIMEOUT_S = 2;
|
|
21224
|
+
var HINDSIGHT_DEFAULT_LLM_REASONING_EFFORT = "low";
|
|
21225
|
+
var HINDSIGHT_DEFAULT_LLM_MAX_CONCURRENT = 4;
|
|
21226
|
+
var HINDSIGHT_DEFAULT_RETAIN_LLM_MAX_CONCURRENT = 1;
|
|
21227
|
+
var HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_MAX_CONCURRENT = 1;
|
|
21228
|
+
var HINDSIGHT_DEFAULT_RERANKER_LOCAL_FP16 = "true";
|
|
21229
|
+
var HINDSIGHT_DEFAULT_RERANKER_LOCAL_BATCH_SIZE = 128;
|
|
21230
|
+
var HINDSIGHT_DEFAULT_LLM_STRICT_SCHEMA = "true";
|
|
21231
|
+
var HINDSIGHT_DEFAULT_LLM_MAX_RETRIES = 2;
|
|
21232
|
+
var HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_PARALLELISM = 2;
|
|
21233
|
+
var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
21234
|
+
[
|
|
21235
|
+
"HINDSIGHT_API_RECALL_MAX_CANDIDATES_PER_SOURCE",
|
|
21236
|
+
String(HINDSIGHT_DEFAULT_RECALL_MAX_CANDIDATES_PER_SOURCE)
|
|
21237
|
+
],
|
|
21238
|
+
[
|
|
21239
|
+
"HINDSIGHT_API_LINK_EXPANSION_PER_ENTITY_LIMIT",
|
|
21240
|
+
String(HINDSIGHT_DEFAULT_LINK_EXPANSION_PER_ENTITY_LIMIT)
|
|
21241
|
+
],
|
|
21242
|
+
[
|
|
21243
|
+
"HINDSIGHT_API_LINK_EXPANSION_TIMEOUT",
|
|
21244
|
+
String(HINDSIGHT_DEFAULT_LINK_EXPANSION_TIMEOUT_S)
|
|
21245
|
+
],
|
|
21246
|
+
["HINDSIGHT_API_LLM_REASONING_EFFORT", HINDSIGHT_DEFAULT_LLM_REASONING_EFFORT],
|
|
21247
|
+
[
|
|
21248
|
+
"HINDSIGHT_API_CONSOLIDATION_LLM_PARALLELISM",
|
|
21249
|
+
String(HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_PARALLELISM)
|
|
21250
|
+
]
|
|
21251
|
+
];
|
|
21252
|
+
var HINDSIGHT_PERF_DEFAULTS_GPU = [
|
|
21253
|
+
["HINDSIGHT_API_RERANKER_LOCAL_FP16", HINDSIGHT_DEFAULT_RERANKER_LOCAL_FP16],
|
|
21254
|
+
[
|
|
21255
|
+
"HINDSIGHT_API_RERANKER_LOCAL_BATCH_SIZE",
|
|
21256
|
+
String(HINDSIGHT_DEFAULT_RERANKER_LOCAL_BATCH_SIZE)
|
|
21257
|
+
]
|
|
21258
|
+
];
|
|
21259
|
+
var HINDSIGHT_PERF_DEFAULTS_LOCAL_LLM = [
|
|
21260
|
+
["HINDSIGHT_API_LLM_MAX_CONCURRENT", String(HINDSIGHT_DEFAULT_LLM_MAX_CONCURRENT)],
|
|
21261
|
+
[
|
|
21262
|
+
"HINDSIGHT_API_RETAIN_LLM_MAX_CONCURRENT",
|
|
21263
|
+
String(HINDSIGHT_DEFAULT_RETAIN_LLM_MAX_CONCURRENT)
|
|
21264
|
+
],
|
|
21265
|
+
[
|
|
21266
|
+
"HINDSIGHT_API_CONSOLIDATION_LLM_MAX_CONCURRENT",
|
|
21267
|
+
String(HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_MAX_CONCURRENT)
|
|
21268
|
+
],
|
|
21269
|
+
["HINDSIGHT_API_LLM_STRICT_SCHEMA", HINDSIGHT_DEFAULT_LLM_STRICT_SCHEMA],
|
|
21270
|
+
["HINDSIGHT_API_LLM_MAX_RETRIES", String(HINDSIGHT_DEFAULT_LLM_MAX_RETRIES)]
|
|
21271
|
+
];
|
|
21272
|
+
var HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS = new Set([
|
|
21273
|
+
"HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY"
|
|
21274
|
+
]);
|
|
21275
|
+
var HINDSIGHT_PERF_ENV_KEYS = new Set([
|
|
21276
|
+
...[
|
|
21277
|
+
...HINDSIGHT_PERF_DEFAULTS_UNGATED,
|
|
21278
|
+
...HINDSIGHT_PERF_DEFAULTS_GPU,
|
|
21279
|
+
...HINDSIGHT_PERF_DEFAULTS_LOCAL_LLM
|
|
21280
|
+
].map(([k]) => k),
|
|
21281
|
+
...HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS
|
|
21282
|
+
]);
|
|
21283
|
+
|
|
21284
|
+
// src/setup/hindsight-pg-defaults.ts
|
|
21285
|
+
var HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION = 8 * 1024;
|
|
21286
|
+
var HINDSIGHT_PG_APP_ANON_MIB = 2560;
|
|
21287
|
+
var HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB = 2048;
|
|
21288
|
+
var HINDSIGHT_PG_SHARED_BUFFERS_BUDGET_MIB = HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION - HINDSIGHT_PG_APP_ANON_MIB - HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB;
|
|
21289
|
+
var HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB = 1536;
|
|
21290
|
+
var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB = 4096;
|
|
21291
|
+
function pgMib(mib) {
|
|
21292
|
+
return `${mib}MB`;
|
|
21293
|
+
}
|
|
21294
|
+
var HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE_ENV = "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE";
|
|
21295
|
+
var HINDSIGHT_PG_SHARED_BUFFERS_ENV = "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS";
|
|
21296
|
+
var HINDSIGHT_PG_DEFAULTS = [
|
|
21297
|
+
[
|
|
21298
|
+
HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE_ENV,
|
|
21299
|
+
pgMib(HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB)
|
|
21300
|
+
],
|
|
21301
|
+
[HINDSIGHT_PG_SHARED_BUFFERS_ENV, pgMib(HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB)]
|
|
21302
|
+
];
|
|
21303
|
+
var HINDSIGHT_PG_ENV_KEYS = new Set(HINDSIGHT_PG_DEFAULTS.map(([k]) => k));
|
|
21304
|
+
|
|
21305
|
+
// src/setup/hindsight-context-budget.ts
|
|
21306
|
+
var HINDSIGHT_UPSTREAM_RETAIN_CHUNK_SIZE = 3000;
|
|
21307
|
+
var HINDSIGHT_RETAIN_MAX_COMPLETION_FLOOR = HINDSIGHT_UPSTREAM_RETAIN_CHUNK_SIZE + 72;
|
|
21308
|
+
|
|
21216
21309
|
// src/setup/hindsight.ts
|
|
21217
21310
|
var HINDSIGHT_DEFAULT_API_PORT = 18888;
|
|
21218
21311
|
var HINDSIGHT_DEFAULT_MCP_URL = `http://127.0.0.1:${HINDSIGHT_DEFAULT_API_PORT}/mcp/`;
|
|
@@ -4377,16 +4377,19 @@ var init_schema = __esm(() => {
|
|
|
4377
4377
|
model: exports_external.string().min(1).optional().describe("Per-op model (upstream `HINDSIGHT_API_<OP>_LLM_MODEL`). Absent → " + "inherit the global `hindsight.llm.model`."),
|
|
4378
4378
|
provider: exports_external.string().min(1).optional().describe("Per-op provider (upstream `HINDSIGHT_API_<OP>_LLM_PROVIDER`). " + "Absent → inherit the global `hindsight.llm.provider`."),
|
|
4379
4379
|
base_url: exports_external.string().min(1).optional().describe("Per-op base URL (upstream `HINDSIGHT_API_<OP>_LLM_BASE_URL`). " + "Optional passthrough; absent → inherit the global."),
|
|
4380
|
-
api_key: exports_external.string().min(1).optional().describe("Per-op API key (upstream `HINDSIGHT_API_<OP>_LLM_API_KEY`). Literal " + "or `vault:` reference. Optional passthrough; absent → inherit global.")
|
|
4380
|
+
api_key: exports_external.string().min(1).optional().describe("Per-op API key (upstream `HINDSIGHT_API_<OP>_LLM_API_KEY`). Literal " + "or `vault:` reference. Optional passthrough; absent → inherit global."),
|
|
4381
|
+
context_window: exports_external.number().int().positive().optional().describe("Context window (tokens) of the backend serving THIS op. NOT an " + "upstream env var — switchroom derives the op's token budget " + "(consolidation batch size / max-completion caps / reflect " + "max-context cap) from it so a single call can never overflow the " + "window. Absent → inherit " + "`hindsight.llm.context_window`, else a per-provider default " + "(conservative for non-`claude-code` providers, which usually mean " + "a local llama.cpp/Ollama slot; a self-hosted `base_url` — loopback, " + "RFC1918, `.local`/`.internal` — forces the conservative default too, " + "regardless of the provider NAME, since the endpoint is where the " + "traffic actually terminates). All three lanes (`retain`, " + "`reflect`, `consolidation`) are budgeted independently.")
|
|
4381
4382
|
}).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.");
|
|
4382
4383
|
HindsightConfigSchema = exports_external.object({
|
|
4383
4384
|
llm: exports_external.object({
|
|
4384
4385
|
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."),
|
|
4385
4386
|
model: exports_external.string().min(1).optional().describe("Hindsight LLM model (upstream `HINDSIGHT_API_LLM_MODEL`). Defaults " + "to HINDSIGHT_DEFAULT_MODEL. Any model your LiteLLM proxy can route " + "is valid, e.g. `openrouter/z-ai/glm-5.2` when routing through the " + "fleet proxy. With provider=claude-code this value is ALSO exported " + "as `ANTHROPIC_MODEL` to the claude subprocess. Serves as the GLOBAL " + "default for every op absent a per-op override."),
|
|
4387
|
+
context_window: exports_external.number().int().positive().optional().describe("GLOBAL context window (tokens) of the backend serving hindsight's " + "LLM ops — the declared size switchroom derives every token budget " + "from. Set this to the real window of whatever you point " + "`hindsight.llm` at (e.g. 32768 for a llama.cpp slot launched with " + "`-c 65536 -np 2`, 131072 for a large-window OpenRouter model). " + "Absent → a per-provider default: 200000 for `claude-code`, a " + "conservative 32768 for everything else. Overflowing a local " + "backend's window does NOT error — llama.cpp context-shift silently " + "drops the system prompt and the model answers conversationally " + "with HTTP 200 — so this value is what makes the failure " + "detectable at setup time instead of never."),
|
|
4386
4388
|
retain: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `retain` LLM op (memory ingestion). Emits " + "`HINDSIGHT_API_RETAIN_LLM_*`. Absent → uses the global model/provider."),
|
|
4387
4389
|
reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent → uses global."),
|
|
4388
4390
|
consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent → global.")
|
|
4389
|
-
}).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.")
|
|
4391
|
+
}).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."),
|
|
4392
|
+
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, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT), 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), 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).")
|
|
4390
4393
|
});
|
|
4391
4394
|
MicrosoftWorkspaceConfigSchema = exports_external.object({
|
|
4392
4395
|
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)."),
|
|
@@ -19188,6 +19191,99 @@ function assertPositive(value, label) {
|
|
|
19188
19191
|
}
|
|
19189
19192
|
}
|
|
19190
19193
|
|
|
19194
|
+
// src/setup/host-capabilities.ts
|
|
19195
|
+
init_paths();
|
|
19196
|
+
|
|
19197
|
+
// src/setup/hindsight-perf-defaults.ts
|
|
19198
|
+
var HINDSIGHT_RERANKER_MAX_CANDIDATES_FOR_DERIVATION = 150;
|
|
19199
|
+
var HINDSIGHT_DEFAULT_RECALL_MAX_CANDIDATES_PER_SOURCE = Math.ceil(HINDSIGHT_RERANKER_MAX_CANDIDATES_FOR_DERIVATION * 0.4);
|
|
19200
|
+
var HINDSIGHT_DEFAULT_LINK_EXPANSION_PER_ENTITY_LIMIT = 50;
|
|
19201
|
+
var HINDSIGHT_DEFAULT_LINK_EXPANSION_TIMEOUT_S = 2;
|
|
19202
|
+
var HINDSIGHT_DEFAULT_LLM_REASONING_EFFORT = "low";
|
|
19203
|
+
var HINDSIGHT_DEFAULT_LLM_MAX_CONCURRENT = 4;
|
|
19204
|
+
var HINDSIGHT_DEFAULT_RETAIN_LLM_MAX_CONCURRENT = 1;
|
|
19205
|
+
var HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_MAX_CONCURRENT = 1;
|
|
19206
|
+
var HINDSIGHT_DEFAULT_RERANKER_LOCAL_FP16 = "true";
|
|
19207
|
+
var HINDSIGHT_DEFAULT_RERANKER_LOCAL_BATCH_SIZE = 128;
|
|
19208
|
+
var HINDSIGHT_DEFAULT_LLM_STRICT_SCHEMA = "true";
|
|
19209
|
+
var HINDSIGHT_DEFAULT_LLM_MAX_RETRIES = 2;
|
|
19210
|
+
var HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_PARALLELISM = 2;
|
|
19211
|
+
var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
19212
|
+
[
|
|
19213
|
+
"HINDSIGHT_API_RECALL_MAX_CANDIDATES_PER_SOURCE",
|
|
19214
|
+
String(HINDSIGHT_DEFAULT_RECALL_MAX_CANDIDATES_PER_SOURCE)
|
|
19215
|
+
],
|
|
19216
|
+
[
|
|
19217
|
+
"HINDSIGHT_API_LINK_EXPANSION_PER_ENTITY_LIMIT",
|
|
19218
|
+
String(HINDSIGHT_DEFAULT_LINK_EXPANSION_PER_ENTITY_LIMIT)
|
|
19219
|
+
],
|
|
19220
|
+
[
|
|
19221
|
+
"HINDSIGHT_API_LINK_EXPANSION_TIMEOUT",
|
|
19222
|
+
String(HINDSIGHT_DEFAULT_LINK_EXPANSION_TIMEOUT_S)
|
|
19223
|
+
],
|
|
19224
|
+
["HINDSIGHT_API_LLM_REASONING_EFFORT", HINDSIGHT_DEFAULT_LLM_REASONING_EFFORT],
|
|
19225
|
+
[
|
|
19226
|
+
"HINDSIGHT_API_CONSOLIDATION_LLM_PARALLELISM",
|
|
19227
|
+
String(HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_PARALLELISM)
|
|
19228
|
+
]
|
|
19229
|
+
];
|
|
19230
|
+
var HINDSIGHT_PERF_DEFAULTS_GPU = [
|
|
19231
|
+
["HINDSIGHT_API_RERANKER_LOCAL_FP16", HINDSIGHT_DEFAULT_RERANKER_LOCAL_FP16],
|
|
19232
|
+
[
|
|
19233
|
+
"HINDSIGHT_API_RERANKER_LOCAL_BATCH_SIZE",
|
|
19234
|
+
String(HINDSIGHT_DEFAULT_RERANKER_LOCAL_BATCH_SIZE)
|
|
19235
|
+
]
|
|
19236
|
+
];
|
|
19237
|
+
var HINDSIGHT_PERF_DEFAULTS_LOCAL_LLM = [
|
|
19238
|
+
["HINDSIGHT_API_LLM_MAX_CONCURRENT", String(HINDSIGHT_DEFAULT_LLM_MAX_CONCURRENT)],
|
|
19239
|
+
[
|
|
19240
|
+
"HINDSIGHT_API_RETAIN_LLM_MAX_CONCURRENT",
|
|
19241
|
+
String(HINDSIGHT_DEFAULT_RETAIN_LLM_MAX_CONCURRENT)
|
|
19242
|
+
],
|
|
19243
|
+
[
|
|
19244
|
+
"HINDSIGHT_API_CONSOLIDATION_LLM_MAX_CONCURRENT",
|
|
19245
|
+
String(HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_MAX_CONCURRENT)
|
|
19246
|
+
],
|
|
19247
|
+
["HINDSIGHT_API_LLM_STRICT_SCHEMA", HINDSIGHT_DEFAULT_LLM_STRICT_SCHEMA],
|
|
19248
|
+
["HINDSIGHT_API_LLM_MAX_RETRIES", String(HINDSIGHT_DEFAULT_LLM_MAX_RETRIES)]
|
|
19249
|
+
];
|
|
19250
|
+
var HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS = new Set([
|
|
19251
|
+
"HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY"
|
|
19252
|
+
]);
|
|
19253
|
+
var HINDSIGHT_PERF_ENV_KEYS = new Set([
|
|
19254
|
+
...[
|
|
19255
|
+
...HINDSIGHT_PERF_DEFAULTS_UNGATED,
|
|
19256
|
+
...HINDSIGHT_PERF_DEFAULTS_GPU,
|
|
19257
|
+
...HINDSIGHT_PERF_DEFAULTS_LOCAL_LLM
|
|
19258
|
+
].map(([k]) => k),
|
|
19259
|
+
...HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS
|
|
19260
|
+
]);
|
|
19261
|
+
|
|
19262
|
+
// src/setup/hindsight-pg-defaults.ts
|
|
19263
|
+
var HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION = 8 * 1024;
|
|
19264
|
+
var HINDSIGHT_PG_APP_ANON_MIB = 2560;
|
|
19265
|
+
var HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB = 2048;
|
|
19266
|
+
var HINDSIGHT_PG_SHARED_BUFFERS_BUDGET_MIB = HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION - HINDSIGHT_PG_APP_ANON_MIB - HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB;
|
|
19267
|
+
var HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB = 1536;
|
|
19268
|
+
var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB = 4096;
|
|
19269
|
+
function pgMib(mib) {
|
|
19270
|
+
return `${mib}MB`;
|
|
19271
|
+
}
|
|
19272
|
+
var HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE_ENV = "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE";
|
|
19273
|
+
var HINDSIGHT_PG_SHARED_BUFFERS_ENV = "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS";
|
|
19274
|
+
var HINDSIGHT_PG_DEFAULTS = [
|
|
19275
|
+
[
|
|
19276
|
+
HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE_ENV,
|
|
19277
|
+
pgMib(HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB)
|
|
19278
|
+
],
|
|
19279
|
+
[HINDSIGHT_PG_SHARED_BUFFERS_ENV, pgMib(HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB)]
|
|
19280
|
+
];
|
|
19281
|
+
var HINDSIGHT_PG_ENV_KEYS = new Set(HINDSIGHT_PG_DEFAULTS.map(([k]) => k));
|
|
19282
|
+
|
|
19283
|
+
// src/setup/hindsight-context-budget.ts
|
|
19284
|
+
var HINDSIGHT_UPSTREAM_RETAIN_CHUNK_SIZE = 3000;
|
|
19285
|
+
var HINDSIGHT_RETAIN_MAX_COMPLETION_FLOOR = HINDSIGHT_UPSTREAM_RETAIN_CHUNK_SIZE + 72;
|
|
19286
|
+
|
|
19191
19287
|
// src/setup/hindsight.ts
|
|
19192
19288
|
var HINDSIGHT_DEFAULT_API_PORT = 18888;
|
|
19193
19289
|
var HINDSIGHT_DEFAULT_MCP_URL = `http://127.0.0.1:${HINDSIGHT_DEFAULT_API_PORT}/mcp/`;
|
|
@@ -19300,9 +19396,6 @@ var DOCKER_HOOKS_PATH = `${DOCKER_TELEGRAM_PLUGIN_PATH}/hooks`;
|
|
|
19300
19396
|
init_merge();
|
|
19301
19397
|
init_timezone();
|
|
19302
19398
|
|
|
19303
|
-
// src/setup/host-capabilities.ts
|
|
19304
|
-
init_paths();
|
|
19305
|
-
|
|
19306
19399
|
// src/vault/grants-db-path.ts
|
|
19307
19400
|
var GRANTS_DB_DIRNAME = "vault-broker";
|
|
19308
19401
|
var GRANTS_DB_FILENAME = "vault-grants.db";
|
|
@@ -4377,16 +4377,19 @@ var init_schema = __esm(() => {
|
|
|
4377
4377
|
model: exports_external.string().min(1).optional().describe("Per-op model (upstream `HINDSIGHT_API_<OP>_LLM_MODEL`). Absent → " + "inherit the global `hindsight.llm.model`."),
|
|
4378
4378
|
provider: exports_external.string().min(1).optional().describe("Per-op provider (upstream `HINDSIGHT_API_<OP>_LLM_PROVIDER`). " + "Absent → inherit the global `hindsight.llm.provider`."),
|
|
4379
4379
|
base_url: exports_external.string().min(1).optional().describe("Per-op base URL (upstream `HINDSIGHT_API_<OP>_LLM_BASE_URL`). " + "Optional passthrough; absent → inherit the global."),
|
|
4380
|
-
api_key: exports_external.string().min(1).optional().describe("Per-op API key (upstream `HINDSIGHT_API_<OP>_LLM_API_KEY`). Literal " + "or `vault:` reference. Optional passthrough; absent → inherit global.")
|
|
4380
|
+
api_key: exports_external.string().min(1).optional().describe("Per-op API key (upstream `HINDSIGHT_API_<OP>_LLM_API_KEY`). Literal " + "or `vault:` reference. Optional passthrough; absent → inherit global."),
|
|
4381
|
+
context_window: exports_external.number().int().positive().optional().describe("Context window (tokens) of the backend serving THIS op. NOT an " + "upstream env var — switchroom derives the op's token budget " + "(consolidation batch size / max-completion caps / reflect " + "max-context cap) from it so a single call can never overflow the " + "window. Absent → inherit " + "`hindsight.llm.context_window`, else a per-provider default " + "(conservative for non-`claude-code` providers, which usually mean " + "a local llama.cpp/Ollama slot; a self-hosted `base_url` — loopback, " + "RFC1918, `.local`/`.internal` — forces the conservative default too, " + "regardless of the provider NAME, since the endpoint is where the " + "traffic actually terminates). All three lanes (`retain`, " + "`reflect`, `consolidation`) are budgeted independently.")
|
|
4381
4382
|
}).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.");
|
|
4382
4383
|
HindsightConfigSchema = exports_external.object({
|
|
4383
4384
|
llm: exports_external.object({
|
|
4384
4385
|
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."),
|
|
4385
4386
|
model: exports_external.string().min(1).optional().describe("Hindsight LLM model (upstream `HINDSIGHT_API_LLM_MODEL`). Defaults " + "to HINDSIGHT_DEFAULT_MODEL. Any model your LiteLLM proxy can route " + "is valid, e.g. `openrouter/z-ai/glm-5.2` when routing through the " + "fleet proxy. With provider=claude-code this value is ALSO exported " + "as `ANTHROPIC_MODEL` to the claude subprocess. Serves as the GLOBAL " + "default for every op absent a per-op override."),
|
|
4387
|
+
context_window: exports_external.number().int().positive().optional().describe("GLOBAL context window (tokens) of the backend serving hindsight's " + "LLM ops — the declared size switchroom derives every token budget " + "from. Set this to the real window of whatever you point " + "`hindsight.llm` at (e.g. 32768 for a llama.cpp slot launched with " + "`-c 65536 -np 2`, 131072 for a large-window OpenRouter model). " + "Absent → a per-provider default: 200000 for `claude-code`, a " + "conservative 32768 for everything else. Overflowing a local " + "backend's window does NOT error — llama.cpp context-shift silently " + "drops the system prompt and the model answers conversationally " + "with HTTP 200 — so this value is what makes the failure " + "detectable at setup time instead of never."),
|
|
4386
4388
|
retain: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `retain` LLM op (memory ingestion). Emits " + "`HINDSIGHT_API_RETAIN_LLM_*`. Absent → uses the global model/provider."),
|
|
4387
4389
|
reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent → uses global."),
|
|
4388
4390
|
consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent → global.")
|
|
4389
|
-
}).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.")
|
|
4391
|
+
}).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."),
|
|
4392
|
+
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, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT), 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), 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).")
|
|
4390
4393
|
});
|
|
4391
4394
|
MicrosoftWorkspaceConfigSchema = exports_external.object({
|
|
4392
4395
|
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)."),
|
|
@@ -18861,6 +18864,99 @@ function assertPositive(value, label) {
|
|
|
18861
18864
|
}
|
|
18862
18865
|
}
|
|
18863
18866
|
|
|
18867
|
+
// src/setup/host-capabilities.ts
|
|
18868
|
+
init_paths();
|
|
18869
|
+
|
|
18870
|
+
// src/setup/hindsight-perf-defaults.ts
|
|
18871
|
+
var HINDSIGHT_RERANKER_MAX_CANDIDATES_FOR_DERIVATION = 150;
|
|
18872
|
+
var HINDSIGHT_DEFAULT_RECALL_MAX_CANDIDATES_PER_SOURCE = Math.ceil(HINDSIGHT_RERANKER_MAX_CANDIDATES_FOR_DERIVATION * 0.4);
|
|
18873
|
+
var HINDSIGHT_DEFAULT_LINK_EXPANSION_PER_ENTITY_LIMIT = 50;
|
|
18874
|
+
var HINDSIGHT_DEFAULT_LINK_EXPANSION_TIMEOUT_S = 2;
|
|
18875
|
+
var HINDSIGHT_DEFAULT_LLM_REASONING_EFFORT = "low";
|
|
18876
|
+
var HINDSIGHT_DEFAULT_LLM_MAX_CONCURRENT = 4;
|
|
18877
|
+
var HINDSIGHT_DEFAULT_RETAIN_LLM_MAX_CONCURRENT = 1;
|
|
18878
|
+
var HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_MAX_CONCURRENT = 1;
|
|
18879
|
+
var HINDSIGHT_DEFAULT_RERANKER_LOCAL_FP16 = "true";
|
|
18880
|
+
var HINDSIGHT_DEFAULT_RERANKER_LOCAL_BATCH_SIZE = 128;
|
|
18881
|
+
var HINDSIGHT_DEFAULT_LLM_STRICT_SCHEMA = "true";
|
|
18882
|
+
var HINDSIGHT_DEFAULT_LLM_MAX_RETRIES = 2;
|
|
18883
|
+
var HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_PARALLELISM = 2;
|
|
18884
|
+
var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
18885
|
+
[
|
|
18886
|
+
"HINDSIGHT_API_RECALL_MAX_CANDIDATES_PER_SOURCE",
|
|
18887
|
+
String(HINDSIGHT_DEFAULT_RECALL_MAX_CANDIDATES_PER_SOURCE)
|
|
18888
|
+
],
|
|
18889
|
+
[
|
|
18890
|
+
"HINDSIGHT_API_LINK_EXPANSION_PER_ENTITY_LIMIT",
|
|
18891
|
+
String(HINDSIGHT_DEFAULT_LINK_EXPANSION_PER_ENTITY_LIMIT)
|
|
18892
|
+
],
|
|
18893
|
+
[
|
|
18894
|
+
"HINDSIGHT_API_LINK_EXPANSION_TIMEOUT",
|
|
18895
|
+
String(HINDSIGHT_DEFAULT_LINK_EXPANSION_TIMEOUT_S)
|
|
18896
|
+
],
|
|
18897
|
+
["HINDSIGHT_API_LLM_REASONING_EFFORT", HINDSIGHT_DEFAULT_LLM_REASONING_EFFORT],
|
|
18898
|
+
[
|
|
18899
|
+
"HINDSIGHT_API_CONSOLIDATION_LLM_PARALLELISM",
|
|
18900
|
+
String(HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_PARALLELISM)
|
|
18901
|
+
]
|
|
18902
|
+
];
|
|
18903
|
+
var HINDSIGHT_PERF_DEFAULTS_GPU = [
|
|
18904
|
+
["HINDSIGHT_API_RERANKER_LOCAL_FP16", HINDSIGHT_DEFAULT_RERANKER_LOCAL_FP16],
|
|
18905
|
+
[
|
|
18906
|
+
"HINDSIGHT_API_RERANKER_LOCAL_BATCH_SIZE",
|
|
18907
|
+
String(HINDSIGHT_DEFAULT_RERANKER_LOCAL_BATCH_SIZE)
|
|
18908
|
+
]
|
|
18909
|
+
];
|
|
18910
|
+
var HINDSIGHT_PERF_DEFAULTS_LOCAL_LLM = [
|
|
18911
|
+
["HINDSIGHT_API_LLM_MAX_CONCURRENT", String(HINDSIGHT_DEFAULT_LLM_MAX_CONCURRENT)],
|
|
18912
|
+
[
|
|
18913
|
+
"HINDSIGHT_API_RETAIN_LLM_MAX_CONCURRENT",
|
|
18914
|
+
String(HINDSIGHT_DEFAULT_RETAIN_LLM_MAX_CONCURRENT)
|
|
18915
|
+
],
|
|
18916
|
+
[
|
|
18917
|
+
"HINDSIGHT_API_CONSOLIDATION_LLM_MAX_CONCURRENT",
|
|
18918
|
+
String(HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_MAX_CONCURRENT)
|
|
18919
|
+
],
|
|
18920
|
+
["HINDSIGHT_API_LLM_STRICT_SCHEMA", HINDSIGHT_DEFAULT_LLM_STRICT_SCHEMA],
|
|
18921
|
+
["HINDSIGHT_API_LLM_MAX_RETRIES", String(HINDSIGHT_DEFAULT_LLM_MAX_RETRIES)]
|
|
18922
|
+
];
|
|
18923
|
+
var HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS = new Set([
|
|
18924
|
+
"HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY"
|
|
18925
|
+
]);
|
|
18926
|
+
var HINDSIGHT_PERF_ENV_KEYS = new Set([
|
|
18927
|
+
...[
|
|
18928
|
+
...HINDSIGHT_PERF_DEFAULTS_UNGATED,
|
|
18929
|
+
...HINDSIGHT_PERF_DEFAULTS_GPU,
|
|
18930
|
+
...HINDSIGHT_PERF_DEFAULTS_LOCAL_LLM
|
|
18931
|
+
].map(([k]) => k),
|
|
18932
|
+
...HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS
|
|
18933
|
+
]);
|
|
18934
|
+
|
|
18935
|
+
// src/setup/hindsight-pg-defaults.ts
|
|
18936
|
+
var HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION = 8 * 1024;
|
|
18937
|
+
var HINDSIGHT_PG_APP_ANON_MIB = 2560;
|
|
18938
|
+
var HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB = 2048;
|
|
18939
|
+
var HINDSIGHT_PG_SHARED_BUFFERS_BUDGET_MIB = HINDSIGHT_PG_MEM_LIMIT_MIB_FOR_DERIVATION - HINDSIGHT_PG_APP_ANON_MIB - HINDSIGHT_PG_PAGE_CACHE_FLOOR_MIB;
|
|
18940
|
+
var HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB = 1536;
|
|
18941
|
+
var HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB = 4096;
|
|
18942
|
+
function pgMib(mib) {
|
|
18943
|
+
return `${mib}MB`;
|
|
18944
|
+
}
|
|
18945
|
+
var HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE_ENV = "SWITCHROOM_HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE";
|
|
18946
|
+
var HINDSIGHT_PG_SHARED_BUFFERS_ENV = "SWITCHROOM_HINDSIGHT_PG_SHARED_BUFFERS";
|
|
18947
|
+
var HINDSIGHT_PG_DEFAULTS = [
|
|
18948
|
+
[
|
|
18949
|
+
HINDSIGHT_PG_EFFECTIVE_CACHE_SIZE_ENV,
|
|
18950
|
+
pgMib(HINDSIGHT_PG_DEFAULT_EFFECTIVE_CACHE_SIZE_MIB)
|
|
18951
|
+
],
|
|
18952
|
+
[HINDSIGHT_PG_SHARED_BUFFERS_ENV, pgMib(HINDSIGHT_PG_DEFAULT_SHARED_BUFFERS_MIB)]
|
|
18953
|
+
];
|
|
18954
|
+
var HINDSIGHT_PG_ENV_KEYS = new Set(HINDSIGHT_PG_DEFAULTS.map(([k]) => k));
|
|
18955
|
+
|
|
18956
|
+
// src/setup/hindsight-context-budget.ts
|
|
18957
|
+
var HINDSIGHT_UPSTREAM_RETAIN_CHUNK_SIZE = 3000;
|
|
18958
|
+
var HINDSIGHT_RETAIN_MAX_COMPLETION_FLOOR = HINDSIGHT_UPSTREAM_RETAIN_CHUNK_SIZE + 72;
|
|
18959
|
+
|
|
18864
18960
|
// src/setup/hindsight.ts
|
|
18865
18961
|
var HINDSIGHT_DEFAULT_API_PORT = 18888;
|
|
18866
18962
|
var HINDSIGHT_DEFAULT_MCP_URL = `http://127.0.0.1:${HINDSIGHT_DEFAULT_API_PORT}/mcp/`;
|
|
@@ -19728,9 +19824,6 @@ var DOCKER_HOOKS_PATH = `${DOCKER_TELEGRAM_PLUGIN_PATH}/hooks`;
|
|
|
19728
19824
|
init_merge();
|
|
19729
19825
|
init_timezone();
|
|
19730
19826
|
|
|
19731
|
-
// src/setup/host-capabilities.ts
|
|
19732
|
-
init_paths();
|
|
19733
|
-
|
|
19734
19827
|
// src/vault/grants-db-path.ts
|
|
19735
19828
|
import * as os from "node:os";
|
|
19736
19829
|
import * as path from "node:path";
|
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.19.
|
|
4
|
+
"version": "0.19.24",
|
|
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/catch-all-forwarded-history.test.ts telegram-plugin/tests/history.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-query-pending-permission.test.ts telegram-plugin/tests/ipc-server-check-pre-approved.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/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/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/catch-all-forwarded-history.test.ts telegram-plugin/tests/history.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-query-pending-permission.test.ts telegram-plugin/tests/ipc-server-check-pre-approved.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/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/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/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/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-query-pending-permission.test.ts telegram-plugin/tests/ipc-server-check-pre-approved.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/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/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/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/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-query-pending-permission.test.ts telegram-plugin/tests/ipc-server-check-pre-approved.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/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/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-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-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-litellm-config-guard.mjs && node scripts/check-release-asset-names.mjs",
|
|
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-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-litellm-config-guard.mjs && node scripts/check-release-asset-names.mjs",
|
|
32
32
|
"lint:tsc": "tsc --noEmit",
|
|
33
33
|
"lint:plugin-references": "node scripts/check-plugin-references.mjs",
|
|
34
34
|
"lint:bot-api-wrapping": "bash scripts/check-bot-api-wrapping.sh",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"lint:bun-module-mock-scope": "node scripts/check-bun-module-mock-scope.mjs",
|
|
37
37
|
"lint:no-pii": "node scripts/check-no-pii-secrets.mjs",
|
|
38
38
|
"lint:auth-test-hermeticity": "node scripts/check-auth-test-hermeticity.mjs",
|
|
39
|
+
"lint:agent-state-dir-hermeticity": "node scripts/check-agent-state-dir-hermeticity.mjs",
|
|
39
40
|
"lint:web-subscription-honest": "node scripts/check-web-subscription-honest.mjs",
|
|
40
41
|
"lint:no-broadcast-delivery": "node scripts/check-no-broadcast-delivery.mjs",
|
|
41
42
|
"lint:gateway-line-ratchet": "node scripts/check-gateway-line-ratchet.mjs",
|
|
@@ -458,6 +458,107 @@ x-litellm-tags: agent:$SWITCHROOM_AGENT_NAME,profile:${SWITCHROOM_AGENT_PROFILE:
|
|
|
458
458
|
fi
|
|
459
459
|
{{/if}}
|
|
460
460
|
|
|
461
|
+
{{#if hindsightEnabled}}
|
|
462
|
+
# 5) hindsight backlog drain — the memory queue's only real consumer.
|
|
463
|
+
#
|
|
464
|
+
# WHY THIS EXISTS. `pending-retains` is written whenever a retain
|
|
465
|
+
# fails, but before this the ONLY automatic thing that drained it was
|
|
466
|
+
# the SessionStart hook (`session_start.py`), which runs once per
|
|
467
|
+
# session boot under a hard ~9s latency budget against work measured
|
|
468
|
+
# at 85-280s per entry. So an agent that simply stays up never drained
|
|
469
|
+
# at all: on this fleet 8 of 11 agents had not drained a single entry
|
|
470
|
+
# and the queue reached 1,060 files. A memory sitting in that queue is
|
|
471
|
+
# a memory the agent cannot recall — the job this feature exists for.
|
|
472
|
+
#
|
|
473
|
+
# A sidecar, not a cron entry: cron fires cost a model turn and depend
|
|
474
|
+
# on the agent remembering to keep the entry. This is a deterministic
|
|
475
|
+
# mechanism — it runs because the container is up, needs no LLM turn of
|
|
476
|
+
# its own, and cannot be prompted away.
|
|
477
|
+
#
|
|
478
|
+
# SERIALISED. `flock -n` on a per-agent lockfile makes overlapping runs
|
|
479
|
+
# impossible: a run that overshoots the interval causes the next tick to
|
|
480
|
+
# SKIP, never to stack. The lock path is deliberately the one the
|
|
481
|
+
# out-of-band recovery tooling also takes, so a manual sweep and this
|
|
482
|
+
# loop mutually exclude instead of double-processing an entry.
|
|
483
|
+
#
|
|
484
|
+
# LANE-RESPECTING. Retain extraction is served by a small fixed pool of
|
|
485
|
+
# LLM lanes (4 on this fleet, 2 boxes x 2 slots) SHARED with live
|
|
486
|
+
# retains, reflect and consolidation, already near saturation. So:
|
|
487
|
+
# `HINDSIGHT_DRAIN_CONCURRENCY` is left at its default of 1 (one
|
|
488
|
+
# in-flight POST per agent — do not raise it here), `drain_pending`'s
|
|
489
|
+
# own inter-retain sleep and p95 backoff still apply, and the first
|
|
490
|
+
# tick is delayed by a per-agent offset derived from the agent NAME so
|
|
491
|
+
# the fleet does not all wake together. The offset is a `cksum` of the
|
|
492
|
+
# name modulo the interval: deterministic (same agent, same offset,
|
|
493
|
+
# every boot) and evenly spread, with no shared coordinator.
|
|
494
|
+
# HONEST LIMIT: N agents x 1 lane still exceeds 4 lanes when every
|
|
495
|
+
# agent has a backlog. The offset spreads the START times; it does not
|
|
496
|
+
# cap fleet-wide demand. Sustained oversubscription is absorbed by the
|
|
497
|
+
# p95 backoff, and the real fix is more lanes.
|
|
498
|
+
#
|
|
499
|
+
# WHY NO `HINDSIGHT_DRAIN_BACKLOG_TIMEOUT` HERE, given the measurement.
|
|
500
|
+
# A host-side stopgap measured, on the SHIPPED defaults:
|
|
501
|
+
# timeout=310 conc=1, busy lane -> drained 0 of 2
|
|
502
|
+
# timeout=310 conc=3, FREE lane -> drained 0 of 3, stalled
|
|
503
|
+
# timeout=900 conc=1, free lane -> drained 5 of 5
|
|
504
|
+
# It failed on an IDLE lane, so scheduling and contention were never the
|
|
505
|
+
# whole story. The reading that matters is the third row's concurrency,
|
|
506
|
+
# not its timeout: raising concurrency made it WORSE, which is why 1 is
|
|
507
|
+
# the value above and is not a knob this sidecar exposes.
|
|
508
|
+
# The timeout is deliberately left DERIVED rather than pinned at 900.
|
|
509
|
+
# `_backlog_timeout()` defaults to `retain_client_deadline()` and the
|
|
510
|
+
# content bound is sized against that same number — they must stay one
|
|
511
|
+
# number, and hard-coding 900 here would silently unpick that. What
|
|
512
|
+
# those runs actually measured was the bound consuming ~100% of the
|
|
513
|
+
# deadline, so a maximally-sized part could never finish; that is fixed
|
|
514
|
+
# at its root in #3693 (the bound is now a FRACTION of the deadline),
|
|
515
|
+
# which brings a max part to 202s inside a 310s deadline. Entries
|
|
516
|
+
# already queued ABOVE the current bound are recovered by re-splitting
|
|
517
|
+
# them, not by waiting longer. An operator who still wants a longer
|
|
518
|
+
# deadline moves HINDSIGHT_RETAIN_CLIENT_DEADLINE_S, which moves both.
|
|
519
|
+
#
|
|
520
|
+
# Failure is never terminal: the drain exits non-zero only when it
|
|
521
|
+
# promoted entries to `.dead`, and the loop below ignores the status
|
|
522
|
+
# and waits for the next tick. `--backlog` reads api_url/token/bank
|
|
523
|
+
# from each queue ENTRY, so this sidecar needs no HINDSIGHT_* env
|
|
524
|
+
# (those are exported later, in the inner pass) — only $HOME, to find
|
|
525
|
+
# the queue.
|
|
526
|
+
#
|
|
527
|
+
# Kill switch: SWITCHROOM_HINDSIGHT_DRAIN=0 at the container level.
|
|
528
|
+
# Interval: SWITCHROOM_HINDSIGHT_DRAIN_INTERVAL_S (default 900s).
|
|
529
|
+
_hs_drain_script="{{agentDir}}/.claude/plugins/hindsight-memory/scripts/drain_pending.py"
|
|
530
|
+
if [ "$SWITCHROOM_HINDSIGHT_DRAIN" != "0" ] \
|
|
531
|
+
&& [ -f "$_hs_drain_script" ] \
|
|
532
|
+
&& command -v python3 >/dev/null 2>&1 \
|
|
533
|
+
&& command -v flock >/dev/null 2>&1; then
|
|
534
|
+
_switchroom_hindsight_drain_loop() {
|
|
535
|
+
local _script="$1"
|
|
536
|
+
local _interval="${SWITCHROOM_HINDSIGHT_DRAIN_INTERVAL_S:-900}"
|
|
537
|
+
# Reject a non-numeric or too-eager interval rather than busy-looping
|
|
538
|
+
# against the LLM lane. 60s is the floor.
|
|
539
|
+
case "$_interval" in ''|*[!0-9]*) _interval=900 ;; esac
|
|
540
|
+
[ "$_interval" -lt 60 ] && _interval=60
|
|
541
|
+
local _lock="$HOME/.hindsight/drain.lock"
|
|
542
|
+
mkdir -p "$HOME/.hindsight" 2>/dev/null || true
|
|
543
|
+
# Deterministic per-agent phase offset (see the note above).
|
|
544
|
+
local _offset=0
|
|
545
|
+
if command -v cksum >/dev/null 2>&1; then
|
|
546
|
+
_offset=$(( $(printf '%s' "{{name}}" | cksum | cut -d' ' -f1) % _interval ))
|
|
547
|
+
fi
|
|
548
|
+
echo "[hindsight-drain] starting: interval=${_interval}s offset=${_offset}s lock=${_lock}"
|
|
549
|
+
sleep "$_offset"
|
|
550
|
+
while true; do
|
|
551
|
+
# -n: if a drain (ours or an operator sweep) already holds the
|
|
552
|
+
# lock, skip this tick entirely instead of queueing behind it.
|
|
553
|
+
flock -n "$_lock" python3 "$_script" --backlog || true
|
|
554
|
+
sleep "$_interval"
|
|
555
|
+
done
|
|
556
|
+
}
|
|
557
|
+
_switchroom_supervise hindsight-drain /var/log/switchroom/hindsight-drain.log \
|
|
558
|
+
_switchroom_hindsight_drain_loop "$_hs_drain_script" &
|
|
559
|
+
fi
|
|
560
|
+
{{/if}}
|
|
561
|
+
|
|
461
562
|
export SWITCHROOM_DOCKER_TMUX_INNER=1
|
|
462
563
|
exec tmux -L "switchroom-{{name}}" \
|
|
463
564
|
new-session -A -s "{{name}}" -x 400 -y 50 \
|