switchroom 0.19.41 → 0.19.42

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.
Files changed (29) hide show
  1. package/dist/agent-scheduler/index.js +22 -2
  2. package/dist/auth-broker/index.js +22 -2
  3. package/dist/cli/notion-write-pretool.mjs +22 -2
  4. package/dist/cli/switchroom.js +772 -234
  5. package/dist/host-control/main.js +23 -3
  6. package/dist/vault/approvals/kernel-server.js +22 -2
  7. package/dist/vault/broker/server.js +22 -2
  8. package/package.json +1 -1
  9. package/telegram-plugin/dist/gateway/gateway.js +97 -83
  10. package/telegram-plugin/gateway/approval-callback-consume-record.test.ts +132 -0
  11. package/telegram-plugin/gateway/gateway.ts +7 -7
  12. package/telegram-plugin/gateway/liveness-wiring.ts +12 -0
  13. package/telegram-plugin/gateway/model-command.ts +21 -109
  14. package/telegram-plugin/gateway/stream-render.ts +57 -0
  15. package/telegram-plugin/tests/framework-fallback-drains-parked.test.ts +134 -0
  16. package/telegram-plugin/tests/helpers/liveness-wiring-fixture.ts +3 -0
  17. package/vendor/hindsight-memory/CHANGELOG.md +28 -0
  18. package/vendor/hindsight-memory/docs/measurements/subagent-volume-gate-3994.md +84 -0
  19. package/vendor/hindsight-memory/scripts/backfill_transcripts.py +254 -40
  20. package/vendor/hindsight-memory/scripts/lib/content.py +11 -2
  21. package/vendor/hindsight-memory/scripts/recall.py +18 -3
  22. package/vendor/hindsight-memory/scripts/subagent_retain.py +59 -38
  23. package/vendor/hindsight-memory/scripts/tests/data/replay_volume_gate_3994.py +295 -0
  24. package/vendor/hindsight-memory/scripts/tests/test_backfill_from_logs.py +109 -0
  25. package/vendor/hindsight-memory/scripts/tests/test_overlap_tokens.py +135 -0
  26. package/vendor/hindsight-memory/scripts/tests/test_recall_no_lexical_gate.py +20 -23
  27. package/vendor/hindsight-memory/scripts/tests/test_recall_query_shaping.py +48 -0
  28. package/vendor/hindsight-memory/scripts/tests/test_subagent_retain.py +94 -1
  29. package/vendor/hindsight-memory/scripts/tests/test_subagent_retain_learnings.py +98 -42
@@ -11116,6 +11116,7 @@ var init_schema = __esm(() => {
11116
11116
  auto_recall: exports_external.boolean().default(true).describe("Auto-search memories before each response"),
11117
11117
  file: exports_external.boolean().default(true).describe("Maintain a curated workspace MEMORY.md file (seeded once, " + "auto-loaded every turn). Set false for hindsight-only memory: " + "the file is not seeded or re-created, so once migrated into " + "Hindsight and deleted it stays gone. Recall + directives carry " + "the memory instead. Cascade: override (per-agent wins over default)."),
11118
11118
  isolation: exports_external.enum(["default", "strict"]).default("default").describe("strict = never shared cross-agent, default = eligible for reflect"),
11119
+ profile: exports_external.string().optional().describe("Memory profile bank this agent's curated memory defaults key off — " + "the built-in disposition + observations_mission in PROFILE_MEMORY_DEFAULTS. " + "Decouples the memory profile from `extends` (the filesystem persona " + "profile), so an agent on `extends: default` can opt into the `coding` " + "memory bundle via `memory.profile: coding` without inheriting the coding " + "persona. Resolution: memory.profile → extends → DEFAULT_PROFILE (see " + "resolveMemoryProfile). Unset ⇒ byte-identical to keying off `extends`."),
11119
11120
  bank_mission: exports_external.string().optional().describe("Bank-level mission statement used during recall to contextualize " + "results. NOTE: this is an alias for the Hindsight engine's " + "`reflect_mission` field (verified live: switchroom's bank_mission " + "lands in `config.reflect_mission`). Prefer `reflect_mission` going " + "forward; `bank_mission` is retained for back-compat. If both are " + "set, `reflect_mission` wins. Cascade: override."),
11120
11121
  reflect_mission: exports_external.string().optional().describe("Mission/context steering Hindsight Reflect operations (the bank's " + "'who am I / what matters' framing applied during recall). The " + "engine-accurate name for what `bank_mission` sets. Cascade: override."),
11121
11122
  retain_mission: exports_external.string().optional().describe("Instructions for the fact extraction LLM during retain. Cascade: override."),
@@ -11409,6 +11410,8 @@ var init_schema = __esm(() => {
11409
11410
  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."),
11410
11411
  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."),
11411
11412
  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."),
11413
+ base_url: exports_external.string().min(1).optional().describe("GLOBAL LLM base URL (upstream `HINDSIGHT_API_LLM_BASE_URL`). The " + "default endpoint every op inherits absent a per-op " + "`hindsight.llm.<op>.base_url`. Optional passthrough; unset → the " + "engine's provider default. When this points at host loopback the " + "hindsight container is forced onto host networking, same as a " + "per-op base URL, so the endpoint stays reachable (#3687)."),
11414
+ api_key: exports_external.string().min(1).optional().describe("GLOBAL LLM API key (upstream `HINDSIGHT_API_LLM_API_KEY`). Literal " + "or `vault:` reference. The default credential every op inherits " + "absent a per-op `hindsight.llm.<op>.api_key`; the engine reads it as " + "a plain env fallback. Optional passthrough (#3687)."),
11412
11415
  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."),
11413
11416
  reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent → uses global."),
11414
11417
  consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent → global.")
@@ -11545,6 +11548,7 @@ var init_schema = __esm(() => {
11545
11548
  auto_recall: exports_external.boolean().optional(),
11546
11549
  file: exports_external.boolean().optional(),
11547
11550
  isolation: exports_external.enum(["default", "strict"]).optional(),
11551
+ profile: exports_external.string().optional(),
11548
11552
  directive_capture_nudge: exports_external.boolean().optional(),
11549
11553
  observation_scopes: ObservationScopesSchema,
11550
11554
  observation_scope_strategy: ObservationScopeStrategySchema,
@@ -11586,7 +11590,23 @@ var init_schema = __esm(() => {
11586
11590
  max_query_chars: exports_external.number().int().min(1).optional(),
11587
11591
  parallel: exports_external.boolean().optional(),
11588
11592
  additional_banks: exports_external.array(exports_external.string()).optional(),
11589
- sender_banks: exports_external.record(exports_external.string(), exports_external.string()).optional()
11593
+ sender_banks: exports_external.record(exports_external.string(), exports_external.string()).optional(),
11594
+ types: exports_external.array(exports_external.string()).optional(),
11595
+ skip_trivial: exports_external.boolean().optional(),
11596
+ topic_filter_mode: exports_external.enum(["soft-preamble", "hard-filter"]).optional()
11597
+ }).optional(),
11598
+ retain: exports_external.object({
11599
+ every_n_turns: exports_external.number().int().min(1).optional(),
11600
+ overlap_turns: exports_external.number().int().min(0).optional()
11601
+ }).optional(),
11602
+ bank_mission: exports_external.string().optional(),
11603
+ reflect_mission: exports_external.string().optional(),
11604
+ retain_mission: exports_external.string().optional(),
11605
+ observations_mission: exports_external.string().optional(),
11606
+ disposition: exports_external.object({
11607
+ skepticism: exports_external.number().int().min(1).max(5).optional(),
11608
+ literalism: exports_external.number().int().min(1).max(5).optional(),
11609
+ empathy: exports_external.number().int().min(1).max(5).optional()
11590
11610
  }).optional()
11591
11611
  }).optional(),
11592
11612
  schedule: exports_external.array(ScheduleEntrySchema).optional(),
@@ -18753,11 +18773,11 @@ var init_protocol = __esm(() => {
18753
18773
  OkRevokeGrantResponseSchema,
18754
18774
  OkApprovalRequestResponseSchema,
18755
18775
  OkApprovalLookupResponseSchema,
18776
+ OkApprovalConsumeRecordResponseSchema,
18756
18777
  OkApprovalConsumeResponseSchema,
18757
18778
  OkApprovalRevokeResponseSchema,
18758
18779
  OkApprovalListResponseSchema,
18759
18780
  OkApprovalRecordResponseSchema,
18760
- OkApprovalConsumeRecordResponseSchema,
18761
18781
  ErrorResponseSchema
18762
18782
  ]);
18763
18783
  });
@@ -21322,7 +21342,7 @@ function allocateAgentUid(name) {
21322
21342
  }
21323
21343
 
21324
21344
  // src/build-info.ts
21325
- var VERSION = "0.19.41";
21345
+ var VERSION = "0.19.42";
21326
21346
 
21327
21347
  // src/setup/hindsight-recall-tunables.ts
21328
21348
  var RECALL_DEADLINE_HEADROOM_SECONDS = 2;
@@ -4407,11 +4407,11 @@ var init_protocol = __esm(() => {
4407
4407
  OkRevokeGrantResponseSchema,
4408
4408
  OkApprovalRequestResponseSchema,
4409
4409
  OkApprovalLookupResponseSchema,
4410
+ OkApprovalConsumeRecordResponseSchema,
4410
4411
  OkApprovalConsumeResponseSchema,
4411
4412
  OkApprovalRevokeResponseSchema,
4412
4413
  OkApprovalListResponseSchema,
4413
4414
  OkApprovalRecordResponseSchema,
4414
- OkApprovalConsumeRecordResponseSchema,
4415
4415
  ErrorResponseSchema
4416
4416
  ]);
4417
4417
  });
@@ -4556,6 +4556,7 @@ var init_schema = __esm(() => {
4556
4556
  auto_recall: exports_external.boolean().default(true).describe("Auto-search memories before each response"),
4557
4557
  file: exports_external.boolean().default(true).describe("Maintain a curated workspace MEMORY.md file (seeded once, " + "auto-loaded every turn). Set false for hindsight-only memory: " + "the file is not seeded or re-created, so once migrated into " + "Hindsight and deleted it stays gone. Recall + directives carry " + "the memory instead. Cascade: override (per-agent wins over default)."),
4558
4558
  isolation: exports_external.enum(["default", "strict"]).default("default").describe("strict = never shared cross-agent, default = eligible for reflect"),
4559
+ profile: exports_external.string().optional().describe("Memory profile bank this agent's curated memory defaults key off — " + "the built-in disposition + observations_mission in PROFILE_MEMORY_DEFAULTS. " + "Decouples the memory profile from `extends` (the filesystem persona " + "profile), so an agent on `extends: default` can opt into the `coding` " + "memory bundle via `memory.profile: coding` without inheriting the coding " + "persona. Resolution: memory.profile → extends → DEFAULT_PROFILE (see " + "resolveMemoryProfile). Unset ⇒ byte-identical to keying off `extends`."),
4559
4560
  bank_mission: exports_external.string().optional().describe("Bank-level mission statement used during recall to contextualize " + "results. NOTE: this is an alias for the Hindsight engine's " + "`reflect_mission` field (verified live: switchroom's bank_mission " + "lands in `config.reflect_mission`). Prefer `reflect_mission` going " + "forward; `bank_mission` is retained for back-compat. If both are " + "set, `reflect_mission` wins. Cascade: override."),
4560
4561
  reflect_mission: exports_external.string().optional().describe("Mission/context steering Hindsight Reflect operations (the bank's " + "'who am I / what matters' framing applied during recall). The " + "engine-accurate name for what `bank_mission` sets. Cascade: override."),
4561
4562
  retain_mission: exports_external.string().optional().describe("Instructions for the fact extraction LLM during retain. Cascade: override."),
@@ -4849,6 +4850,8 @@ var init_schema = __esm(() => {
4849
4850
  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."),
4850
4851
  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."),
4851
4852
  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."),
4853
+ base_url: exports_external.string().min(1).optional().describe("GLOBAL LLM base URL (upstream `HINDSIGHT_API_LLM_BASE_URL`). The " + "default endpoint every op inherits absent a per-op " + "`hindsight.llm.<op>.base_url`. Optional passthrough; unset → the " + "engine's provider default. When this points at host loopback the " + "hindsight container is forced onto host networking, same as a " + "per-op base URL, so the endpoint stays reachable (#3687)."),
4854
+ api_key: exports_external.string().min(1).optional().describe("GLOBAL LLM API key (upstream `HINDSIGHT_API_LLM_API_KEY`). Literal " + "or `vault:` reference. The default credential every op inherits " + "absent a per-op `hindsight.llm.<op>.api_key`; the engine reads it as " + "a plain env fallback. Optional passthrough (#3687)."),
4852
4855
  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."),
4853
4856
  reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent → uses global."),
4854
4857
  consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent → global.")
@@ -4985,6 +4988,7 @@ var init_schema = __esm(() => {
4985
4988
  auto_recall: exports_external.boolean().optional(),
4986
4989
  file: exports_external.boolean().optional(),
4987
4990
  isolation: exports_external.enum(["default", "strict"]).optional(),
4991
+ profile: exports_external.string().optional(),
4988
4992
  directive_capture_nudge: exports_external.boolean().optional(),
4989
4993
  observation_scopes: ObservationScopesSchema,
4990
4994
  observation_scope_strategy: ObservationScopeStrategySchema,
@@ -5026,7 +5030,23 @@ var init_schema = __esm(() => {
5026
5030
  max_query_chars: exports_external.number().int().min(1).optional(),
5027
5031
  parallel: exports_external.boolean().optional(),
5028
5032
  additional_banks: exports_external.array(exports_external.string()).optional(),
5029
- sender_banks: exports_external.record(exports_external.string(), exports_external.string()).optional()
5033
+ sender_banks: exports_external.record(exports_external.string(), exports_external.string()).optional(),
5034
+ types: exports_external.array(exports_external.string()).optional(),
5035
+ skip_trivial: exports_external.boolean().optional(),
5036
+ topic_filter_mode: exports_external.enum(["soft-preamble", "hard-filter"]).optional()
5037
+ }).optional(),
5038
+ retain: exports_external.object({
5039
+ every_n_turns: exports_external.number().int().min(1).optional(),
5040
+ overlap_turns: exports_external.number().int().min(0).optional()
5041
+ }).optional(),
5042
+ bank_mission: exports_external.string().optional(),
5043
+ reflect_mission: exports_external.string().optional(),
5044
+ retain_mission: exports_external.string().optional(),
5045
+ observations_mission: exports_external.string().optional(),
5046
+ disposition: exports_external.object({
5047
+ skepticism: exports_external.number().int().min(1).max(5).optional(),
5048
+ literalism: exports_external.number().int().min(1).max(5).optional(),
5049
+ empathy: exports_external.number().int().min(1).max(5).optional()
5030
5050
  }).optional()
5031
5051
  }).optional(),
5032
5052
  schedule: exports_external.array(ScheduleEntrySchema).optional(),
@@ -4152,6 +4152,7 @@ var init_schema = __esm(() => {
4152
4152
  auto_recall: exports_external.boolean().default(true).describe("Auto-search memories before each response"),
4153
4153
  file: exports_external.boolean().default(true).describe("Maintain a curated workspace MEMORY.md file (seeded once, " + "auto-loaded every turn). Set false for hindsight-only memory: " + "the file is not seeded or re-created, so once migrated into " + "Hindsight and deleted it stays gone. Recall + directives carry " + "the memory instead. Cascade: override (per-agent wins over default)."),
4154
4154
  isolation: exports_external.enum(["default", "strict"]).default("default").describe("strict = never shared cross-agent, default = eligible for reflect"),
4155
+ profile: exports_external.string().optional().describe("Memory profile bank this agent's curated memory defaults key off — " + "the built-in disposition + observations_mission in PROFILE_MEMORY_DEFAULTS. " + "Decouples the memory profile from `extends` (the filesystem persona " + "profile), so an agent on `extends: default` can opt into the `coding` " + "memory bundle via `memory.profile: coding` without inheriting the coding " + "persona. Resolution: memory.profile → extends → DEFAULT_PROFILE (see " + "resolveMemoryProfile). Unset ⇒ byte-identical to keying off `extends`."),
4155
4156
  bank_mission: exports_external.string().optional().describe("Bank-level mission statement used during recall to contextualize " + "results. NOTE: this is an alias for the Hindsight engine's " + "`reflect_mission` field (verified live: switchroom's bank_mission " + "lands in `config.reflect_mission`). Prefer `reflect_mission` going " + "forward; `bank_mission` is retained for back-compat. If both are " + "set, `reflect_mission` wins. Cascade: override."),
4156
4157
  reflect_mission: exports_external.string().optional().describe("Mission/context steering Hindsight Reflect operations (the bank's " + "'who am I / what matters' framing applied during recall). The " + "engine-accurate name for what `bank_mission` sets. Cascade: override."),
4157
4158
  retain_mission: exports_external.string().optional().describe("Instructions for the fact extraction LLM during retain. Cascade: override."),
@@ -4445,6 +4446,8 @@ var init_schema = __esm(() => {
4445
4446
  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."),
4446
4447
  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."),
4447
4448
  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."),
4449
+ base_url: exports_external.string().min(1).optional().describe("GLOBAL LLM base URL (upstream `HINDSIGHT_API_LLM_BASE_URL`). The " + "default endpoint every op inherits absent a per-op " + "`hindsight.llm.<op>.base_url`. Optional passthrough; unset → the " + "engine's provider default. When this points at host loopback the " + "hindsight container is forced onto host networking, same as a " + "per-op base URL, so the endpoint stays reachable (#3687)."),
4450
+ api_key: exports_external.string().min(1).optional().describe("GLOBAL LLM API key (upstream `HINDSIGHT_API_LLM_API_KEY`). Literal " + "or `vault:` reference. The default credential every op inherits " + "absent a per-op `hindsight.llm.<op>.api_key`; the engine reads it as " + "a plain env fallback. Optional passthrough (#3687)."),
4448
4451
  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."),
4449
4452
  reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent → uses global."),
4450
4453
  consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent → global.")
@@ -4581,6 +4584,7 @@ var init_schema = __esm(() => {
4581
4584
  auto_recall: exports_external.boolean().optional(),
4582
4585
  file: exports_external.boolean().optional(),
4583
4586
  isolation: exports_external.enum(["default", "strict"]).optional(),
4587
+ profile: exports_external.string().optional(),
4584
4588
  directive_capture_nudge: exports_external.boolean().optional(),
4585
4589
  observation_scopes: ObservationScopesSchema,
4586
4590
  observation_scope_strategy: ObservationScopeStrategySchema,
@@ -4622,7 +4626,23 @@ var init_schema = __esm(() => {
4622
4626
  max_query_chars: exports_external.number().int().min(1).optional(),
4623
4627
  parallel: exports_external.boolean().optional(),
4624
4628
  additional_banks: exports_external.array(exports_external.string()).optional(),
4625
- sender_banks: exports_external.record(exports_external.string(), exports_external.string()).optional()
4629
+ sender_banks: exports_external.record(exports_external.string(), exports_external.string()).optional(),
4630
+ types: exports_external.array(exports_external.string()).optional(),
4631
+ skip_trivial: exports_external.boolean().optional(),
4632
+ topic_filter_mode: exports_external.enum(["soft-preamble", "hard-filter"]).optional()
4633
+ }).optional(),
4634
+ retain: exports_external.object({
4635
+ every_n_turns: exports_external.number().int().min(1).optional(),
4636
+ overlap_turns: exports_external.number().int().min(0).optional()
4637
+ }).optional(),
4638
+ bank_mission: exports_external.string().optional(),
4639
+ reflect_mission: exports_external.string().optional(),
4640
+ retain_mission: exports_external.string().optional(),
4641
+ observations_mission: exports_external.string().optional(),
4642
+ disposition: exports_external.object({
4643
+ skepticism: exports_external.number().int().min(1).max(5).optional(),
4644
+ literalism: exports_external.number().int().min(1).max(5).optional(),
4645
+ empathy: exports_external.number().int().min(1).max(5).optional()
4626
4646
  }).optional()
4627
4647
  }).optional(),
4628
4648
  schedule: exports_external.array(ScheduleEntrySchema).optional(),
@@ -19406,11 +19426,11 @@ var init_protocol = __esm(() => {
19406
19426
  OkRevokeGrantResponseSchema,
19407
19427
  OkApprovalRequestResponseSchema,
19408
19428
  OkApprovalLookupResponseSchema,
19429
+ OkApprovalConsumeRecordResponseSchema,
19409
19430
  OkApprovalConsumeResponseSchema,
19410
19431
  OkApprovalRevokeResponseSchema,
19411
19432
  OkApprovalListResponseSchema,
19412
19433
  OkApprovalRecordResponseSchema,
19413
- OkApprovalConsumeRecordResponseSchema,
19414
19434
  ErrorResponseSchema
19415
19435
  ]);
19416
19436
  });
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.41",
4
+ "version": "0.19.42",
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": {
@@ -14354,11 +14354,11 @@ var init_protocol2 = __esm(() => {
14354
14354
  OkRevokeGrantResponseSchema,
14355
14355
  OkApprovalRequestResponseSchema,
14356
14356
  OkApprovalLookupResponseSchema,
14357
+ OkApprovalConsumeRecordResponseSchema,
14357
14358
  OkApprovalConsumeResponseSchema,
14358
14359
  OkApprovalRevokeResponseSchema,
14359
14360
  OkApprovalListResponseSchema,
14360
14361
  OkApprovalRecordResponseSchema,
14361
- OkApprovalConsumeRecordResponseSchema,
14362
14362
  ErrorResponseSchema2
14363
14363
  ]);
14364
14364
  });
@@ -21865,6 +21865,7 @@ var init_schema = __esm(() => {
21865
21865
  auto_recall: exports_external.boolean().default(true).describe("Auto-search memories before each response"),
21866
21866
  file: exports_external.boolean().default(true).describe("Maintain a curated workspace MEMORY.md file (seeded once, " + "auto-loaded every turn). Set false for hindsight-only memory: " + "the file is not seeded or re-created, so once migrated into " + "Hindsight and deleted it stays gone. Recall + directives carry " + "the memory instead. Cascade: override (per-agent wins over default)."),
21867
21867
  isolation: exports_external.enum(["default", "strict"]).default("default").describe("strict = never shared cross-agent, default = eligible for reflect"),
21868
+ profile: exports_external.string().optional().describe("Memory profile bank this agent's curated memory defaults key off \u2014 " + "the built-in disposition + observations_mission in PROFILE_MEMORY_DEFAULTS. " + "Decouples the memory profile from `extends` (the filesystem persona " + "profile), so an agent on `extends: default` can opt into the `coding` " + "memory bundle via `memory.profile: coding` without inheriting the coding " + "persona. Resolution: memory.profile \u2192 extends \u2192 DEFAULT_PROFILE (see " + "resolveMemoryProfile). Unset \u21d2 byte-identical to keying off `extends`."),
21868
21869
  bank_mission: exports_external.string().optional().describe("Bank-level mission statement used during recall to contextualize " + "results. NOTE: this is an alias for the Hindsight engine's " + "`reflect_mission` field (verified live: switchroom's bank_mission " + "lands in `config.reflect_mission`). Prefer `reflect_mission` going " + "forward; `bank_mission` is retained for back-compat. If both are " + "set, `reflect_mission` wins. Cascade: override."),
21869
21870
  reflect_mission: exports_external.string().optional().describe("Mission/context steering Hindsight Reflect operations (the bank's " + "'who am I / what matters' framing applied during recall). The " + "engine-accurate name for what `bank_mission` sets. Cascade: override."),
21870
21871
  retain_mission: exports_external.string().optional().describe("Instructions for the fact extraction LLM during retain. Cascade: override."),
@@ -22158,6 +22159,8 @@ var init_schema = __esm(() => {
22158
22159
  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."),
22159
22160
  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."),
22160
22161
  context_window: exports_external.number().int().positive().optional().describe("GLOBAL context window (tokens) of the backend serving hindsight's " + "LLM ops \u2014 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 \u2192 a per-provider default: 200000 for `claude-code`, a " + "conservative 32768 for everything else. Overflowing a local " + "backend's window does NOT error \u2014 llama.cpp context-shift silently " + "drops the system prompt and the model answers conversationally " + "with HTTP 200 \u2014 so this value is what makes the failure " + "detectable at setup time instead of never."),
22162
+ base_url: exports_external.string().min(1).optional().describe("GLOBAL LLM base URL (upstream `HINDSIGHT_API_LLM_BASE_URL`). The " + "default endpoint every op inherits absent a per-op " + "`hindsight.llm.<op>.base_url`. Optional passthrough; unset \u2192 the " + "engine's provider default. When this points at host loopback the " + "hindsight container is forced onto host networking, same as a " + "per-op base URL, so the endpoint stays reachable (#3687)."),
22163
+ api_key: exports_external.string().min(1).optional().describe("GLOBAL LLM API key (upstream `HINDSIGHT_API_LLM_API_KEY`). Literal " + "or `vault:` reference. The default credential every op inherits " + "absent a per-op `hindsight.llm.<op>.api_key`; the engine reads it as " + "a plain env fallback. Optional passthrough (#3687)."),
22161
22164
  retain: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `retain` LLM op (memory ingestion). Emits " + "`HINDSIGHT_API_RETAIN_LLM_*`. Absent \u2192 uses the global model/provider."),
22162
22165
  reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent \u2192 uses global."),
22163
22166
  consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent \u2192 global.")
@@ -22294,6 +22297,7 @@ var init_schema = __esm(() => {
22294
22297
  auto_recall: exports_external.boolean().optional(),
22295
22298
  file: exports_external.boolean().optional(),
22296
22299
  isolation: exports_external.enum(["default", "strict"]).optional(),
22300
+ profile: exports_external.string().optional(),
22297
22301
  directive_capture_nudge: exports_external.boolean().optional(),
22298
22302
  observation_scopes: ObservationScopesSchema,
22299
22303
  observation_scope_strategy: ObservationScopeStrategySchema,
@@ -22335,7 +22339,23 @@ var init_schema = __esm(() => {
22335
22339
  max_query_chars: exports_external.number().int().min(1).optional(),
22336
22340
  parallel: exports_external.boolean().optional(),
22337
22341
  additional_banks: exports_external.array(exports_external.string()).optional(),
22338
- sender_banks: exports_external.record(exports_external.string(), exports_external.string()).optional()
22342
+ sender_banks: exports_external.record(exports_external.string(), exports_external.string()).optional(),
22343
+ types: exports_external.array(exports_external.string()).optional(),
22344
+ skip_trivial: exports_external.boolean().optional(),
22345
+ topic_filter_mode: exports_external.enum(["soft-preamble", "hard-filter"]).optional()
22346
+ }).optional(),
22347
+ retain: exports_external.object({
22348
+ every_n_turns: exports_external.number().int().min(1).optional(),
22349
+ overlap_turns: exports_external.number().int().min(0).optional()
22350
+ }).optional(),
22351
+ bank_mission: exports_external.string().optional(),
22352
+ reflect_mission: exports_external.string().optional(),
22353
+ retain_mission: exports_external.string().optional(),
22354
+ observations_mission: exports_external.string().optional(),
22355
+ disposition: exports_external.object({
22356
+ skepticism: exports_external.number().int().min(1).max(5).optional(),
22357
+ literalism: exports_external.number().int().min(1).max(5).optional(),
22358
+ empathy: exports_external.number().int().min(1).max(5).optional()
22339
22359
  }).optional()
22340
22360
  }).optional(),
22341
22361
  schedule: exports_external.array(ScheduleEntrySchema).optional(),
@@ -45562,12 +45582,42 @@ function assessThinkingEffortRisk(model, effort) {
45562
45582
  };
45563
45583
  }
45564
45584
 
45565
- // gateway/model-command.ts
45566
- var MODEL_ALIASES = ["opus", "sonnet", "haiku", "fable", "default"];
45585
+ // ../src/agents/model-aliases.ts
45567
45586
  var CLAUDE_MODEL_ALIASES = {
45568
45587
  opus48: "claude-opus-4-8",
45569
45588
  "opus-4-8": "claude-opus-4-8"
45570
45589
  };
45590
+ var SR_MODEL_ALIASES = {
45591
+ flash: "sr-gemini-2.5-flash",
45592
+ gemini: "sr-gemini-2.5-pro",
45593
+ deepseek: "sr-deepseek-v3",
45594
+ r1: "sr-deepseek-r1",
45595
+ glm: "sr-glm-5",
45596
+ codex: "sr-codex-5.5",
45597
+ grok: "sr-grok-4.5",
45598
+ kimi: "sr-kimi-k3",
45599
+ gpt: "sr-gpt-5.6-sol",
45600
+ sol: "sr-gpt-5.6-sol",
45601
+ terra: "sr-gpt-5.6-terra",
45602
+ luna: "sr-gpt-5.6-luna"
45603
+ };
45604
+ function expandSrAlias(arg) {
45605
+ return SR_MODEL_ALIASES[arg.toLowerCase()] ?? arg;
45606
+ }
45607
+ function expandClaudeAlias(arg) {
45608
+ return CLAUDE_MODEL_ALIASES[arg.trim().toLowerCase()] ?? arg;
45609
+ }
45610
+ function canonicalModelToken(arg) {
45611
+ const trimmed = arg.trim();
45612
+ const lower = trimmed.toLowerCase();
45613
+ return lower.startsWith("claude-") ? lower : trimmed;
45614
+ }
45615
+ function expandModelAlias(arg) {
45616
+ return canonicalModelToken(expandSrAlias(expandClaudeAlias(arg)));
45617
+ }
45618
+
45619
+ // gateway/model-command.ts
45620
+ var MODEL_ALIASES = ["opus", "sonnet", "haiku", "fable", "default"];
45571
45621
  var MODEL_ARG_RE = /^[A-Za-z0-9][A-Za-z0-9._/\[\]-]{0,99}$/;
45572
45622
  function isValidModelArg(arg) {
45573
45623
  return MODEL_ARG_RE.test(arg);
@@ -45767,34 +45817,6 @@ var SR_MODEL_LABELS = {
45767
45817
  "sr-gpt-5.6-terra": "GPT-5.6 Terra",
45768
45818
  "sr-gpt-5.6-luna": "GPT-5.6 Luna"
45769
45819
  };
45770
- var SR_MODEL_ALIASES = {
45771
- flash: "sr-gemini-2.5-flash",
45772
- gemini: "sr-gemini-2.5-pro",
45773
- deepseek: "sr-deepseek-v3",
45774
- r1: "sr-deepseek-r1",
45775
- glm: "sr-glm-5",
45776
- codex: "sr-codex-5.5",
45777
- grok: "sr-grok-4.5",
45778
- kimi: "sr-kimi-k3",
45779
- gpt: "sr-gpt-5.6-sol",
45780
- sol: "sr-gpt-5.6-sol",
45781
- terra: "sr-gpt-5.6-terra",
45782
- luna: "sr-gpt-5.6-luna"
45783
- };
45784
- function expandSrAlias(arg) {
45785
- return SR_MODEL_ALIASES[arg.toLowerCase()] ?? arg;
45786
- }
45787
- function canonicalModelToken(arg) {
45788
- const trimmed = arg.trim();
45789
- const lower = trimmed.toLowerCase();
45790
- return lower.startsWith("claude-") ? lower : trimmed;
45791
- }
45792
- function expandClaudeAlias(arg) {
45793
- return CLAUDE_MODEL_ALIASES[arg.trim().toLowerCase()] ?? arg;
45794
- }
45795
- function expandModelAlias(arg) {
45796
- return canonicalModelToken(expandSrAlias(expandClaudeAlias(arg)));
45797
- }
45798
45820
  function srFriendlyLabel(srName) {
45799
45821
  return SR_MODEL_LABELS[srName] ?? srName.replace(/^sr-/, "").replace(/-/g, " ");
45800
45822
  }
@@ -80388,6 +80410,25 @@ function discardParkedTurnStart(rawContent) {
80388
80410
  }
80389
80411
  return null;
80390
80412
  }
80413
+ function drainParkedTurnStartsForChat(deps, chatId, threadId) {
80414
+ const wantThread = envThreadIdNum(threadId);
80415
+ const drained = [];
80416
+ for (let i = 0;i < parkedTurnStarts.length; ) {
80417
+ const entry = parkedTurnStarts[i];
80418
+ if (entry.chatId === chatId && envThreadIdNum(entry.threadId) === wantThread) {
80419
+ drained.push(entry);
80420
+ parkedTurnStarts.splice(i, 1);
80421
+ } else {
80422
+ i++;
80423
+ }
80424
+ }
80425
+ for (const env of drained) {
80426
+ process.stderr.write(`telegram gateway: parked-turn-start drained on silence-fallback ` + `chat=${env.chatId ?? "-"} thread=${envThreadIdNum(env.threadId) ?? "-"} ` + `msg=${env.messageId ?? "-"}
80427
+ `);
80428
+ beginTurn(deps, env);
80429
+ }
80430
+ return drained;
80431
+ }
80391
80432
  async function openQueuedCard(deps, chatId, threadId, replyToMessageId) {
80392
80433
  try {
80393
80434
  const sent = await deps.robustApiCall(() => deps.bot.api.sendRichMessage(chatId, richMessage(QUEUED_CARD_HTML), {
@@ -84127,10 +84168,6 @@ Allowed: \`${deps.escapeHtml(allow)}\``, { html: true });
84127
84168
 
84128
84169
  // gateway/model-command.ts
84129
84170
  var MODEL_ALIASES2 = ["opus", "sonnet", "haiku", "fable", "default"];
84130
- var CLAUDE_MODEL_ALIASES2 = {
84131
- opus48: "claude-opus-4-8",
84132
- "opus-4-8": "claude-opus-4-8"
84133
- };
84134
84171
  var MODEL_ARG_RE2 = /^[A-Za-z0-9][A-Za-z0-9._/\[\]-]{0,99}$/;
84135
84172
  function isValidModelArg2(arg) {
84136
84173
  return MODEL_ARG_RE2.test(arg);
@@ -84289,7 +84326,7 @@ function resolveStaleAwareBusy(input) {
84289
84326
  var PERSIST_NOTE3 = "_A `/model` switch relaunches the session (~30s) on the chosen model. Session-only \u2014 reverts to the configured `model:` on the next restart. `/model default` reverts now. Live scrollback is replaced by a fresh session; memory and the handoff briefing carry the context. To change the default permanently, set `model:` in switchroom.yaml._";
84290
84327
  function claudeAliasHints2(prefix) {
84291
84328
  const byTarget = new Map;
84292
- for (const [alias, target] of Object.entries(CLAUDE_MODEL_ALIASES2)) {
84329
+ for (const [alias, target] of Object.entries(CLAUDE_MODEL_ALIASES)) {
84293
84330
  const spellings = byTarget.get(target) ?? [];
84294
84331
  spellings.push(alias);
84295
84332
  byTarget.set(target, spellings);
@@ -84297,7 +84334,7 @@ function claudeAliasHints2(prefix) {
84297
84334
  return [...byTarget].map(([target, spellings]) => `${spellings.map((a) => `\`${prefix}${a}\``).join(" \u00b7 ")} \u2192 \`${target}\``).join("; ");
84298
84335
  }
84299
84336
  function helpText4(deps, reason) {
84300
- const srAliasExamples = Object.keys(SR_MODEL_ALIASES2).map((a) => `\`${a}\``).join(" \u00b7 ");
84337
+ const srAliasExamples = Object.keys(SR_MODEL_ALIASES).map((a) => `\`${a}\``).join(" \u00b7 ");
84301
84338
  const claudeAliasExamples = claudeAliasHints2("");
84302
84339
  const lines = [];
84303
84340
  if (reason)
@@ -84312,7 +84349,7 @@ async function handleModelCommand2(parsed, deps) {
84312
84349
  if (parsed.kind === "show") {
84313
84350
  const configured = deps.getConfiguredModel();
84314
84351
  const shown = configured && configured.length > 0 ? configured : "default";
84315
- const srAliasExamples = Object.keys(SR_MODEL_ALIASES2).map((a) => `\`/model ${a}\``).join(" \u00b7 ");
84352
+ const srAliasExamples = Object.keys(SR_MODEL_ALIASES).map((a) => `\`/model ${a}\``).join(" \u00b7 ");
84316
84353
  return {
84317
84354
  text: [
84318
84355
  `**Model \u2014 ${deps.escapeHtml(deps.getAgentName())}**`,
@@ -84330,7 +84367,7 @@ async function handleModelCommand2(parsed, deps) {
84330
84367
  if (!isValidModelArg2(parsed.model)) {
84331
84368
  return helpText4(deps, `not a valid model name: ${parsed.model}`);
84332
84369
  }
84333
- const model = expandModelAlias2(parsed.model);
84370
+ const model = expandModelAlias(parsed.model);
84334
84371
  if (deps.isBusy()) {
84335
84372
  return {
84336
84373
  text: "\u23f3 The agent is mid-turn \u2014 a model switch needs an idle session. The switch was not applied.",
@@ -84357,10 +84394,10 @@ function relaunchErrorReply2(deps, model, err) {
84357
84394
  return { text: `\u274c Could not schedule model switch: ${deps.escapeHtml(msg)}`, html: true };
84358
84395
  }
84359
84396
  function unvalidatedIdCaveat2(deps, model) {
84360
- const lower = canonicalModelToken2(model).toLowerCase();
84397
+ const lower = canonicalModelToken(model).toLowerCase();
84361
84398
  if (!lower.startsWith("claude-"))
84362
84399
  return null;
84363
- if (Object.values(CLAUDE_MODEL_ALIASES2).includes(lower))
84400
+ if (Object.values(CLAUDE_MODEL_ALIASES).includes(lower))
84364
84401
  return null;
84365
84402
  return `_\`${deps.escapeHtml(model)}\` can't be validated before launch \u2014 if it isn't a real Claude model id, claude will silently serve the configured fallback model instead. I check the first reply and will warn if that happens._`;
84366
84403
  }
@@ -84445,45 +84482,17 @@ var SR_MODEL_LABELS2 = {
84445
84482
  "sr-gpt-5.6-terra": "GPT-5.6 Terra",
84446
84483
  "sr-gpt-5.6-luna": "GPT-5.6 Luna"
84447
84484
  };
84448
- var SR_MODEL_ALIASES2 = {
84449
- flash: "sr-gemini-2.5-flash",
84450
- gemini: "sr-gemini-2.5-pro",
84451
- deepseek: "sr-deepseek-v3",
84452
- r1: "sr-deepseek-r1",
84453
- glm: "sr-glm-5",
84454
- codex: "sr-codex-5.5",
84455
- grok: "sr-grok-4.5",
84456
- kimi: "sr-kimi-k3",
84457
- gpt: "sr-gpt-5.6-sol",
84458
- sol: "sr-gpt-5.6-sol",
84459
- terra: "sr-gpt-5.6-terra",
84460
- luna: "sr-gpt-5.6-luna"
84461
- };
84462
84485
  function isOfflineTrustedModelToken(token) {
84463
84486
  const lower = token.toLowerCase();
84464
84487
  if (MODEL_ALIASES2.includes(lower))
84465
84488
  return true;
84466
- if (lower in SR_MODEL_ALIASES2)
84489
+ if (lower in SR_MODEL_ALIASES)
84467
84490
  return true;
84468
- if (Object.values(SR_MODEL_ALIASES2).includes(lower))
84491
+ if (Object.values(SR_MODEL_ALIASES).includes(lower))
84469
84492
  return true;
84470
- if (lower in CLAUDE_MODEL_ALIASES2)
84493
+ if (lower in CLAUDE_MODEL_ALIASES)
84471
84494
  return true;
84472
- return Object.values(CLAUDE_MODEL_ALIASES2).includes(lower);
84473
- }
84474
- function expandSrAlias2(arg) {
84475
- return SR_MODEL_ALIASES2[arg.toLowerCase()] ?? arg;
84476
- }
84477
- function canonicalModelToken2(arg) {
84478
- const trimmed = arg.trim();
84479
- const lower = trimmed.toLowerCase();
84480
- return lower.startsWith("claude-") ? lower : trimmed;
84481
- }
84482
- function expandClaudeAlias2(arg) {
84483
- return CLAUDE_MODEL_ALIASES2[arg.trim().toLowerCase()] ?? arg;
84484
- }
84485
- function expandModelAlias2(arg) {
84486
- return canonicalModelToken2(expandSrAlias2(expandClaudeAlias2(arg)));
84495
+ return Object.values(CLAUDE_MODEL_ALIASES).includes(lower);
84487
84496
  }
84488
84497
  function srFriendlyLabel2(srName) {
84489
84498
  return SR_MODEL_LABELS2[srName] ?? srName.replace(/^sr-/, "").replace(/-/g, " ");
@@ -84563,7 +84572,7 @@ function headerRow2(label) {
84563
84572
  return [{ text: label, callback_data: MODEL_CALLBACK_HEADER2 }];
84564
84573
  }
84565
84574
  function externalModelNames2(discovered) {
84566
- const set = new Set(Object.values(SR_MODEL_ALIASES2));
84575
+ const set = new Set(Object.values(SR_MODEL_ALIASES));
84567
84576
  for (const n of discovered) {
84568
84577
  if (isSrModel2(n))
84569
84578
  set.add(n);
@@ -84681,7 +84690,7 @@ async function handleModelMenuCallback(data, deps) {
84681
84690
  if (!isValidModelArg2(token)) {
84682
84691
  return { answer: "Invalid model name", reply: await buildModelMenu2(deps) };
84683
84692
  }
84684
- token = expandModelAlias2(token);
84693
+ token = expandModelAlias(token);
84685
84694
  if (!isRecognizedSwitchToken(token)) {
84686
84695
  return { answer: "Model list changed \u2014 menu refreshed", reply: await buildModelMenu2(deps) };
84687
84696
  }
@@ -85787,7 +85796,9 @@ function resolveMainModel(model) {
85787
85796
  return normalizeModelAlias(model);
85788
85797
  }
85789
85798
  function normalizeModelAlias(model) {
85790
- return model === "claude-fable-5" ? "fable" : model;
85799
+ if (model === "claude-fable-5")
85800
+ return "fable";
85801
+ return expandModelAlias(model);
85791
85802
  }
85792
85803
  var CLAUDE_MD_YOURS_PLACEHOLDER = "This space is yours. Add per-agent rules, exceptions, or context the " + "Switchroom template doesn't capture. Everything above the marker line is " + "regenerated on every apply; this section is preserved.";
85793
85804
  var pendingBankOps = new Set;
@@ -93615,6 +93626,7 @@ function buildSilencePokeOptions(deps) {
93615
93626
  endCurrentTurnForKey,
93616
93627
  getPendingInboundBuffer,
93617
93628
  trackRedeliveredInbound,
93629
+ drainParkedTurnStarts,
93618
93630
  closeActivityLane,
93619
93631
  closeProgressLane,
93620
93632
  hangRestart
@@ -93808,7 +93820,8 @@ function buildSilencePokeOptions(deps) {
93808
93820
  } catch {}
93809
93821
  const fbSelfAgent = process.env.SWITCHROOM_AGENT_NAME ?? "";
93810
93822
  const fbRedeliver = redeliverBufferedInbound2(getPendingInboundBuffer(), fbSelfAgent, (m) => sendToAgent(fbSelfAgent, m), getInboundSpool(), trackRedeliveredInbound);
93811
- process.stderr.write(`telegram gateway: silence-poke framework-fallback ended wedged turn ` + `chat=${fbChatId} thread=${ctx.threadId ?? "-"} silence_ms=${ctx.silenceMs} ` + `currentTurn_nulled=${tearsDownLiveTurn} ` + `drained_buffered=${fbRedeliver.redelivered}/${fbRedeliver.drained}` + `${fbRedeliver.rebuffered > 0 ? ` rebuffered=${fbRedeliver.rebuffered}` : ""}` + `${fbExtraPurge.purged.length > 0 ? ` extra_keys_purged=${fbExtraPurge.purged.length}` : ""}
93823
+ const fbDrainedParked = drainParkedTurnStarts?.(fbChatId, fbThreadId ?? null) ?? 0;
93824
+ process.stderr.write(`telegram gateway: silence-poke framework-fallback ended wedged turn ` + `chat=${fbChatId} thread=${ctx.threadId ?? "-"} silence_ms=${ctx.silenceMs} ` + `currentTurn_nulled=${tearsDownLiveTurn} ` + `drained_buffered=${fbRedeliver.redelivered}/${fbRedeliver.drained}` + `${fbDrainedParked > 0 ? ` drained_parked=${fbDrainedParked}` : ""}` + `${fbRedeliver.rebuffered > 0 ? ` rebuffered=${fbRedeliver.rebuffered}` : ""}` + `${fbExtraPurge.purged.length > 0 ? ` extra_keys_purged=${fbExtraPurge.purged.length}` : ""}
93812
93825
  `);
93813
93826
  }
93814
93827
  };
@@ -100106,10 +100119,10 @@ function startOutboxSweep(deps) {
100106
100119
  }
100107
100120
 
100108
100121
  // ../src/build-info.ts
100109
- var VERSION2 = "0.19.41";
100110
- var COMMIT_SHA = "e77ee9c0";
100111
- var COMMIT_DATE = "2026-07-31T09:46:10Z";
100112
- var LATEST_PR = 4066;
100122
+ var VERSION2 = "0.19.42";
100123
+ var COMMIT_SHA = "e288dac2";
100124
+ var COMMIT_DATE = "2026-08-01T02:20:24Z";
100125
+ var LATEST_PR = 4094;
100113
100126
  var COMMITS_AHEAD_OF_TAG = 0;
100114
100127
 
100115
100128
  // gateway/boot-version.ts
@@ -105649,6 +105662,7 @@ function gatewayLivenessWiringDeps() {
105649
105662
  endCurrentTurnForKey,
105650
105663
  getPendingInboundBuffer: () => pendingInboundBuffer,
105651
105664
  trackRedeliveredInbound,
105665
+ drainParkedTurnStarts: (chatId, threadId) => drainParkedTurnStartsForChat(gatewayStreamRenderDeps(), chatId, threadId != null ? String(threadId) : null).length,
105652
105666
  closeActivityLane,
105653
105667
  closeProgressLane,
105654
105668
  hangRestart: {
@@ -109784,7 +109798,7 @@ function persistQueuedCommandForRestart(action) {
109784
109798
  return `\u21A9\uFE0F Couldn\u2019t verify \`${escapeHtmlForTg2(action.cmd.targetLabel || action.arg)}\` as a known model without the live session \u2014 it was NOT saved. Re-issue \`/model ${escapeHtmlForTg2(action.arg)}\` once the agent is back.`;
109785
109799
  }
109786
109800
  const configured = readConfiguredDefaultModel(agentDir) ?? resolveMainModel(undefined);
109787
- writeSessionModelFile(agentDir, expandModelAlias2(action.arg), configured);
109801
+ writeSessionModelFile(agentDir, expandModelAlias(action.arg), configured);
109788
109802
  break;
109789
109803
  }
109790
109804
  case "clear-model":