switchroom 0.19.41 → 0.19.43
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 +23 -3
- package/dist/auth-broker/index.js +54 -9
- package/dist/cli/notion-write-pretool.mjs +23 -3
- package/dist/cli/switchroom.js +1956 -900
- package/dist/host-control/main.js +227 -30
- package/dist/vault/approvals/kernel-server.js +54 -9
- package/dist/vault/broker/server.js +54 -9
- package/package.json +3 -3
- package/profiles/_base/start.sh.hbs +82 -4
- package/telegram-plugin/bridge/bridge.ts +1 -1
- package/telegram-plugin/card-layout.ts +63 -1
- package/telegram-plugin/dist/bridge/bridge.js +4 -1
- package/telegram-plugin/dist/gateway/gateway.js +1318 -693
- package/telegram-plugin/dist/server.js +5 -2
- package/telegram-plugin/flood-429-ledger.ts +5 -3
- package/telegram-plugin/flood-circuit-breaker.ts +11 -3
- package/telegram-plugin/format.ts +223 -13
- package/telegram-plugin/gateway/approval-callback-consume-record.test.ts +132 -0
- package/telegram-plugin/gateway/boot-card.ts +7 -2
- package/telegram-plugin/gateway/flood-reply-queue.ts +5 -0
- package/telegram-plugin/gateway/gateway.ts +56 -58
- package/telegram-plugin/gateway/handback-orphan-recovery.ts +69 -0
- package/telegram-plugin/gateway/handback-preturn-signal.ts +170 -32
- package/telegram-plugin/gateway/ipc-protocol.ts +31 -3
- package/telegram-plugin/gateway/ipc-server.ts +13 -4
- package/telegram-plugin/gateway/liveness-wiring.ts +12 -0
- package/telegram-plugin/gateway/model-command.ts +21 -109
- package/telegram-plugin/gateway/obligation-store.ts +55 -0
- package/telegram-plugin/gateway/outbound-send-path.ts +127 -11
- package/telegram-plugin/gateway/outbox-sweep.ts +371 -61
- package/telegram-plugin/gateway/rollout-status-edit.ts +175 -0
- package/telegram-plugin/gateway/stream-render.ts +62 -0
- package/telegram-plugin/gateway/update-announce.ts +11 -4
- package/telegram-plugin/hooks/audience-classify.d.mts +50 -0
- package/telegram-plugin/hooks/audience-classify.mjs +364 -0
- package/telegram-plugin/hooks/silent-end-interrupt-stop.mjs +86 -3
- package/telegram-plugin/hooks/silent-end-scan.mjs +80 -4
- package/telegram-plugin/outbox.ts +103 -2
- package/telegram-plugin/render/rich-render.ts +10 -2
- package/telegram-plugin/reply-quote.ts +150 -0
- package/telegram-plugin/retry-api-call.ts +254 -11
- package/telegram-plugin/shared/bot-runtime.ts +69 -34
- package/telegram-plugin/shared/gw-trace-gate.ts +14 -2
- package/telegram-plugin/silent-end.ts +34 -2
- package/telegram-plugin/status-no-truncate.ts +31 -16
- package/telegram-plugin/stream-controller.ts +44 -9
- package/telegram-plugin/stream-reply-handler.ts +5 -3
- package/telegram-plugin/tests/boot-card-render.test.ts +2 -1
- package/telegram-plugin/tests/card-budget-never-overflows.test.ts +165 -0
- package/telegram-plugin/tests/card-hard-truncate-entity-safe.test.ts +153 -0
- package/telegram-plugin/tests/card-variants.golden.txt +9 -9
- package/telegram-plugin/tests/flood-reply-queue.test.ts +89 -4
- package/telegram-plugin/tests/format-consistency.test.ts +160 -14
- package/telegram-plugin/tests/framework-fallback-drains-parked.test.ts +134 -0
- package/telegram-plugin/tests/handback-orphan-recovery.test.ts +131 -0
- package/telegram-plugin/tests/handback-preturn-signal.test.ts +212 -17
- package/telegram-plugin/tests/helpers/liveness-wiring-fixture.ts +3 -0
- package/telegram-plugin/tests/nested-indent-idiom.test.ts +162 -0
- package/telegram-plugin/tests/nested-prefix-indent.test.ts +115 -0
- package/telegram-plugin/tests/no-robust-api-call-factory.test.ts +62 -0
- package/telegram-plugin/tests/obligation-store.test.ts +51 -0
- package/telegram-plugin/tests/outbox-audience-3865.test.ts +579 -0
- package/telegram-plugin/tests/outbox-provenance-4141.test.ts +1126 -0
- package/telegram-plugin/tests/outbox-sweep-single-flight.test.ts +138 -0
- package/telegram-plugin/tests/pinned-card-collapse.test.ts +12 -10
- package/telegram-plugin/tests/plain-fallback-4096-cap.test.ts +509 -0
- package/telegram-plugin/tests/reply-quote-wire.test.ts +433 -0
- package/telegram-plugin/tests/retry-grammy-http-error.test.ts +404 -0
- package/telegram-plugin/tests/rollout-narration-edit-socket.test.ts +170 -0
- package/telegram-plugin/tests/rollout-status-edit-retry-policy.test.ts +366 -0
- package/telegram-plugin/tests/rollout-status-edit.test.ts +140 -0
- package/telegram-plugin/tests/rollout-status-wiring.test.ts +40 -7
- package/telegram-plugin/tests/tg-post-logger-error-shape.test.ts +4 -0
- package/telegram-plugin/tests/tg-post-retry-attribution.test.ts +196 -0
- package/telegram-plugin/tests/tool-activity-summary.test.ts +23 -17
- package/telegram-plugin/tool-activity-summary.ts +58 -30
- package/telegram-plugin/uat/scenarios/jtbd-foreground-subagent-activity-dm.test.ts +3 -2
- package/vendor/hindsight-memory/CHANGELOG.md +28 -0
- package/vendor/hindsight-memory/docs/measurements/subagent-volume-gate-3994.md +84 -0
- package/vendor/hindsight-memory/scripts/backfill_transcripts.py +254 -40
- package/vendor/hindsight-memory/scripts/lib/content.py +11 -2
- package/vendor/hindsight-memory/scripts/recall.py +18 -3
- package/vendor/hindsight-memory/scripts/subagent_retain.py +59 -38
- package/vendor/hindsight-memory/scripts/tests/data/replay_volume_gate_3994.py +295 -0
- package/vendor/hindsight-memory/scripts/tests/test_backfill_from_logs.py +109 -0
- package/vendor/hindsight-memory/scripts/tests/test_overlap_tokens.py +135 -0
- package/vendor/hindsight-memory/scripts/tests/test_recall_no_lexical_gate.py +20 -23
- package/vendor/hindsight-memory/scripts/tests/test_recall_query_shaping.py +48 -0
- package/vendor/hindsight-memory/scripts/tests/test_subagent_retain.py +94 -1
- package/vendor/hindsight-memory/scripts/tests/test_subagent_retain_learnings.py +98 -42
|
@@ -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,11 +4850,13 @@ 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.")
|
|
4855
4858
|
}).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."),
|
|
4856
|
-
env: exports_external.record(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()])).optional().describe("Operator overrides for switchroom's capability-gated Hindsight " + "performance defaults. Only the keys switchroom actually manages are " + "honoured (`HINDSIGHT_PERF_ENV_KEYS` in " + "src/setup/hindsight-perf-defaults.ts: RERANKER_LOCAL_FP16, " + "RERANKER_LOCAL_BATCH_SIZE, LLM_MAX_CONCURRENT, " + "RETAIN/CONSOLIDATION_LLM_MAX_CONCURRENT, LLM_STRICT_SCHEMA, " + "LLM_MAX_RETRIES, CONSOLIDATION_LLM_PARALLELISM, " + "MAX_OBSERVATIONS_PER_SCOPE, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT, " + "RERANKER_LOCAL_BUCKET_BATCHING, RERANKER_MAX_CANDIDATES, " + "RERANKER_LOCAL_MAX_CONCURRENT, RECALL_MAX_CONCURRENT, " + "REFLECT_WALL_TIMEOUT,
|
|
4859
|
+
env: exports_external.record(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()])).optional().describe("Operator overrides for switchroom's capability-gated Hindsight " + "performance defaults. Only the keys switchroom actually manages are " + "honoured (`HINDSIGHT_PERF_ENV_KEYS` in " + "src/setup/hindsight-perf-defaults.ts: RERANKER_LOCAL_FP16, " + "RERANKER_LOCAL_BATCH_SIZE, LLM_MAX_CONCURRENT, " + "RETAIN/CONSOLIDATION_LLM_MAX_CONCURRENT, LLM_STRICT_SCHEMA, " + "LLM_MAX_RETRIES, CONSOLIDATION_LLM_PARALLELISM, " + "MAX_OBSERVATIONS_PER_SCOPE, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT, " + "RERANKER_LOCAL_BUCKET_BATCHING, RERANKER_MAX_CANDIDATES, " + "RERANKER_LOCAL_MAX_CONCURRENT, RECALL_MAX_CONCURRENT, " + "REFLECT_WALL_TIMEOUT, WORKER_CONSOLIDATION_RESERVED_SLOTS, " + "WORKER_CONSOLIDATION_SLOT_LIMIT, " + "CONSOLIDATION_MAX_MEMORIES_PER_ROUND, GRAPH_SEED_MIN_SIMILARITY, " + "LLM_SUPPORTS_MAX_ITEMS, RECENCY_DECAY_FUNCTION, " + "RECENCY_DECAY_HALFLIFE_DAYS — switchroom defaults recall's recency " + "curve to `exponential` with a 30-day half-life so a fact retained " + "today outranks a stale one, instead of upstream's near-flat " + "linear/365-day window), the override-only keys " + "switchroom manages but ships NO default for " + "(`HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS`: " + "HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY — a per-deployment " + "`bank-pattern:priority,...` map; unset means upstream's flat " + "created_at FIFO across banks; and " + "HINDSIGHT_CE_DECISIVE_RELATIVE_GAP — the rollback knob for " + "switchroom's CE-saturation damping patch, a float; >= ~0.65 backs the " + "damping out entirely, unset means the patch's own derived gap; and " + "HINDSIGHT_API_RECENCY_DECAY_LINEAR_WINDOW_DAYS — only read when the " + "decay function is `linear`, so switchroom ships no default for it but " + "still honours an operator who flips the function back; and " + "HINDSIGHT_API_WORKER_MAX_SLOTS — the worker poller's TOTAL in-flight " + "task budget, the pool WORKER_CONSOLIDATION_RESERVED_SLOTS reserves out of; " + "unset means upstream's own default; and " + "HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS — the reserved slot FLOOR for the " + "retain (memory write) lane, carved from that same total; unset means " + "upstream's own 0, i.e. no floor and retain competes for the shared " + "pool; and " + "the pre-0.8.6 name HINDSIGHT_API_WORKER_<TYPE>_MAX_SLOTS is still " + "accepted for every operation type and normalised to " + "..._RESERVED_SLOTS on the way in, because setting both names for " + "one type is a hard boot failure in the engine and switchroom " + "therefore emits only the canonical name; and " + "HINDSIGHT_API_SEMANTIC_MIN_SIMILARITY — the cosine-similarity floor a " + "candidate must reach to be returned by the semantic retrieval arm at " + "all (0..1); unset means upstream's own 0.3, and where it should sit " + "depends on the bank's embedding model and phrasing diversity, so " + "switchroom ships no opinion; and " + "HINDSIGHT_MCP_RECALL_BUDGET_MODE — the rollback knob for switchroom's " + "mcp-recall-token-budget image patch; `legacy` restores upstream's " + "exact pre-patch recall returns, anything else or unset is the " + "honest-envelope mode; and " + "HINDSIGHT_API_LLM_TEMPERATURE_REFLECT — upstream's own per-op reflect " + "temperature knob, made live by switchroom's reflect-temperature image " + "patch; a float, or `none` to omit the kwarg (provider default, " + "upstream's accidental pre-patch behaviour); unset means the image's " + "baked default 0.1), 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).")
|
|
4857
4860
|
});
|
|
4858
4861
|
MicrosoftWorkspaceConfigSchema = exports_external.object({
|
|
4859
4862
|
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)."),
|
|
@@ -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(),
|
|
@@ -19393,7 +19413,9 @@ var HINDSIGHT_DEFAULT_RECALL_MAX_CONCURRENT = 8;
|
|
|
19393
19413
|
var HINDSIGHT_DEFAULT_REFLECT_WALL_TIMEOUT_S = 600;
|
|
19394
19414
|
var HINDSIGHT_DEFAULT_CONSOLIDATION_MAX_MEMORIES_PER_ROUND = 250;
|
|
19395
19415
|
var HINDSIGHT_DEFAULT_CONSOLIDATION_SLOT_LIMIT = 6;
|
|
19396
|
-
var
|
|
19416
|
+
var HINDSIGHT_DEFAULT_CONSOLIDATION_RESERVED_SLOTS = 1;
|
|
19417
|
+
var HINDSIGHT_DEFAULT_GRAPH_SEED_MIN_SIMILARITY = 0.3;
|
|
19418
|
+
var HINDSIGHT_DEFAULT_LLM_SUPPORTS_MAX_ITEMS = "false";
|
|
19397
19419
|
var HINDSIGHT_DEFAULT_RECENCY_DECAY_FUNCTION = "exponential";
|
|
19398
19420
|
var HINDSIGHT_DEFAULT_RECENCY_DECAY_HALFLIFE_DAYS = 30;
|
|
19399
19421
|
var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
@@ -19439,8 +19461,8 @@ var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
|
19439
19461
|
String(HINDSIGHT_DEFAULT_REFLECT_WALL_TIMEOUT_S)
|
|
19440
19462
|
],
|
|
19441
19463
|
[
|
|
19442
|
-
"
|
|
19443
|
-
String(
|
|
19464
|
+
"HINDSIGHT_API_WORKER_CONSOLIDATION_RESERVED_SLOTS",
|
|
19465
|
+
String(HINDSIGHT_DEFAULT_CONSOLIDATION_RESERVED_SLOTS)
|
|
19444
19466
|
],
|
|
19445
19467
|
[
|
|
19446
19468
|
"HINDSIGHT_API_WORKER_CONSOLIDATION_SLOT_LIMIT",
|
|
@@ -19457,6 +19479,10 @@ var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
|
19457
19479
|
[
|
|
19458
19480
|
"HINDSIGHT_API_RECENCY_DECAY_HALFLIFE_DAYS",
|
|
19459
19481
|
String(HINDSIGHT_DEFAULT_RECENCY_DECAY_HALFLIFE_DAYS)
|
|
19482
|
+
],
|
|
19483
|
+
[
|
|
19484
|
+
"HINDSIGHT_API_GRAPH_SEED_MIN_SIMILARITY",
|
|
19485
|
+
String(HINDSIGHT_DEFAULT_GRAPH_SEED_MIN_SIMILARITY)
|
|
19460
19486
|
]
|
|
19461
19487
|
];
|
|
19462
19488
|
var HINDSIGHT_PERF_DEFAULTS_GPU = [
|
|
@@ -19477,22 +19503,41 @@ var HINDSIGHT_PERF_DEFAULTS_LOCAL_LLM = [
|
|
|
19477
19503
|
String(HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_MAX_CONCURRENT)
|
|
19478
19504
|
],
|
|
19479
19505
|
["HINDSIGHT_API_LLM_STRICT_SCHEMA", HINDSIGHT_DEFAULT_LLM_STRICT_SCHEMA],
|
|
19480
|
-
["HINDSIGHT_API_LLM_MAX_RETRIES", String(HINDSIGHT_DEFAULT_LLM_MAX_RETRIES)]
|
|
19506
|
+
["HINDSIGHT_API_LLM_MAX_RETRIES", String(HINDSIGHT_DEFAULT_LLM_MAX_RETRIES)],
|
|
19507
|
+
["HINDSIGHT_API_LLM_SUPPORTS_MAX_ITEMS", HINDSIGHT_DEFAULT_LLM_SUPPORTS_MAX_ITEMS]
|
|
19481
19508
|
];
|
|
19482
19509
|
var HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS = new Set([
|
|
19483
19510
|
"HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY",
|
|
19484
19511
|
"HINDSIGHT_CE_DECISIVE_RELATIVE_GAP",
|
|
19485
19512
|
"HINDSIGHT_API_RECENCY_DECAY_LINEAR_WINDOW_DAYS",
|
|
19486
19513
|
"HINDSIGHT_API_WORKER_MAX_SLOTS",
|
|
19487
|
-
"
|
|
19514
|
+
"HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS",
|
|
19515
|
+
"HINDSIGHT_API_SEMANTIC_MIN_SIMILARITY",
|
|
19516
|
+
"HINDSIGHT_MCP_RECALL_BUDGET_MODE",
|
|
19517
|
+
"HINDSIGHT_API_LLM_TEMPERATURE_REFLECT",
|
|
19518
|
+
"HINDSIGHT_API_RETAIN_WALL_TIMEOUT"
|
|
19488
19519
|
]);
|
|
19520
|
+
var HINDSIGHT_WORKER_SLOT_TYPES = [
|
|
19521
|
+
"consolidation",
|
|
19522
|
+
"file_convert_retain",
|
|
19523
|
+
"graph_maintenance",
|
|
19524
|
+
"import_documents",
|
|
19525
|
+
"refresh_mental_model",
|
|
19526
|
+
"retain"
|
|
19527
|
+
];
|
|
19528
|
+
var HINDSIGHT_WORKER_RESERVED_SLOT_ALIASES = new Map(HINDSIGHT_WORKER_SLOT_TYPES.map((type) => [
|
|
19529
|
+
`HINDSIGHT_API_WORKER_${type.toUpperCase()}_MAX_SLOTS`,
|
|
19530
|
+
`HINDSIGHT_API_WORKER_${type.toUpperCase()}_RESERVED_SLOTS`
|
|
19531
|
+
]));
|
|
19489
19532
|
var HINDSIGHT_PERF_ENV_KEYS = new Set([
|
|
19490
19533
|
...[
|
|
19491
19534
|
...HINDSIGHT_PERF_DEFAULTS_UNGATED,
|
|
19492
19535
|
...HINDSIGHT_PERF_DEFAULTS_GPU,
|
|
19493
19536
|
...HINDSIGHT_PERF_DEFAULTS_LOCAL_LLM
|
|
19494
19537
|
].map(([k]) => k),
|
|
19495
|
-
...HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS
|
|
19538
|
+
...HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS,
|
|
19539
|
+
...HINDSIGHT_WORKER_RESERVED_SLOT_ALIASES.keys(),
|
|
19540
|
+
...HINDSIGHT_WORKER_RESERVED_SLOT_ALIASES.values()
|
|
19496
19541
|
]);
|
|
19497
19542
|
|
|
19498
19543
|
// src/setup/hindsight-context-budget.ts
|
|
@@ -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,11 +4446,13 @@ 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.")
|
|
4451
4454
|
}).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."),
|
|
4452
|
-
env: exports_external.record(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()])).optional().describe("Operator overrides for switchroom's capability-gated Hindsight " + "performance defaults. Only the keys switchroom actually manages are " + "honoured (`HINDSIGHT_PERF_ENV_KEYS` in " + "src/setup/hindsight-perf-defaults.ts: RERANKER_LOCAL_FP16, " + "RERANKER_LOCAL_BATCH_SIZE, LLM_MAX_CONCURRENT, " + "RETAIN/CONSOLIDATION_LLM_MAX_CONCURRENT, LLM_STRICT_SCHEMA, " + "LLM_MAX_RETRIES, CONSOLIDATION_LLM_PARALLELISM, " + "MAX_OBSERVATIONS_PER_SCOPE, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT, " + "RERANKER_LOCAL_BUCKET_BATCHING, RERANKER_MAX_CANDIDATES, " + "RERANKER_LOCAL_MAX_CONCURRENT, RECALL_MAX_CONCURRENT, " + "REFLECT_WALL_TIMEOUT,
|
|
4455
|
+
env: exports_external.record(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()])).optional().describe("Operator overrides for switchroom's capability-gated Hindsight " + "performance defaults. Only the keys switchroom actually manages are " + "honoured (`HINDSIGHT_PERF_ENV_KEYS` in " + "src/setup/hindsight-perf-defaults.ts: RERANKER_LOCAL_FP16, " + "RERANKER_LOCAL_BATCH_SIZE, LLM_MAX_CONCURRENT, " + "RETAIN/CONSOLIDATION_LLM_MAX_CONCURRENT, LLM_STRICT_SCHEMA, " + "LLM_MAX_RETRIES, CONSOLIDATION_LLM_PARALLELISM, " + "MAX_OBSERVATIONS_PER_SCOPE, " + "RECALL_MAX_CANDIDATES_PER_SOURCE, LINK_EXPANSION_PER_ENTITY_LIMIT, " + "LINK_EXPANSION_TIMEOUT, LLM_REASONING_EFFORT, " + "RERANKER_LOCAL_BUCKET_BATCHING, RERANKER_MAX_CANDIDATES, " + "RERANKER_LOCAL_MAX_CONCURRENT, RECALL_MAX_CONCURRENT, " + "REFLECT_WALL_TIMEOUT, WORKER_CONSOLIDATION_RESERVED_SLOTS, " + "WORKER_CONSOLIDATION_SLOT_LIMIT, " + "CONSOLIDATION_MAX_MEMORIES_PER_ROUND, GRAPH_SEED_MIN_SIMILARITY, " + "LLM_SUPPORTS_MAX_ITEMS, RECENCY_DECAY_FUNCTION, " + "RECENCY_DECAY_HALFLIFE_DAYS — switchroom defaults recall's recency " + "curve to `exponential` with a 30-day half-life so a fact retained " + "today outranks a stale one, instead of upstream's near-flat " + "linear/365-day window), the override-only keys " + "switchroom manages but ships NO default for " + "(`HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS`: " + "HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY — a per-deployment " + "`bank-pattern:priority,...` map; unset means upstream's flat " + "created_at FIFO across banks; and " + "HINDSIGHT_CE_DECISIVE_RELATIVE_GAP — the rollback knob for " + "switchroom's CE-saturation damping patch, a float; >= ~0.65 backs the " + "damping out entirely, unset means the patch's own derived gap; and " + "HINDSIGHT_API_RECENCY_DECAY_LINEAR_WINDOW_DAYS — only read when the " + "decay function is `linear`, so switchroom ships no default for it but " + "still honours an operator who flips the function back; and " + "HINDSIGHT_API_WORKER_MAX_SLOTS — the worker poller's TOTAL in-flight " + "task budget, the pool WORKER_CONSOLIDATION_RESERVED_SLOTS reserves out of; " + "unset means upstream's own default; and " + "HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS — the reserved slot FLOOR for the " + "retain (memory write) lane, carved from that same total; unset means " + "upstream's own 0, i.e. no floor and retain competes for the shared " + "pool; and " + "the pre-0.8.6 name HINDSIGHT_API_WORKER_<TYPE>_MAX_SLOTS is still " + "accepted for every operation type and normalised to " + "..._RESERVED_SLOTS on the way in, because setting both names for " + "one type is a hard boot failure in the engine and switchroom " + "therefore emits only the canonical name; and " + "HINDSIGHT_API_SEMANTIC_MIN_SIMILARITY — the cosine-similarity floor a " + "candidate must reach to be returned by the semantic retrieval arm at " + "all (0..1); unset means upstream's own 0.3, and where it should sit " + "depends on the bank's embedding model and phrasing diversity, so " + "switchroom ships no opinion; and " + "HINDSIGHT_MCP_RECALL_BUDGET_MODE — the rollback knob for switchroom's " + "mcp-recall-token-budget image patch; `legacy` restores upstream's " + "exact pre-patch recall returns, anything else or unset is the " + "honest-envelope mode; and " + "HINDSIGHT_API_LLM_TEMPERATURE_REFLECT — upstream's own per-op reflect " + "temperature knob, made live by switchroom's reflect-temperature image " + "patch; a float, or `none` to omit the kwarg (provider default, " + "upstream's accidental pre-patch behaviour); unset means the image's " + "baked default 0.1), 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).")
|
|
4453
4456
|
});
|
|
4454
4457
|
MicrosoftWorkspaceConfigSchema = exports_external.object({
|
|
4455
4458
|
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)."),
|
|
@@ -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
|
});
|
|
@@ -19806,7 +19826,9 @@ var HINDSIGHT_DEFAULT_RECALL_MAX_CONCURRENT = 8;
|
|
|
19806
19826
|
var HINDSIGHT_DEFAULT_REFLECT_WALL_TIMEOUT_S = 600;
|
|
19807
19827
|
var HINDSIGHT_DEFAULT_CONSOLIDATION_MAX_MEMORIES_PER_ROUND = 250;
|
|
19808
19828
|
var HINDSIGHT_DEFAULT_CONSOLIDATION_SLOT_LIMIT = 6;
|
|
19809
|
-
var
|
|
19829
|
+
var HINDSIGHT_DEFAULT_CONSOLIDATION_RESERVED_SLOTS = 1;
|
|
19830
|
+
var HINDSIGHT_DEFAULT_GRAPH_SEED_MIN_SIMILARITY = 0.3;
|
|
19831
|
+
var HINDSIGHT_DEFAULT_LLM_SUPPORTS_MAX_ITEMS = "false";
|
|
19810
19832
|
var HINDSIGHT_DEFAULT_RECENCY_DECAY_FUNCTION = "exponential";
|
|
19811
19833
|
var HINDSIGHT_DEFAULT_RECENCY_DECAY_HALFLIFE_DAYS = 30;
|
|
19812
19834
|
var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
@@ -19852,8 +19874,8 @@ var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
|
19852
19874
|
String(HINDSIGHT_DEFAULT_REFLECT_WALL_TIMEOUT_S)
|
|
19853
19875
|
],
|
|
19854
19876
|
[
|
|
19855
|
-
"
|
|
19856
|
-
String(
|
|
19877
|
+
"HINDSIGHT_API_WORKER_CONSOLIDATION_RESERVED_SLOTS",
|
|
19878
|
+
String(HINDSIGHT_DEFAULT_CONSOLIDATION_RESERVED_SLOTS)
|
|
19857
19879
|
],
|
|
19858
19880
|
[
|
|
19859
19881
|
"HINDSIGHT_API_WORKER_CONSOLIDATION_SLOT_LIMIT",
|
|
@@ -19870,6 +19892,10 @@ var HINDSIGHT_PERF_DEFAULTS_UNGATED = [
|
|
|
19870
19892
|
[
|
|
19871
19893
|
"HINDSIGHT_API_RECENCY_DECAY_HALFLIFE_DAYS",
|
|
19872
19894
|
String(HINDSIGHT_DEFAULT_RECENCY_DECAY_HALFLIFE_DAYS)
|
|
19895
|
+
],
|
|
19896
|
+
[
|
|
19897
|
+
"HINDSIGHT_API_GRAPH_SEED_MIN_SIMILARITY",
|
|
19898
|
+
String(HINDSIGHT_DEFAULT_GRAPH_SEED_MIN_SIMILARITY)
|
|
19873
19899
|
]
|
|
19874
19900
|
];
|
|
19875
19901
|
var HINDSIGHT_PERF_DEFAULTS_GPU = [
|
|
@@ -19890,22 +19916,41 @@ var HINDSIGHT_PERF_DEFAULTS_LOCAL_LLM = [
|
|
|
19890
19916
|
String(HINDSIGHT_DEFAULT_CONSOLIDATION_LLM_MAX_CONCURRENT)
|
|
19891
19917
|
],
|
|
19892
19918
|
["HINDSIGHT_API_LLM_STRICT_SCHEMA", HINDSIGHT_DEFAULT_LLM_STRICT_SCHEMA],
|
|
19893
|
-
["HINDSIGHT_API_LLM_MAX_RETRIES", String(HINDSIGHT_DEFAULT_LLM_MAX_RETRIES)]
|
|
19919
|
+
["HINDSIGHT_API_LLM_MAX_RETRIES", String(HINDSIGHT_DEFAULT_LLM_MAX_RETRIES)],
|
|
19920
|
+
["HINDSIGHT_API_LLM_SUPPORTS_MAX_ITEMS", HINDSIGHT_DEFAULT_LLM_SUPPORTS_MAX_ITEMS]
|
|
19894
19921
|
];
|
|
19895
19922
|
var HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS = new Set([
|
|
19896
19923
|
"HINDSIGHT_API_WORKER_CONSOLIDATION_BANK_PRIORITY",
|
|
19897
19924
|
"HINDSIGHT_CE_DECISIVE_RELATIVE_GAP",
|
|
19898
19925
|
"HINDSIGHT_API_RECENCY_DECAY_LINEAR_WINDOW_DAYS",
|
|
19899
19926
|
"HINDSIGHT_API_WORKER_MAX_SLOTS",
|
|
19900
|
-
"
|
|
19927
|
+
"HINDSIGHT_API_WORKER_RETAIN_RESERVED_SLOTS",
|
|
19928
|
+
"HINDSIGHT_API_SEMANTIC_MIN_SIMILARITY",
|
|
19929
|
+
"HINDSIGHT_MCP_RECALL_BUDGET_MODE",
|
|
19930
|
+
"HINDSIGHT_API_LLM_TEMPERATURE_REFLECT",
|
|
19931
|
+
"HINDSIGHT_API_RETAIN_WALL_TIMEOUT"
|
|
19901
19932
|
]);
|
|
19933
|
+
var HINDSIGHT_WORKER_SLOT_TYPES = [
|
|
19934
|
+
"consolidation",
|
|
19935
|
+
"file_convert_retain",
|
|
19936
|
+
"graph_maintenance",
|
|
19937
|
+
"import_documents",
|
|
19938
|
+
"refresh_mental_model",
|
|
19939
|
+
"retain"
|
|
19940
|
+
];
|
|
19941
|
+
var HINDSIGHT_WORKER_RESERVED_SLOT_ALIASES = new Map(HINDSIGHT_WORKER_SLOT_TYPES.map((type) => [
|
|
19942
|
+
`HINDSIGHT_API_WORKER_${type.toUpperCase()}_MAX_SLOTS`,
|
|
19943
|
+
`HINDSIGHT_API_WORKER_${type.toUpperCase()}_RESERVED_SLOTS`
|
|
19944
|
+
]));
|
|
19902
19945
|
var HINDSIGHT_PERF_ENV_KEYS = new Set([
|
|
19903
19946
|
...[
|
|
19904
19947
|
...HINDSIGHT_PERF_DEFAULTS_UNGATED,
|
|
19905
19948
|
...HINDSIGHT_PERF_DEFAULTS_GPU,
|
|
19906
19949
|
...HINDSIGHT_PERF_DEFAULTS_LOCAL_LLM
|
|
19907
19950
|
].map(([k]) => k),
|
|
19908
|
-
...HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS
|
|
19951
|
+
...HINDSIGHT_PERF_OVERRIDE_ONLY_KEYS,
|
|
19952
|
+
...HINDSIGHT_WORKER_RESERVED_SLOT_ALIASES.keys(),
|
|
19953
|
+
...HINDSIGHT_WORKER_RESERVED_SLOT_ALIASES.values()
|
|
19909
19954
|
]);
|
|
19910
19955
|
|
|
19911
19956
|
// src/setup/hindsight-context-budget.ts
|
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.43",
|
|
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,9 +24,9 @@
|
|
|
24
24
|
"build": "node scripts/build.mjs",
|
|
25
25
|
"build:cli": "node scripts/build.mjs && bun build --compile --target=bun-linux-x64 --minify bin/switchroom.ts --outfile switchroom-linux-amd64",
|
|
26
26
|
"pretest": "npm run build",
|
|
27
|
-
"test": "vitest run && bun test telegram-plugin/tests/agent-state-dir-preload.test.ts telegram-plugin/tests/catch-all-forwarded-history.test.ts telegram-plugin/tests/history.test.ts telegram-plugin/tests/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/rollout-narration-edit-socket.test.ts telegram-plugin/tests/gateway-bridge.test.ts telegram-plugin/tests/gateway-startup-mutex.test.ts telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts telegram-plugin/tests/boot-card-dedupe.test.ts telegram-plugin/tests/boot-card-reason.test.ts telegram-plugin/tests/progress-update.test.ts telegram-plugin/tests/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/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",
|
|
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/rollout-narration-edit-socket.test.ts telegram-plugin/tests/gateway-bridge.test.ts telegram-plugin/tests/gateway-startup-mutex.test.ts telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts telegram-plugin/tests/boot-card-dedupe.test.ts telegram-plugin/tests/boot-card-reason.test.ts telegram-plugin/tests/progress-update.test.ts telegram-plugin/tests/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
31
|
"lint": "tsc --noEmit && node scripts/check-plugin-references.mjs && bash scripts/check-bot-api-wrapping.sh && node scripts/check-bun-test-imports.mjs && node scripts/check-test-runner-coverage.mjs && node scripts/check-bun-module-mock-scope.mjs && node scripts/check-no-pii-secrets.mjs && node scripts/check-vault-test-hermeticity.mjs && node scripts/check-auth-test-hermeticity.mjs && node scripts/check-agent-state-dir-hermeticity.mjs && node scripts/check-no-broadcast-delivery.mjs && node scripts/check-stale-tool-descriptions.mjs && node scripts/check-mcp-instructions-budget.mjs && node scripts/check-web-subscription-honest.mjs && node scripts/check-no-unpinned-npx-playwright.mjs && node scripts/check-gateway-line-ratchet.mjs && node scripts/check-retry-flood-hooks.mjs && node scripts/check-callback-ctx-wrapping.mjs && node scripts/check-status-pin-single-path.mjs && node scripts/check-litellm-config-guard.mjs && node scripts/check-release-asset-names.mjs && node scripts/check-agent-attribution-trailers.mjs && node scripts/check-hindsight-write-redaction.mjs && bun scripts/check-secret-pattern-parity.ts",
|
|
32
32
|
"lint:tsc": "tsc --noEmit",
|
|
@@ -2002,10 +2002,88 @@ esac
|
|
|
2002
2002
|
# changed) appends to `.session-model-alert` so the gateway's boot relay
|
|
2003
2003
|
# tells the operator once.
|
|
2004
2004
|
#
|
|
2005
|
-
#
|
|
2006
|
-
#
|
|
2007
|
-
#
|
|
2008
|
-
|
|
2005
|
+
# --- Live configured-default resolution (effort sibling of the model block) ---
|
|
2006
|
+
#
|
|
2007
|
+
# The apply-time bake is only the LAST-DITCH fallback: editing
|
|
2008
|
+
# `thinking_effort:` in switchroom.yaml and restarting must take effect
|
|
2009
|
+
# WITHOUT a full `switchroom apply`, exactly as `model:` already does. Before
|
|
2010
|
+
# this, model was live-read and effort was bake-only, so a yaml effort change
|
|
2011
|
+
# needed an apply to re-render every start.sh — and the gateway's /effort menu
|
|
2012
|
+
# (which derives its configured default from `agent list --json`, i.e. the LIVE
|
|
2013
|
+
# yaml) disagreed with what the launcher actually passed to `--effort`.
|
|
2014
|
+
#
|
|
2015
|
+
# Same resolver as the gateway, asked as a verb (`switchroom agent
|
|
2016
|
+
# effective-effort`), never re-implemented in shell. Fallback chain, never
|
|
2017
|
+
# silent past step 1:
|
|
2018
|
+
# 1. live read of $SWITCHROOM_CONFIG (one bounded retry — a host-side
|
|
2019
|
+
# in-place rewrite can present a torn file for a moment);
|
|
2020
|
+
# 2. `.configured-default-effort` — the last-known-good live value this
|
|
2021
|
+
# launcher recorded on every prior boot (read BEFORE it is overwritten);
|
|
2022
|
+
# 3. the apply-time bake.
|
|
2023
|
+
# Steps 2/3 append to `.session-model-alert` so the gateway tells the operator
|
|
2024
|
+
# once at boot. No SWITCHROOM_CONFIG mount at all means there is nothing to
|
|
2025
|
+
# read live — the bake IS the truth there (stderr note only).
|
|
2026
|
+
#
|
|
2027
|
+
# Unlike the model sibling there is no routing class to flip: effort is a pure
|
|
2028
|
+
# CLI flag, so a live change is always safe to apply on a bare restart.
|
|
2029
|
+
#
|
|
2030
|
+
# NB {{thinkingEffort}} renders inside single quotes here (the scaffold does
|
|
2031
|
+
# not pre-quote it, unlike modelQ), and an unset value renders as '' — which
|
|
2032
|
+
# means "no --effort flag", handled by the $_EFFORT_ARG guard below.
|
|
2033
|
+
_BAKED_EFFORT={{#if thinkingEffort}}'{{thinkingEffort}}'{{else}}''{{/if}}
|
|
2034
|
+
_LKG_EFFORT="$(cat "{{agentDir}}/.configured-default-effort" 2>/dev/null | tr -d '[:space:]' || true)"
|
|
2035
|
+
_EFFECTIVE_EFFORT=""
|
|
2036
|
+
# Set only when step 1 actually produced a live value — it gates the
|
|
2037
|
+
# `.configured-default-effort` write below so the last-known-good file can
|
|
2038
|
+
# never record a value that was never live truth.
|
|
2039
|
+
_LE_LIVE_OK=""
|
|
2040
|
+
if [ -n "$SWITCHROOM_CONFIG" ] && [ -f "$SWITCHROOM_CONFIG" ] && command -v switchroom >/dev/null 2>&1; then
|
|
2041
|
+
_le_live=""
|
|
2042
|
+
for _le_try in 1 2; do
|
|
2043
|
+
_le_live="$(timeout 20 switchroom --config "$SWITCHROOM_CONFIG" agent effective-effort "{{name}}" 2>/dev/null | tail -n 1 | tr -d '[:space:]')" || _le_live=""
|
|
2044
|
+
# Allowlist gate — kept in sync with EFFORT_LEVELS in
|
|
2045
|
+
# telegram-plugin/gateway/effort-command.ts, byte-identical to the carrier
|
|
2046
|
+
# gate below. Anything else is treated as a failed read, not a value.
|
|
2047
|
+
if [ -n "$_le_live" ] && printf '%s' "$_le_live" | grep -Eq '^(low|medium|high|xhigh|max)$'; then
|
|
2048
|
+
break
|
|
2049
|
+
fi
|
|
2050
|
+
_le_live=""
|
|
2051
|
+
if [ "$_le_try" -eq 1 ]; then sleep 1; fi
|
|
2052
|
+
done
|
|
2053
|
+
if [ -n "$_le_live" ]; then
|
|
2054
|
+
_EFFECTIVE_EFFORT="$_le_live"
|
|
2055
|
+
_LE_LIVE_OK=1
|
|
2056
|
+
if [ "$_le_live" != "$_BAKED_EFFORT" ]; then
|
|
2057
|
+
echo "session-effort: live configured thinking_effort '$_le_live' differs from apply-time bake '${_BAKED_EFFORT:-<unset>}' — using the live value (switchroom.yaml is the source of truth)" >&2
|
|
2058
|
+
fi
|
|
2059
|
+
elif [ -n "$_LKG_EFFORT" ] && printf '%s' "$_LKG_EFFORT" | grep -Eq '^(low|medium|high|xhigh|max)$'; then
|
|
2060
|
+
# Live read failed (torn write mid-read, yaml schema error, CLI wedge).
|
|
2061
|
+
# Last-known-good beats the bake: it was live truth on a prior boot, while
|
|
2062
|
+
# the bake can predate any number of yaml edits. Loud either way.
|
|
2063
|
+
_EFFECTIVE_EFFORT="$_LKG_EFFORT"
|
|
2064
|
+
echo "session-effort: live effort read FAILED or returned an unrecognised level — using last-known-good configured thinking_effort '$_LKG_EFFORT' (apply-time bake: '${_BAKED_EFFORT:-<unset>}')" >&2
|
|
2065
|
+
printf 'The live `thinking_effort:` could not be resolved at boot — switchroom.yaml could not be read, or it held a value this launcher does not recognise. The agent booted on the last-known-good configured effort `%s`. Check `thinking_effort:` in the yaml (low/medium/high/xhigh/max) and restart the agent.\n' "$_LKG_EFFORT" >> "{{agentDir}}/.session-model-alert" 2>/dev/null || true
|
|
2066
|
+
else
|
|
2067
|
+
_EFFECTIVE_EFFORT="$_BAKED_EFFORT"
|
|
2068
|
+
echo "session-effort: live effort read FAILED or returned an unrecognised level, and no last-known-good value — using apply-time baked thinking_effort '${_BAKED_EFFORT:-<unset>}'" >&2
|
|
2069
|
+
printf 'The live `thinking_effort:` could not be resolved at boot — switchroom.yaml could not be read, or it held a value this launcher does not recognise — and no prior boot recorded an effort. The agent booted on the apply-time default `%s`. Check `thinking_effort:` in the yaml (low/medium/high/xhigh/max) and restart the agent.\n' "${_BAKED_EFFORT:-<unset>}" >> "{{agentDir}}/.session-model-alert" 2>/dev/null || true
|
|
2070
|
+
fi
|
|
2071
|
+
unset _le_live _le_try
|
|
2072
|
+
else
|
|
2073
|
+
_EFFECTIVE_EFFORT="$_BAKED_EFFORT"
|
|
2074
|
+
fi
|
|
2075
|
+
unset _BAKED_EFFORT _LKG_EFFORT
|
|
2076
|
+
# Record the LIVE-RESOLVED configured default, BEFORE the carrier below can
|
|
2077
|
+
# override it — this is the last-known-good the fallback chain reads on the
|
|
2078
|
+
# NEXT boot, and it must be the configured value, not a session override.
|
|
2079
|
+
# Written ONLY when step 1 genuinely produced a live value: a bake/LKG-fallback
|
|
2080
|
+
# boot (or a boot with no config mount at all) has no live truth to record, and
|
|
2081
|
+
# writing the bake here would let a LATER failed read cite a "last-known-good"
|
|
2082
|
+
# that was never read from switchroom.yaml.
|
|
2083
|
+
if [ -n "$_LE_LIVE_OK" ]; then
|
|
2084
|
+
printf '%s\n' "$_EFFECTIVE_EFFORT" > "{{agentDir}}/.configured-default-effort" 2>/dev/null || true
|
|
2085
|
+
fi
|
|
2086
|
+
unset _LE_LIVE_OK
|
|
2009
2087
|
if [ -f "{{agentDir}}/.session-effort" ]; then
|
|
2010
2088
|
_sef="$(cat "{{agentDir}}/.session-effort" 2>/dev/null || true)"
|
|
2011
2089
|
_se_level="$(printf '%s' "$_sef" | sed -n 's/.*"level"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')"
|
|
@@ -108,7 +108,7 @@ const TOOL_SCHEMAS = [
|
|
|
108
108
|
format: { type: 'string', enum: ['html', 'markdownv2', 'text'], description: "Rendering mode. Default renders your text as rich GFM markdown (Bot API 10.1). 'text' sends plain text verbatim. 'html' and 'markdownv2' are legacy aliases that route through the same single rich GFM path — no separate HTML engine, no auto-escaping." },
|
|
109
109
|
disable_web_page_preview: { type: 'boolean', description: 'Disable link preview thumbnails. Default: true.' },
|
|
110
110
|
protect_content: { type: 'boolean', description: 'When true, Telegram prevents the message from being forwarded or saved.' },
|
|
111
|
-
quote_text: { type: 'string', description: 'Surgical quote: specific text to highlight from the reply_to message. Requires reply_to.' },
|
|
111
|
+
quote_text: { type: 'string', description: 'Surgical quote: specific text to highlight from the reply_to message. Must be an EXACT substring of that message (copy it verbatim, do not paraphrase; max 1024 chars) — a quote Telegram cannot find is dropped and the reply lands unquoted. Requires reply_to.' },
|
|
112
112
|
disable_notification: { type: 'boolean', description: 'When true, Telegram delivers the message silently — no device ping for this user. Default false (pings). Use true for mid-turn updates ("still working through X") so only the final answer pings. Always omit (or pass false) on the final answer of a turn.' },
|
|
113
113
|
inline_keyboard: {
|
|
114
114
|
type: 'array',
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
32
|
import { escapeMarkdown, stripMarkdown, truncate, stackCardLines } from './card-format.js'
|
|
33
|
+
import { truncateMarkdownSafe } from './format.js'
|
|
33
34
|
import { formatModelLabel } from './model-label.js'
|
|
34
35
|
import { STATUS_CARD_CHAR_BUDGET, STATUS_LINE_MAX, STATUS_ROLLING_LINES } from './status-no-truncate.js'
|
|
35
36
|
|
|
@@ -313,6 +314,13 @@ export interface CardCandidate {
|
|
|
313
314
|
* an oversized newest bullet), while the combined card drops its newest worker
|
|
314
315
|
* row into `+M more working…`. The MECHANISM — render, measure, accept or go
|
|
315
316
|
* deeper — exists only here.
|
|
317
|
+
*
|
|
318
|
+
* The return is UNCONDITIONALLY within `STATUS_CARD_CHAR_BUDGET` (#3833). The
|
|
319
|
+
* loop used to return the deepest render unmeasured, so a card whose FIXED
|
|
320
|
+
* chrome/footer alone exceeds the budget (a 40k-char worker description — the
|
|
321
|
+
* #3682 repro) escaped over the wire limit and the send failed. No shrink level
|
|
322
|
+
* can rescue that case by construction — every level keeps the chrome — so the
|
|
323
|
+
* last resort hard-truncates. A clipped card beats no card.
|
|
316
324
|
*/
|
|
317
325
|
export function fitCardToBudget(
|
|
318
326
|
build: (level: number) => CardCandidate,
|
|
@@ -324,5 +332,59 @@ export function fitCardToBudget(
|
|
|
324
332
|
text = renderCardSpec(candidate.spec)
|
|
325
333
|
if (candidate.overflow !== true && text.length <= STATUS_CARD_CHAR_BUDGET) return text
|
|
326
334
|
}
|
|
327
|
-
return text
|
|
335
|
+
return hardTruncateCard(text)
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Last-resort clip for a rendered card that no shrink level could fit — the
|
|
340
|
+
* only place a card's text is cut without going through a spec.
|
|
341
|
+
*
|
|
342
|
+
* Keeps as many WHOLE lines as fit, so line structure survives, and then runs
|
|
343
|
+
* the chosen cut through {@link truncateMarkdownSafe} so the emitted text is
|
|
344
|
+
* always PARSEABLE markdown (#4116). Two things make that necessary rather
|
|
345
|
+
* than decorative:
|
|
346
|
+
*
|
|
347
|
+
* - a first line longer than the whole budget keeps no whole line at all, so
|
|
348
|
+
* the cut lands mid-line — between a `**` pair, inside a `` ` `` span, in
|
|
349
|
+
* the middle of a `[label](href)` — and Telegram parse-REJECTS the result.
|
|
350
|
+
* The path that exists to guarantee delivery would itself fail the send.
|
|
351
|
+
* - even a whole-line cut can leave a FENCED block open, which is a
|
|
352
|
+
* multi-line entity and therefore invisible to a per-line rule.
|
|
353
|
+
*
|
|
354
|
+
* The tail is then cleaned of the stack's own break chrome (hard-break spaces /
|
|
355
|
+
* `COLLAPSE_SAFE_SEPARATOR`) and of a dangling lone surrogate, so the wire
|
|
356
|
+
* string is never invalid UTF-16.
|
|
357
|
+
*
|
|
358
|
+
* Exported for the budget tests; production callers go through
|
|
359
|
+
* {@link fitCardToBudget}.
|
|
360
|
+
*/
|
|
361
|
+
export function hardTruncateCard(
|
|
362
|
+
text: string,
|
|
363
|
+
budget: number = STATUS_CARD_CHAR_BUDGET,
|
|
364
|
+
): string {
|
|
365
|
+
if (text.length <= budget) return text
|
|
366
|
+
// The break chrome is measured on the KEPT prefix, not on the final line:
|
|
367
|
+
// a line that is followed by a break carries ` \n` (+ separator) which is
|
|
368
|
+
// stripped once it becomes the last line, so a prefix can fit after the
|
|
369
|
+
// strip even when its raw length is a few chars over.
|
|
370
|
+
let kept = ''
|
|
371
|
+
for (const line of text.split('\n')) {
|
|
372
|
+
const next = kept.length === 0 ? line : `${kept}\n${line}`
|
|
373
|
+
if (trimBreakChrome(next).length > budget) break
|
|
374
|
+
kept = next
|
|
375
|
+
}
|
|
376
|
+
// A first line longer than the budget keeps nothing; cut into it rather than
|
|
377
|
+
// emit a blank card. Either way the cut is taken against the FULL text — an
|
|
378
|
+
// entity straddling the boundary is only visible from there.
|
|
379
|
+
const target = kept.length > 0 ? kept.length : Math.min(budget, text.length)
|
|
380
|
+
let out = trimBreakChrome(truncateMarkdownSafe(text, target))
|
|
381
|
+
if (out.length > budget) out = trimBreakChrome(truncateMarkdownSafe(text, budget))
|
|
382
|
+
// Finally, never leave a lone high surrogate from slicing through an astral
|
|
383
|
+
// character.
|
|
384
|
+
return /[\uD800-\uDBFF]$/.test(out) ? out.slice(0, -1) : out
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/** Strip a stacked card's trailing hard-break spaces / collapse separator. */
|
|
388
|
+
function trimBreakChrome(text: string): string {
|
|
389
|
+
return text.replace(/[ \t\r\u00A0]+$/, '')
|
|
328
390
|
}
|
|
@@ -22970,6 +22970,9 @@ import {
|
|
|
22970
22970
|
import { homedir as homedir2 } from "os";
|
|
22971
22971
|
import { basename, join as join3 } from "path";
|
|
22972
22972
|
|
|
22973
|
+
// format.ts
|
|
22974
|
+
var DELIMITER_RUN_CHARS = new Set(["*", "_", "`", "~", "|"]);
|
|
22975
|
+
|
|
22973
22976
|
// text-voice-scrub.ts
|
|
22974
22977
|
var NULL = "\x00";
|
|
22975
22978
|
var FENCE_PH = `${NULL}VS_FENCE`;
|
|
@@ -25083,7 +25086,7 @@ var TOOL_SCHEMAS = [
|
|
|
25083
25086
|
format: { type: "string", enum: ["html", "markdownv2", "text"], description: "Rendering mode. Default renders your text as rich GFM markdown (Bot API 10.1). 'text' sends plain text verbatim. 'html' and 'markdownv2' are legacy aliases that route through the same single rich GFM path \u2014 no separate HTML engine, no auto-escaping." },
|
|
25084
25087
|
disable_web_page_preview: { type: "boolean", description: "Disable link preview thumbnails. Default: true." },
|
|
25085
25088
|
protect_content: { type: "boolean", description: "When true, Telegram prevents the message from being forwarded or saved." },
|
|
25086
|
-
quote_text: { type: "string", description: "Surgical quote: specific text to highlight from the reply_to message. Requires reply_to." },
|
|
25089
|
+
quote_text: { type: "string", description: "Surgical quote: specific text to highlight from the reply_to message. Must be an EXACT substring of that message (copy it verbatim, do not paraphrase; max 1024 chars) \u2014 a quote Telegram cannot find is dropped and the reply lands unquoted. Requires reply_to." },
|
|
25087
25090
|
disable_notification: { type: "boolean", description: 'When true, Telegram delivers the message silently \u2014 no device ping for this user. Default false (pings). Use true for mid-turn updates ("still working through X") so only the final answer pings. Always omit (or pass false) on the final answer of a turn.' },
|
|
25088
25091
|
inline_keyboard: {
|
|
25089
25092
|
type: "array",
|