switchroom 0.19.39 → 0.19.40

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 (31) hide show
  1. package/dist/agent-scheduler/index.js +10 -1
  2. package/dist/auth-broker/index.js +12 -3
  3. package/dist/cli/notion-write-pretool.mjs +10 -1
  4. package/dist/cli/switchroom.js +524 -189
  5. package/dist/host-control/main.js +217 -5
  6. package/dist/vault/approvals/kernel-server.js +12 -3
  7. package/dist/vault/broker/server.js +12 -3
  8. package/package.json +1 -1
  9. package/profiles/_base/start.sh.hbs +10 -0
  10. package/telegram-plugin/dist/bridge/bridge.js +8 -0
  11. package/telegram-plugin/dist/gateway/gateway.js +314 -191
  12. package/telegram-plugin/dist/server.js +8 -0
  13. package/telegram-plugin/gateway/backstop-delivery.ts +48 -0
  14. package/telegram-plugin/gateway/compaction-marker.ts +84 -0
  15. package/telegram-plugin/gateway/gateway.ts +3 -3
  16. package/telegram-plugin/gateway/liveness-wiring.ts +15 -0
  17. package/telegram-plugin/gateway/outbound-send-path.ts +20 -0
  18. package/telegram-plugin/gateway/outbox-sweep.ts +116 -18
  19. package/telegram-plugin/gateway/silence-poke-session-event.ts +13 -0
  20. package/telegram-plugin/gateway/stream-render.ts +39 -1
  21. package/telegram-plugin/hooks/compaction-marker-precompact.mjs +70 -0
  22. package/telegram-plugin/hooks/hooks.json +11 -0
  23. package/telegram-plugin/session-tail.ts +20 -0
  24. package/telegram-plugin/silence-poke.ts +28 -0
  25. package/telegram-plugin/tests/outbox-delivery.test.ts +38 -1
  26. package/telegram-plugin/tests/outbox-flush-ack-claim-race.test.ts +213 -0
  27. package/telegram-plugin/tests/outbox-reply-then-recap-e2e.test.ts +1 -1
  28. package/telegram-plugin/tests/outbox-sweep-flood-breaker.test.ts +4 -4
  29. package/telegram-plugin/tests/outbox-sweep-listen-button.test.ts +71 -8
  30. package/telegram-plugin/tests/send-reply-golden.test.ts +47 -0
  31. package/telegram-plugin/tests/silence-poke-compaction.test.ts +222 -0
@@ -10965,6 +10965,12 @@ var OBSERVATION_SCOPES = [
10965
10965
  "all_combinations",
10966
10966
  "shared"
10967
10967
  ];
10968
+ var OBSERVATION_SCOPE_STRATEGIES = [
10969
+ "curated",
10970
+ "shared",
10971
+ "combined",
10972
+ "off"
10973
+ ];
10968
10974
 
10969
10975
  // src/config/schema.ts
10970
10976
  var CodeRepoEntrySchema = exports_external.object({
@@ -11078,7 +11084,8 @@ var AgentToolsSchema = exports_external.object({
11078
11084
  allow: exports_external.array(exports_external.string()).default([]).describe("Allowed tools (use ['all'] for unrestricted)"),
11079
11085
  deny: exports_external.array(exports_external.string()).default([]).describe("Denied tools (overrides allow)")
11080
11086
  }).optional();
11081
- var ObservationScopesSchema = exports_external.enum(OBSERVATION_SCOPES).optional().describe("Per-row observation scope stamped on every memory this agent " + `retains. "shared" makes Hindsight's consolidation write the ` + "resulting observations into ONE global untagged scope instead of a " + "scope per tag — what several agents pooling one bank need so their " + "observations actually merge rather than sitting in parallel " + "per-tag silos. OMITTED BY DEFAULT: unset means the field never goes " + "on the wire and the engine's own default stands, which is the " + "shipped behaviour. Applies to every retain path (Stop hook, " + "sidechain, boot reconcile, queue drain, backfill, session-handoff " + "mirror) and is carried on the queued payload, so a retain that fails " + "now and drains later still lands in this scope. Accepted values: " + `${OBSERVATION_SCOPES.join(", ")}. ` + "Cascade: override (per-agent wins over default).");
11087
+ var ObservationScopesSchema = exports_external.enum(OBSERVATION_SCOPES).optional().describe("Operator PIN for the per-row observation scope, overriding the " + 'default `curated` strategy (see docs/configuration.md). "shared" ' + "forces Hindsight's consolidation to write EVERY observation into ONE " + "global untagged scope — what several agents pooling one bank want so " + "their observations merge rather than sitting in parallel silos. " + '"combined" is the pin form of opting out (restores the pre-#4035 ' + "engine default). UNSET does NOT mean 'nothing on the wire': the " + "`curated` strategy still computes a scope per retain. Applies to " + "every retain path (Stop hook, " + "sidechain, boot reconcile, queue drain, backfill, session-handoff " + "mirror) and is carried on the queued payload, so a retain that fails " + "now and drains later still lands in this scope. Accepted values: " + `${OBSERVATION_SCOPES.join(", ")}. ` + "Cascade: override (per-agent wins over default).");
11088
+ var ObservationScopeStrategySchema = exports_external.enum(OBSERVATION_SCOPE_STRATEGIES).optional().describe("Per-retain strategy that decides how the observation scope is " + 'computed when no `observation_scopes` pin is set. "curated" ' + "(the default since #4035) strips volatile per-session provenance " + "tags from each retain's consolidation scope — keeping the stable " + "semantic ones on the source fact — so an agent's observations dedup " + "and merge across sessions instead of pocketing one-per-session. " + '"shared" sends every retain to the one global untagged scope. ' + '"combined" / "off" opt OUT: no per-row scope goes on the wire, ' + "restoring the pre-feature engine default (byte-identical to an " + "unconfigured client). OMITTED BY DEFAULT: unset leaves the plugin's " + "own default (`curated`) in force. A manual `observation_scopes` pin " + "wins over this strategy. Accepted values: " + `${OBSERVATION_SCOPE_STRATEGIES.join(", ")}. ` + "Cascade: override (per-agent wins over default).");
11082
11089
  var AgentMemorySchema = exports_external.object({
11083
11090
  collection: exports_external.string().describe("Hindsight collection name for this agent"),
11084
11091
  auto_recall: exports_external.boolean().default(true).describe("Auto-search memories before each response"),
@@ -11114,6 +11121,7 @@ var AgentMemorySchema = exports_external.object({
11114
11121
  }).optional().describe("Personality traits (1-5 each) steering how this bank frames recall, " + "reflect, and observation synthesis — a coach leans empathy-high, a " + "lawyer/analyst leans skepticism/literalism-high. Maps to the engine's " + "flat `disposition_skepticism`/`_literalism`/`_empathy` fields. " + "Cascade: per-key merge (an agent overrides individual traits and " + "inherits the rest, matching `recall`)."),
11115
11122
  directive_capture_nudge: exports_external.boolean().optional().describe("Deterministic directive-capture nudge (issue #2848 Stage B). When " + "on (switchroom default true — Stage A measured a ~55% miss rate on " + "durable corrections), the auto-recall hook regex-detects correction " + '/ standing-rule-shaped inbound ("always/never …", "from now on …", ' + `"stop doing …", a stated preference, "that's wrong, it's …") and ` + "appends a terse advisory to the turn's context telling the model to " + "persist the rule with mcp__hindsight__create_directive if it IS " + "durable. Detection is pure regex — the model does the judgment " + "in-session and calls create_directive itself (no model callsite, no " + "silent hook-side write). Set false to disable per-agent. " + "Cascade: override (per-agent wins over default)."),
11116
11123
  observation_scopes: ObservationScopesSchema,
11124
+ observation_scope_strategy: ObservationScopeStrategySchema,
11117
11125
  recall: exports_external.object({
11118
11126
  max_memories: exports_external.number().int().min(0).optional().describe("Cap on the number of memories injected into the prompt by " + "auto-recall, regardless of token budget. Plugin default is 12. " + "0 disables the cap (all memories Hindsight returns are injected)."),
11119
11127
  cache_ttl_secs: exports_external.number().int().min(0).optional().describe("Per-session recall cache TTL in seconds. When > 0, identical " + "(prompt, bank) within the same session reuse the cached recall " + "result instead of round-tripping to Hindsight. 0 disables. " + "Default is 600 (10 min) for switchroom-managed agents."),
@@ -11514,6 +11522,7 @@ var profileFields = {
11514
11522
  isolation: exports_external.enum(["default", "strict"]).optional(),
11515
11523
  directive_capture_nudge: exports_external.boolean().optional(),
11516
11524
  observation_scopes: ObservationScopesSchema,
11525
+ observation_scope_strategy: ObservationScopeStrategySchema,
11517
11526
  recall: exports_external.object({
11518
11527
  max_memories: exports_external.number().int().min(0).optional(),
11519
11528
  cache_ttl_secs: exports_external.number().int().min(0).optional(),
@@ -10977,7 +10977,7 @@ var init_zod = __esm(() => {
10977
10977
  });
10978
10978
 
10979
10979
  // src/memory/observation-scopes.ts
10980
- var OBSERVATION_SCOPES;
10980
+ var OBSERVATION_SCOPES, OBSERVATION_SCOPE_STRATEGIES;
10981
10981
  var init_observation_scopes = __esm(() => {
10982
10982
  OBSERVATION_SCOPES = [
10983
10983
  "per_tag",
@@ -10985,10 +10985,16 @@ var init_observation_scopes = __esm(() => {
10985
10985
  "all_combinations",
10986
10986
  "shared"
10987
10987
  ];
10988
+ OBSERVATION_SCOPE_STRATEGIES = [
10989
+ "curated",
10990
+ "shared",
10991
+ "combined",
10992
+ "off"
10993
+ ];
10988
10994
  });
10989
10995
 
10990
10996
  // src/config/schema.ts
10991
- var CodeRepoEntrySchema, AgentBindMountSchema, HttpDiffPollSchema, PollSpecSchema, TelegramMessageActionSchema, WebhookActionSchema, ActionSpecSchema, ScheduleEntrySchema, AgentSoulSchema, AgentToolsSchema, ObservationScopesSchema, AgentMemorySchema, HookEntrySchema, AgentHooksSchema, SubagentSchema, SessionSchema, SessionContinuitySchema, webhookDispatchRule, TelegramChannelSchema, ChannelsSchema, TIMEZONE_REGEX, ApproverIdSchema, GoogleWorkspaceTierSchema, GoogleWorkspaceConfigSchema, LiteLLMConfigSchema, HindsightPerOpLlmSchema, HindsightConfigSchema, MicrosoftWorkspaceConfigSchema, NotionWorkspaceConfigSchema, AgentGoogleWorkspaceConfigSchema, MicrosoftAccountEmailSchema, MicrosoftToolTokenSchema, MicrosoftAccountBindingSchema, AgentMicrosoftWorkspaceConfigSchema, AgentNotionWorkspaceConfigSchema, ReactionsSchema, ReactionDispatchSchema, releaseBlockFields, ReleaseBlock, RootReleaseBlock, NetworkIsolationSchema, servesField, knowsField, profileFields, ProfileSchema, _omitExtends, defaultsFields, AgentDefaultsSchema, AgentSchema, TelegramConfigSchema, MemoryBackendConfigSchema, VaultConfigSchema, QuotaConfigSchema, AutoReleaseCheckSchema, HostControlConfigSchema, WebServiceConfigSchema, FleetHealthConfigSchema, HostdConfigSchema, CronEgressSchema, CronConfigSchema, UserSchema, SwitchroomConfigSchema;
10997
+ var CodeRepoEntrySchema, AgentBindMountSchema, HttpDiffPollSchema, PollSpecSchema, TelegramMessageActionSchema, WebhookActionSchema, ActionSpecSchema, ScheduleEntrySchema, AgentSoulSchema, AgentToolsSchema, ObservationScopesSchema, ObservationScopeStrategySchema, AgentMemorySchema, HookEntrySchema, AgentHooksSchema, SubagentSchema, SessionSchema, SessionContinuitySchema, webhookDispatchRule, TelegramChannelSchema, ChannelsSchema, TIMEZONE_REGEX, ApproverIdSchema, GoogleWorkspaceTierSchema, GoogleWorkspaceConfigSchema, LiteLLMConfigSchema, HindsightPerOpLlmSchema, HindsightConfigSchema, MicrosoftWorkspaceConfigSchema, NotionWorkspaceConfigSchema, AgentGoogleWorkspaceConfigSchema, MicrosoftAccountEmailSchema, MicrosoftToolTokenSchema, MicrosoftAccountBindingSchema, AgentMicrosoftWorkspaceConfigSchema, AgentNotionWorkspaceConfigSchema, ReactionsSchema, ReactionDispatchSchema, releaseBlockFields, ReleaseBlock, RootReleaseBlock, NetworkIsolationSchema, servesField, knowsField, profileFields, ProfileSchema, _omitExtends, defaultsFields, AgentDefaultsSchema, AgentSchema, TelegramConfigSchema, MemoryBackendConfigSchema, VaultConfigSchema, QuotaConfigSchema, AutoReleaseCheckSchema, HostControlConfigSchema, WebServiceConfigSchema, FleetHealthConfigSchema, HostdConfigSchema, CronEgressSchema, CronConfigSchema, UserSchema, SwitchroomConfigSchema;
10992
10998
  var init_schema = __esm(() => {
10993
10999
  init_zod();
10994
11000
  init_observation_scopes();
@@ -11103,7 +11109,8 @@ var init_schema = __esm(() => {
11103
11109
  allow: exports_external.array(exports_external.string()).default([]).describe("Allowed tools (use ['all'] for unrestricted)"),
11104
11110
  deny: exports_external.array(exports_external.string()).default([]).describe("Denied tools (overrides allow)")
11105
11111
  }).optional();
11106
- ObservationScopesSchema = exports_external.enum(OBSERVATION_SCOPES).optional().describe("Per-row observation scope stamped on every memory this agent " + `retains. "shared" makes Hindsight's consolidation write the ` + "resulting observations into ONE global untagged scope instead of a " + "scope per tag — what several agents pooling one bank need so their " + "observations actually merge rather than sitting in parallel " + "per-tag silos. OMITTED BY DEFAULT: unset means the field never goes " + "on the wire and the engine's own default stands, which is the " + "shipped behaviour. Applies to every retain path (Stop hook, " + "sidechain, boot reconcile, queue drain, backfill, session-handoff " + "mirror) and is carried on the queued payload, so a retain that fails " + "now and drains later still lands in this scope. Accepted values: " + `${OBSERVATION_SCOPES.join(", ")}. ` + "Cascade: override (per-agent wins over default).");
11112
+ ObservationScopesSchema = exports_external.enum(OBSERVATION_SCOPES).optional().describe("Operator PIN for the per-row observation scope, overriding the " + 'default `curated` strategy (see docs/configuration.md). "shared" ' + "forces Hindsight's consolidation to write EVERY observation into ONE " + "global untagged scope — what several agents pooling one bank want so " + "their observations merge rather than sitting in parallel silos. " + '"combined" is the pin form of opting out (restores the pre-#4035 ' + "engine default). UNSET does NOT mean 'nothing on the wire': the " + "`curated` strategy still computes a scope per retain. Applies to " + "every retain path (Stop hook, " + "sidechain, boot reconcile, queue drain, backfill, session-handoff " + "mirror) and is carried on the queued payload, so a retain that fails " + "now and drains later still lands in this scope. Accepted values: " + `${OBSERVATION_SCOPES.join(", ")}. ` + "Cascade: override (per-agent wins over default).");
11113
+ ObservationScopeStrategySchema = exports_external.enum(OBSERVATION_SCOPE_STRATEGIES).optional().describe("Per-retain strategy that decides how the observation scope is " + 'computed when no `observation_scopes` pin is set. "curated" ' + "(the default since #4035) strips volatile per-session provenance " + "tags from each retain's consolidation scope — keeping the stable " + "semantic ones on the source fact — so an agent's observations dedup " + "and merge across sessions instead of pocketing one-per-session. " + '"shared" sends every retain to the one global untagged scope. ' + '"combined" / "off" opt OUT: no per-row scope goes on the wire, ' + "restoring the pre-feature engine default (byte-identical to an " + "unconfigured client). OMITTED BY DEFAULT: unset leaves the plugin's " + "own default (`curated`) in force. A manual `observation_scopes` pin " + "wins over this strategy. Accepted values: " + `${OBSERVATION_SCOPE_STRATEGIES.join(", ")}. ` + "Cascade: override (per-agent wins over default).");
11107
11114
  AgentMemorySchema = exports_external.object({
11108
11115
  collection: exports_external.string().describe("Hindsight collection name for this agent"),
11109
11116
  auto_recall: exports_external.boolean().default(true).describe("Auto-search memories before each response"),
@@ -11139,6 +11146,7 @@ var init_schema = __esm(() => {
11139
11146
  }).optional().describe("Personality traits (1-5 each) steering how this bank frames recall, " + "reflect, and observation synthesis — a coach leans empathy-high, a " + "lawyer/analyst leans skepticism/literalism-high. Maps to the engine's " + "flat `disposition_skepticism`/`_literalism`/`_empathy` fields. " + "Cascade: per-key merge (an agent overrides individual traits and " + "inherits the rest, matching `recall`)."),
11140
11147
  directive_capture_nudge: exports_external.boolean().optional().describe("Deterministic directive-capture nudge (issue #2848 Stage B). When " + "on (switchroom default true — Stage A measured a ~55% miss rate on " + "durable corrections), the auto-recall hook regex-detects correction " + '/ standing-rule-shaped inbound ("always/never …", "from now on …", ' + `"stop doing …", a stated preference, "that's wrong, it's …") and ` + "appends a terse advisory to the turn's context telling the model to " + "persist the rule with mcp__hindsight__create_directive if it IS " + "durable. Detection is pure regex — the model does the judgment " + "in-session and calls create_directive itself (no model callsite, no " + "silent hook-side write). Set false to disable per-agent. " + "Cascade: override (per-agent wins over default)."),
11141
11148
  observation_scopes: ObservationScopesSchema,
11149
+ observation_scope_strategy: ObservationScopeStrategySchema,
11142
11150
  recall: exports_external.object({
11143
11151
  max_memories: exports_external.number().int().min(0).optional().describe("Cap on the number of memories injected into the prompt by " + "auto-recall, regardless of token budget. Plugin default is 12. " + "0 disables the cap (all memories Hindsight returns are injected)."),
11144
11152
  cache_ttl_secs: exports_external.number().int().min(0).optional().describe("Per-session recall cache TTL in seconds. When > 0, identical " + "(prompt, bank) within the same session reuse the cached recall " + "result instead of round-tripping to Hindsight. 0 disables. " + "Default is 600 (10 min) for switchroom-managed agents."),
@@ -11539,6 +11547,7 @@ var init_schema = __esm(() => {
11539
11547
  isolation: exports_external.enum(["default", "strict"]).optional(),
11540
11548
  directive_capture_nudge: exports_external.boolean().optional(),
11541
11549
  observation_scopes: ObservationScopesSchema,
11550
+ observation_scope_strategy: ObservationScopeStrategySchema,
11542
11551
  recall: exports_external.object({
11543
11552
  max_memories: exports_external.number().int().min(0).optional(),
11544
11553
  cache_ttl_secs: exports_external.number().int().min(0).optional(),
@@ -11726,6 +11726,12 @@ var OBSERVATION_SCOPES = [
11726
11726
  "all_combinations",
11727
11727
  "shared"
11728
11728
  ];
11729
+ var OBSERVATION_SCOPE_STRATEGIES = [
11730
+ "curated",
11731
+ "shared",
11732
+ "combined",
11733
+ "off"
11734
+ ];
11729
11735
 
11730
11736
  // src/config/schema.ts
11731
11737
  var CodeRepoEntrySchema = exports_external.object({
@@ -11839,7 +11845,8 @@ var AgentToolsSchema = exports_external.object({
11839
11845
  allow: exports_external.array(exports_external.string()).default([]).describe("Allowed tools (use ['all'] for unrestricted)"),
11840
11846
  deny: exports_external.array(exports_external.string()).default([]).describe("Denied tools (overrides allow)")
11841
11847
  }).optional();
11842
- var ObservationScopesSchema = exports_external.enum(OBSERVATION_SCOPES).optional().describe("Per-row observation scope stamped on every memory this agent " + `retains. "shared" makes Hindsight's consolidation write the ` + "resulting observations into ONE global untagged scope instead of a " + "scope per tag \u2014 what several agents pooling one bank need so their " + "observations actually merge rather than sitting in parallel " + "per-tag silos. OMITTED BY DEFAULT: unset means the field never goes " + "on the wire and the engine's own default stands, which is the " + "shipped behaviour. Applies to every retain path (Stop hook, " + "sidechain, boot reconcile, queue drain, backfill, session-handoff " + "mirror) and is carried on the queued payload, so a retain that fails " + "now and drains later still lands in this scope. Accepted values: " + `${OBSERVATION_SCOPES.join(", ")}. ` + "Cascade: override (per-agent wins over default).");
11848
+ var ObservationScopesSchema = exports_external.enum(OBSERVATION_SCOPES).optional().describe("Operator PIN for the per-row observation scope, overriding the " + 'default `curated` strategy (see docs/configuration.md). "shared" ' + "forces Hindsight's consolidation to write EVERY observation into ONE " + "global untagged scope \u2014 what several agents pooling one bank want so " + "their observations merge rather than sitting in parallel silos. " + '"combined" is the pin form of opting out (restores the pre-#4035 ' + "engine default). UNSET does NOT mean 'nothing on the wire': the " + "`curated` strategy still computes a scope per retain. Applies to " + "every retain path (Stop hook, " + "sidechain, boot reconcile, queue drain, backfill, session-handoff " + "mirror) and is carried on the queued payload, so a retain that fails " + "now and drains later still lands in this scope. Accepted values: " + `${OBSERVATION_SCOPES.join(", ")}. ` + "Cascade: override (per-agent wins over default).");
11849
+ var ObservationScopeStrategySchema = exports_external.enum(OBSERVATION_SCOPE_STRATEGIES).optional().describe("Per-retain strategy that decides how the observation scope is " + 'computed when no `observation_scopes` pin is set. "curated" ' + "(the default since #4035) strips volatile per-session provenance " + "tags from each retain's consolidation scope \u2014 keeping the stable " + "semantic ones on the source fact \u2014 so an agent's observations dedup " + "and merge across sessions instead of pocketing one-per-session. " + '"shared" sends every retain to the one global untagged scope. ' + '"combined" / "off" opt OUT: no per-row scope goes on the wire, ' + "restoring the pre-feature engine default (byte-identical to an " + "unconfigured client). OMITTED BY DEFAULT: unset leaves the plugin's " + "own default (`curated`) in force. A manual `observation_scopes` pin " + "wins over this strategy. Accepted values: " + `${OBSERVATION_SCOPE_STRATEGIES.join(", ")}. ` + "Cascade: override (per-agent wins over default).");
11843
11850
  var AgentMemorySchema = exports_external.object({
11844
11851
  collection: exports_external.string().describe("Hindsight collection name for this agent"),
11845
11852
  auto_recall: exports_external.boolean().default(true).describe("Auto-search memories before each response"),
@@ -11875,6 +11882,7 @@ var AgentMemorySchema = exports_external.object({
11875
11882
  }).optional().describe("Personality traits (1-5 each) steering how this bank frames recall, " + "reflect, and observation synthesis \u2014 a coach leans empathy-high, a " + "lawyer/analyst leans skepticism/literalism-high. Maps to the engine's " + "flat `disposition_skepticism`/`_literalism`/`_empathy` fields. " + "Cascade: per-key merge (an agent overrides individual traits and " + "inherits the rest, matching `recall`)."),
11876
11883
  directive_capture_nudge: exports_external.boolean().optional().describe("Deterministic directive-capture nudge (issue #2848 Stage B). When " + "on (switchroom default true \u2014 Stage A measured a ~55% miss rate on " + "durable corrections), the auto-recall hook regex-detects correction " + '/ standing-rule-shaped inbound ("always/never \u2026", "from now on \u2026", ' + `"stop doing \u2026", a stated preference, "that's wrong, it's \u2026") and ` + "appends a terse advisory to the turn's context telling the model to " + "persist the rule with mcp__hindsight__create_directive if it IS " + "durable. Detection is pure regex \u2014 the model does the judgment " + "in-session and calls create_directive itself (no model callsite, no " + "silent hook-side write). Set false to disable per-agent. " + "Cascade: override (per-agent wins over default)."),
11877
11884
  observation_scopes: ObservationScopesSchema,
11885
+ observation_scope_strategy: ObservationScopeStrategySchema,
11878
11886
  recall: exports_external.object({
11879
11887
  max_memories: exports_external.number().int().min(0).optional().describe("Cap on the number of memories injected into the prompt by " + "auto-recall, regardless of token budget. Plugin default is 12. " + "0 disables the cap (all memories Hindsight returns are injected)."),
11880
11888
  cache_ttl_secs: exports_external.number().int().min(0).optional().describe("Per-session recall cache TTL in seconds. When > 0, identical " + "(prompt, bank) within the same session reuse the cached recall " + "result instead of round-tripping to Hindsight. 0 disables. " + "Default is 600 (10 min) for switchroom-managed agents."),
@@ -12275,6 +12283,7 @@ var profileFields = {
12275
12283
  isolation: exports_external.enum(["default", "strict"]).optional(),
12276
12284
  directive_capture_nudge: exports_external.boolean().optional(),
12277
12285
  observation_scopes: ObservationScopesSchema,
12286
+ observation_scope_strategy: ObservationScopeStrategySchema,
12278
12287
  recall: exports_external.object({
12279
12288
  max_memories: exports_external.number().int().min(0).optional(),
12280
12289
  cache_ttl_secs: exports_external.number().int().min(0).optional(),