switchroom 0.17.6 → 0.17.10
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 +38 -4
- package/dist/auth-broker/index.js +302 -203
- package/dist/cli/notion-write-pretool.mjs +35 -2
- package/dist/cli/switchroom.js +1178 -576
- package/dist/host-control/main.js +148 -14
- package/dist/vault/approvals/kernel-server.js +140 -55
- package/dist/vault/broker/server.js +142 -57
- package/package.json +1 -1
- package/profiles/_base/start.sh.hbs +50 -6
- package/profiles/default/CLAUDE.md +116 -0
- package/skills/mental-model-curator/SKILL.md +162 -0
- package/telegram-plugin/bridge/bridge.ts +80 -1
- package/telegram-plugin/bridge/ipc-client.ts +19 -0
- package/telegram-plugin/bridge/permission-ledger.ts +61 -0
- package/telegram-plugin/consolidation-legibility.ts +279 -0
- package/telegram-plugin/dist/bridge/bridge.js +85 -1
- package/telegram-plugin/dist/gateway/gateway.js +2565 -610
- package/telegram-plugin/dist/server.js +86 -2
- package/telegram-plugin/feed-heartbeat-climb.ts +206 -0
- package/telegram-plugin/gateway/activity-card-store.ts +293 -0
- package/telegram-plugin/gateway/gateway.ts +1376 -82
- package/telegram-plugin/gateway/inbound-spool.ts +22 -0
- package/telegram-plugin/gateway/mental-model-propose-card.ts +69 -0
- package/telegram-plugin/gateway/mental-model-propose-diff.ts +171 -0
- package/telegram-plugin/gateway/mental-model-propose-inbound-builders.ts +147 -0
- package/telegram-plugin/gateway/mental-model-propose-resolve.ts +201 -0
- package/telegram-plugin/gateway/missed-approvals-card.ts +161 -0
- package/telegram-plugin/gateway/missed-approvals-store.ts +167 -0
- package/telegram-plugin/gateway/permission-rearm.ts +115 -0
- package/telegram-plugin/gateway/scoped-grant-store.ts +89 -0
- package/telegram-plugin/memory-legibility.ts +217 -0
- package/telegram-plugin/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/telegram-plugin/scoped-approval.ts +59 -0
- package/telegram-plugin/silent-end.ts +78 -0
- package/telegram-plugin/subagent-watcher.ts +60 -6
- package/telegram-plugin/tests/activity-card-store.test.ts +436 -0
- package/telegram-plugin/tests/activity-card-wiring.test.ts +88 -0
- package/telegram-plugin/tests/consolidation-legibility.test.ts +224 -0
- package/telegram-plugin/tests/emission-authority-facade.test.ts +25 -10
- package/telegram-plugin/tests/feed-heartbeat-liveness-open.test.ts +33 -9
- package/telegram-plugin/tests/gateway-boot-marker-clear.test.ts +3 -3
- package/telegram-plugin/tests/inbound-spool.test.ts +105 -0
- package/telegram-plugin/tests/memory-legibility.test.ts +216 -0
- package/telegram-plugin/tests/mental-model-propose-callback-gate.test.ts +67 -0
- package/telegram-plugin/tests/mental-model-propose-card.test.ts +56 -0
- package/telegram-plugin/tests/mental-model-propose-diff.test.ts +201 -0
- package/telegram-plugin/tests/mental-model-propose-inbound-builders.test.ts +68 -0
- package/telegram-plugin/tests/mental-model-propose-resolve.test.ts +157 -0
- package/telegram-plugin/tests/missed-approvals-card.test.ts +145 -0
- package/telegram-plugin/tests/missed-approvals-store.test.ts +147 -0
- package/telegram-plugin/tests/missed-approvals-wiring.test.ts +89 -0
- package/telegram-plugin/tests/permission-ledger.test.ts +166 -0
- package/telegram-plugin/tests/permission-no-repeat-wiring.test.ts +1 -1
- package/telegram-plugin/tests/permission-rearm-wiring.test.ts +175 -0
- package/telegram-plugin/tests/permission-rearm.test.ts +126 -0
- package/telegram-plugin/tests/scoped-grant-persist.test.ts +223 -0
- package/telegram-plugin/tests/silent-end-transport.test.ts +290 -0
- package/telegram-plugin/tests/silent-turn-climb-transport.test.ts +337 -0
- package/telegram-plugin/tests/subagent-watcher.test.ts +139 -0
- package/telegram-plugin/tests/worktree-watch-cwds.test.ts +103 -0
- package/telegram-plugin/uat/assertions.ts +88 -4
- package/telegram-plugin/uat/feed-matcher.test.ts +69 -0
- package/telegram-plugin/uat/scenarios/fuzz-liveness-climb-dm.test.ts +155 -0
- package/telegram-plugin/uat/scenarios/jtbd-directive-capture-nudge-dm.test.ts +185 -0
- package/telegram-plugin/uat/scenarios/jtbd-liveness-climb-channel.test.ts +192 -0
- package/telegram-plugin/uat/scenarios/jtbd-liveness-climb-dm.test.ts +220 -0
- package/telegram-plugin/uat/scenarios/jtbd-liveness-narration-channel.test.ts +137 -0
- package/telegram-plugin/uat/scenarios/jtbd-liveness-narration-dm.test.ts +148 -0
- package/telegram-plugin/uat/scenarios/jtbd-memory-legibility-channel.test.ts +66 -0
- package/telegram-plugin/uat/scenarios/jtbd-memory-legibility-dm.test.ts +61 -0
- package/telegram-plugin/uat/scenarios/silent-end-recovery-channel.test.ts +136 -0
- package/telegram-plugin/uat/scenarios/silent-end-recovery-dm.test.ts +24 -2
- package/telegram-plugin/worktree-watch-cwds.ts +60 -0
- package/vendor/hindsight-memory/hooks/hooks.json +9 -0
- package/vendor/hindsight-memory/scripts/__pycache__/directive_verify.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/__pycache__/drain_pending.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/__pycache__/recall.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/__pycache__/retain.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/__pycache__/session_end.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/directive_verify.py +445 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/__init__.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/bank.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/client.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/config.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/content.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/daemon.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/directives.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/gateway_ipc.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/llm.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/pending.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/state.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/__pycache__/switchroom_envelope.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/lib/config.py +37 -0
- package/vendor/hindsight-memory/scripts/lib/directives.py +88 -0
- package/vendor/hindsight-memory/scripts/lib/switchroom_envelope.py +77 -0
- package/vendor/hindsight-memory/scripts/recall.py +153 -4
- package/vendor/hindsight-memory/scripts/retain.py +17 -0
- package/vendor/hindsight-memory/scripts/setup_hooks.py +9 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/__init__.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_config_client_casts.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_config_client_casts.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_directive_capture_nudge.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_directive_capture_nudge.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_directive_verify.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_directive_verify.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_directives.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_directives.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_gateway_ipc.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_gateway_ipc.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_recall_context_slice.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_recall_context_slice.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_recall_integration.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_recall_integration.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_recall_tag_filters.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_recall_tag_filters.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_recall_topic_filter.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_recall_topic_filter.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_recall_trivial_skip.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_recall_trivial_skip.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_retain_window.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_retain_window.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_sender_routing.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_sender_routing.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/__pycache__/test_switchroom_envelope.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/scripts/tests/test_directive_capture_nudge.py +185 -0
- package/vendor/hindsight-memory/scripts/tests/test_directive_verify.py +516 -0
- package/vendor/hindsight-memory/scripts/tests/test_directives.py +49 -0
- package/vendor/hindsight-memory/scripts/tests/test_retain_window.py +66 -1
- package/vendor/hindsight-memory/scripts/tests/test_switchroom_envelope.py +69 -0
- package/vendor/hindsight-memory/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/conftest.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_bank.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_bank.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_client.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_client.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_config.cpython-313-pytest-9.0.3.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_config.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_config.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_content.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_content.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_drain_pending.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_drain_pending.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_hooks.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_hooks.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_manifest.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_manifest.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_pending.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_pending.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_recall_exit_codes.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_recall_exit_codes.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_session_end_pending.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_session_end_pending.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_state.cpython-313-pytest-9.1.1.pyc +0 -0
- package/vendor/hindsight-memory/tests/__pycache__/test_state.cpython-313.pyc +0 -0
- package/vendor/hindsight-memory/tests/test_recall_exit_codes.py +49 -2
|
@@ -15850,8 +15850,35 @@ var AgentMemorySchema = exports_external.object({
|
|
|
15850
15850
|
auto_recall: exports_external.boolean().default(true).describe("Auto-search memories before each response"),
|
|
15851
15851
|
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)."),
|
|
15852
15852
|
isolation: exports_external.enum(["default", "strict"]).default("default").describe("strict = never shared cross-agent, default = eligible for reflect"),
|
|
15853
|
-
bank_mission: exports_external.string().optional().describe("Bank-level mission statement used during recall to contextualize results"),
|
|
15854
|
-
|
|
15853
|
+
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."),
|
|
15854
|
+
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."),
|
|
15855
|
+
retain_mission: exports_external.string().optional().describe("Instructions for the fact extraction LLM during retain. Cascade: override."),
|
|
15856
|
+
mental_models: exports_external.array(exports_external.object({
|
|
15857
|
+
name: exports_external.string().min(1).describe("Stable model name (identity key for idempotent ensure). Two " + "declarations with the same name in one agent are rejected."),
|
|
15858
|
+
source_query: exports_external.string().min(1).max(2000).describe("The reflection query the model answers, semantically " + "refreshed from the bank's content. Capped at 2000 chars — a " + "standing reflection query, not a document; the ceiling also " + "bounds what an agent-proposed model can smuggle past the " + "operator approval card."),
|
|
15859
|
+
refresh_after_consolidation: exports_external.boolean().optional().describe("Refresh this model after each consolidation. Defaults OFF — " + "refresh adds bounded background model-spend + timeout risk " + "(RFC Phase 5), so it is opt-in per model."),
|
|
15860
|
+
max_tokens: exports_external.number().int().positive().max(8192).optional().describe("Cap on the synthesized model's token size. Upper-bounded at " + "8192 — a mental model is a standing summary, not a corpus; the " + "ceiling also caps what an agent-proposed model can request.")
|
|
15861
|
+
})).superRefine((models, ctx) => {
|
|
15862
|
+
const seen = new Set;
|
|
15863
|
+
for (let i = 0;i < models.length; i++) {
|
|
15864
|
+
const key = models[i].name;
|
|
15865
|
+
if (seen.has(key)) {
|
|
15866
|
+
ctx.addIssue({
|
|
15867
|
+
code: exports_external.ZodIssueCode.custom,
|
|
15868
|
+
path: [i, "name"],
|
|
15869
|
+
message: `duplicate mental_models name "${key}" — model names must be ` + `unique within an agent (they are the idempotent-ensure key)`
|
|
15870
|
+
});
|
|
15871
|
+
}
|
|
15872
|
+
seen.add(key);
|
|
15873
|
+
}
|
|
15874
|
+
}).optional().describe("Operator-declared, per-specialist Hindsight mental models (RFC " + "Phase 5). Named, opt-in curated reflections this agent's bank should " + "carry — e.g. a coach's 'training-plan-state' or a lawyer's " + "'open-matters'. Ensured idempotently at scaffold/reconcile: NOTHING " + "is created unless declared here (zero declarations = zero models, " + "matching post-#2447 behaviour), and no fixed identity model is " + "reintroduced — 'who the user is' stays owned by dedicated profile " + "banks (users.*.profile_bank), never a per-agent model. Per-agent " + "ONLY: intentionally not accepted at the defaults/profile tier, so a " + "model can never be fleet-seeded — each specialist opts in on its own " + "(the invariant-clean inverse of the retired blind auto-seeding)."),
|
|
15875
|
+
observations_mission: exports_external.string().optional().describe("Steers what the observation-consolidation LLM synthesises from raw " + "facts (the higher-order 'what patterns matter' lens). Cascade: override."),
|
|
15876
|
+
disposition: exports_external.object({
|
|
15877
|
+
skepticism: exports_external.number().int().min(1).max(5).optional().describe("How much the bank doubts unverified claims (1-5; engine default 3)."),
|
|
15878
|
+
literalism: exports_external.number().int().min(1).max(5).optional().describe("How literally the bank reads statements vs inferring intent (1-5; engine default 3)."),
|
|
15879
|
+
empathy: exports_external.number().int().min(1).max(5).optional().describe("How much the bank weights emotional/relational context (1-5; engine default 3).")
|
|
15880
|
+
}).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`)."),
|
|
15881
|
+
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)."),
|
|
15855
15882
|
recall: exports_external.object({
|
|
15856
15883
|
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)."),
|
|
15857
15884
|
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."),
|
|
@@ -16116,6 +16143,7 @@ var profileFields = {
|
|
|
16116
16143
|
auto_recall: exports_external.boolean().optional(),
|
|
16117
16144
|
file: exports_external.boolean().optional(),
|
|
16118
16145
|
isolation: exports_external.enum(["default", "strict"]).optional(),
|
|
16146
|
+
directive_capture_nudge: exports_external.boolean().optional(),
|
|
16119
16147
|
recall: exports_external.object({
|
|
16120
16148
|
max_memories: exports_external.number().int().min(0).optional(),
|
|
16121
16149
|
cache_ttl_secs: exports_external.number().int().min(0).optional(),
|
|
@@ -16770,6 +16798,11 @@ function mergeAgentConfig(defaultsIn, agentIn) {
|
|
|
16770
16798
|
continue;
|
|
16771
16799
|
if (k === "recall" && base.recall && typeof v === "object" && v !== null && !Array.isArray(v)) {
|
|
16772
16800
|
combined[k] = { ...base.recall, ...v };
|
|
16801
|
+
} else if (k === "disposition" && base.disposition && typeof v === "object" && v !== null && !Array.isArray(v)) {
|
|
16802
|
+
combined[k] = {
|
|
16803
|
+
...base.disposition,
|
|
16804
|
+
...v
|
|
16805
|
+
};
|
|
16773
16806
|
} else {
|
|
16774
16807
|
combined[k] = v;
|
|
16775
16808
|
}
|
|
@@ -17222,8 +17255,31 @@ function isReservedAgentName(name) {
|
|
|
17222
17255
|
return RESERVED_AGENT_NAMES.has(name);
|
|
17223
17256
|
}
|
|
17224
17257
|
|
|
17258
|
+
// src/setup/hindsight.ts
|
|
17259
|
+
var HINDSIGHT_DEFAULT_API_PORT = 18888;
|
|
17260
|
+
var HINDSIGHT_DEFAULT_MCP_URL = `http://127.0.0.1:${HINDSIGHT_DEFAULT_API_PORT}/mcp/`;
|
|
17261
|
+
var HINDSIGHT_DEFAULT_API_BASE_URL = HINDSIGHT_DEFAULT_MCP_URL.replace(/\/mcp\/?$/, "");
|
|
17262
|
+
var HINDSIGHT_CONSUMER_NAME = "hindsight";
|
|
17263
|
+
var HINDSIGHT_IMAGE_REPO = "ghcr.io/switchroom/switchroom-hindsight";
|
|
17264
|
+
var HINDSIGHT_IMAGE = `${HINDSIGHT_IMAGE_REPO}:latest`;
|
|
17265
|
+
var HINDSIGHT_BROKER_SOCK_VOLUME = `auth-broker-${HINDSIGHT_CONSUMER_NAME}-sock`;
|
|
17266
|
+
var HINDSIGHT_HEALTHCHECK_PY = 'import urllib.request,sys; sys.exit(0 if urllib.request.urlopen("http://localhost:8888/health",timeout=4).getcode()==200 else 1)';
|
|
17267
|
+
var HINDSIGHT_HEALTHCHECK_CMD = `python3 -c '${HINDSIGHT_HEALTHCHECK_PY}'`;
|
|
17268
|
+
|
|
17225
17269
|
// src/memory/hindsight.ts
|
|
17226
17270
|
var DEFAULT_RETAIN_MISSION = "Extract user preferences, ongoing projects, recurring commitments, " + "important context, and durable facts that should help across future " + "conversations. Skip one-off chatter and temporary task noise.";
|
|
17271
|
+
var PROFILE_MEMORY_DEFAULTS = {
|
|
17272
|
+
"health-coach": {
|
|
17273
|
+
disposition: { skepticism: 2, literalism: 2, empathy: 5 },
|
|
17274
|
+
observations_mission: "Synthesise the person's wellbeing patterns, motivations, and emotional " + "context — how habits, setbacks, and encouragement connect over time."
|
|
17275
|
+
},
|
|
17276
|
+
"executive-assistant": {
|
|
17277
|
+
disposition: { skepticism: 4, literalism: 4, empathy: 3 }
|
|
17278
|
+
},
|
|
17279
|
+
coding: {
|
|
17280
|
+
disposition: { skepticism: 4, literalism: 5, empathy: 2 }
|
|
17281
|
+
}
|
|
17282
|
+
};
|
|
17227
17283
|
|
|
17228
17284
|
// src/agents/reconcile-default-skills.ts
|
|
17229
17285
|
var warnedMissingPool = new Set;
|
|
@@ -22670,7 +22726,7 @@ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "node:f
|
|
|
22670
22726
|
import { dirname as dirname4, join as join2 } from "node:path";
|
|
22671
22727
|
|
|
22672
22728
|
// src/build-info.ts
|
|
22673
|
-
var VERSION = "0.17.
|
|
22729
|
+
var VERSION = "0.17.10";
|
|
22674
22730
|
|
|
22675
22731
|
// src/cli/resolve-version.ts
|
|
22676
22732
|
function readPackageVersion() {
|
|
@@ -22800,14 +22856,6 @@ function latestRolloutRowForRequest(raw, requestId) {
|
|
|
22800
22856
|
return latest;
|
|
22801
22857
|
}
|
|
22802
22858
|
|
|
22803
|
-
// src/setup/hindsight.ts
|
|
22804
|
-
var HINDSIGHT_CONSUMER_NAME = "hindsight";
|
|
22805
|
-
var HINDSIGHT_IMAGE_REPO = "ghcr.io/switchroom/switchroom-hindsight";
|
|
22806
|
-
var HINDSIGHT_IMAGE = `${HINDSIGHT_IMAGE_REPO}:latest`;
|
|
22807
|
-
var HINDSIGHT_BROKER_SOCK_VOLUME = `auth-broker-${HINDSIGHT_CONSUMER_NAME}-sock`;
|
|
22808
|
-
var HINDSIGHT_HEALTHCHECK_PY = 'import urllib.request,sys; sys.exit(0 if urllib.request.urlopen("http://localhost:8888/health",timeout=4).getcode()==200 else 1)';
|
|
22809
|
-
var HINDSIGHT_HEALTHCHECK_CMD = `python3 -c '${HINDSIGHT_HEALTHCHECK_PY}'`;
|
|
22810
|
-
|
|
22811
22859
|
// src/cli/rollout.ts
|
|
22812
22860
|
function isVersionAssertable(target) {
|
|
22813
22861
|
return /^v?\d+\.\d+\.\d+$/.test(target.trim());
|
|
@@ -23537,6 +23585,92 @@ function stripCallerAllow(cfg, caller) {
|
|
|
23537
23585
|
}
|
|
23538
23586
|
return clone;
|
|
23539
23587
|
}
|
|
23588
|
+
function assertSelfScopedMentalModelEdit(beforeContent, afterContent, caller) {
|
|
23589
|
+
let before;
|
|
23590
|
+
let after;
|
|
23591
|
+
try {
|
|
23592
|
+
before = toObject(import_yaml5.parseDocument(beforeContent, { merge: false, strict: false }).toJS());
|
|
23593
|
+
after = toObject(import_yaml5.parseDocument(afterContent, { merge: false, strict: false }).toJS());
|
|
23594
|
+
} catch (e) {
|
|
23595
|
+
return { ok: false, detail: `self-scope: config did not parse (${e.message})` };
|
|
23596
|
+
}
|
|
23597
|
+
const beforeModels = readCallerMentalModels(before, caller);
|
|
23598
|
+
const afterByName = new Map;
|
|
23599
|
+
for (const m of readCallerMentalModels(after, caller)) {
|
|
23600
|
+
const n = m && typeof m === "object" ? m.name : undefined;
|
|
23601
|
+
if (typeof n === "string" && !afterByName.has(n))
|
|
23602
|
+
afterByName.set(n, m);
|
|
23603
|
+
}
|
|
23604
|
+
for (const m of beforeModels) {
|
|
23605
|
+
const n = m && typeof m === "object" ? m.name : undefined;
|
|
23606
|
+
if (typeof n !== "string")
|
|
23607
|
+
continue;
|
|
23608
|
+
if (!afterByName.has(n)) {
|
|
23609
|
+
return {
|
|
23610
|
+
ok: false,
|
|
23611
|
+
detail: `self-scope: edit removes existing mental model "${n}" from agents.${caller}.memory.mental_models`
|
|
23612
|
+
};
|
|
23613
|
+
}
|
|
23614
|
+
if (!isDeepStrictEqual(m, afterByName.get(n))) {
|
|
23615
|
+
return {
|
|
23616
|
+
ok: false,
|
|
23617
|
+
detail: `self-scope: edit rewrites existing mental model "${n}" ` + `(append-only: an existing declared model is immutable — only NEW models may be added)`
|
|
23618
|
+
};
|
|
23619
|
+
}
|
|
23620
|
+
}
|
|
23621
|
+
const beforeStripped = stripCallerMentalModels(before, caller);
|
|
23622
|
+
const afterStripped = stripCallerMentalModels(after, caller);
|
|
23623
|
+
if (!isDeepStrictEqual(beforeStripped, afterStripped)) {
|
|
23624
|
+
return {
|
|
23625
|
+
ok: false,
|
|
23626
|
+
detail: `self-scope: edit changes config outside agents.${caller}.memory.mental_models ` + `(a non-admin agent may only append its own declared mental models)`
|
|
23627
|
+
};
|
|
23628
|
+
}
|
|
23629
|
+
return { ok: true };
|
|
23630
|
+
}
|
|
23631
|
+
function admitSelfScopedNonAdminEdit(beforeContent, afterContent, caller) {
|
|
23632
|
+
const allowScope = assertSelfScopedAllowEdit(beforeContent, afterContent, caller);
|
|
23633
|
+
if (allowScope.ok)
|
|
23634
|
+
return { ok: true, via: "tools.allow" };
|
|
23635
|
+
const mentalModelScope = assertSelfScopedMentalModelEdit(beforeContent, afterContent, caller);
|
|
23636
|
+
if (mentalModelScope.ok)
|
|
23637
|
+
return { ok: true, via: "mental_models" };
|
|
23638
|
+
return {
|
|
23639
|
+
ok: false,
|
|
23640
|
+
detail: allowScope.detail,
|
|
23641
|
+
mentalModelDetail: mentalModelScope.detail
|
|
23642
|
+
};
|
|
23643
|
+
}
|
|
23644
|
+
function readCallerMentalModels(cfg, caller) {
|
|
23645
|
+
const agents = cfg.agents;
|
|
23646
|
+
if (!agents || typeof agents !== "object")
|
|
23647
|
+
return [];
|
|
23648
|
+
const agent = agents[caller];
|
|
23649
|
+
if (!agent || typeof agent !== "object")
|
|
23650
|
+
return [];
|
|
23651
|
+
const memory = agent.memory;
|
|
23652
|
+
if (!memory || typeof memory !== "object")
|
|
23653
|
+
return [];
|
|
23654
|
+
const models = memory.mental_models;
|
|
23655
|
+
return Array.isArray(models) ? models : [];
|
|
23656
|
+
}
|
|
23657
|
+
function stripCallerMentalModels(cfg, caller) {
|
|
23658
|
+
const clone = structuredClone(cfg);
|
|
23659
|
+
const agents = clone.agents;
|
|
23660
|
+
if (!agents || typeof agents !== "object")
|
|
23661
|
+
return clone;
|
|
23662
|
+
const agent = agents[caller];
|
|
23663
|
+
if (!agent || typeof agent !== "object")
|
|
23664
|
+
return clone;
|
|
23665
|
+
const memory = agent.memory;
|
|
23666
|
+
if (!memory || typeof memory !== "object")
|
|
23667
|
+
return clone;
|
|
23668
|
+
delete memory.mental_models;
|
|
23669
|
+
if (Object.keys(memory).length === 0) {
|
|
23670
|
+
delete agent.memory;
|
|
23671
|
+
}
|
|
23672
|
+
return clone;
|
|
23673
|
+
}
|
|
23540
23674
|
|
|
23541
23675
|
// src/host-control/config-blast-radius.ts
|
|
23542
23676
|
var import_yaml6 = __toESM(require_dist(), 1);
|
|
@@ -24699,9 +24833,9 @@ class HostdServer {
|
|
|
24699
24833
|
} catch {
|
|
24700
24834
|
beforeContent = "";
|
|
24701
24835
|
}
|
|
24702
|
-
const
|
|
24703
|
-
if (!
|
|
24704
|
-
return err("E_NOT_SELF_SCOPED",
|
|
24836
|
+
const admission = admitSelfScopedNonAdminEdit(beforeContent, verdict.postApplyContent, caller.name);
|
|
24837
|
+
if (!admission.ok) {
|
|
24838
|
+
return err("E_NOT_SELF_SCOPED", admission.detail).why("non-admin agents may only add rules to their own " + "agents.<self>.tools.allow OR append their own " + "agents.<self>.memory.mental_models via config_propose_edit " + `(mental-model check: ${admission.mentalModelDetail})`).fixBadInput("unified_diff").op("config_propose_edit").caller("agent").agentName(caller.name).asDenied().build(req.request_id, Date.now() - started);
|
|
24705
24839
|
}
|
|
24706
24840
|
}
|
|
24707
24841
|
if (!this.opts.approvalGateway) {
|
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
2
4
|
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
12
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
|
+
for (let key of __getOwnPropNames(mod))
|
|
23
|
+
if (!__hasOwnProp.call(to, key))
|
|
24
|
+
__defProp(to, key, {
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
26
|
+
enumerable: true
|
|
27
|
+
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
30
|
+
return to;
|
|
31
|
+
};
|
|
3
32
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
4
33
|
var __returnValue = (v) => v;
|
|
5
34
|
function __exportSetter(name, newValue) {
|
|
@@ -4098,8 +4127,35 @@ var init_schema = __esm(() => {
|
|
|
4098
4127
|
auto_recall: exports_external.boolean().default(true).describe("Auto-search memories before each response"),
|
|
4099
4128
|
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)."),
|
|
4100
4129
|
isolation: exports_external.enum(["default", "strict"]).default("default").describe("strict = never shared cross-agent, default = eligible for reflect"),
|
|
4101
|
-
bank_mission: exports_external.string().optional().describe("Bank-level mission statement used during recall to contextualize results"),
|
|
4102
|
-
|
|
4130
|
+
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."),
|
|
4131
|
+
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."),
|
|
4132
|
+
retain_mission: exports_external.string().optional().describe("Instructions for the fact extraction LLM during retain. Cascade: override."),
|
|
4133
|
+
mental_models: exports_external.array(exports_external.object({
|
|
4134
|
+
name: exports_external.string().min(1).describe("Stable model name (identity key for idempotent ensure). Two " + "declarations with the same name in one agent are rejected."),
|
|
4135
|
+
source_query: exports_external.string().min(1).max(2000).describe("The reflection query the model answers, semantically " + "refreshed from the bank's content. Capped at 2000 chars — a " + "standing reflection query, not a document; the ceiling also " + "bounds what an agent-proposed model can smuggle past the " + "operator approval card."),
|
|
4136
|
+
refresh_after_consolidation: exports_external.boolean().optional().describe("Refresh this model after each consolidation. Defaults OFF — " + "refresh adds bounded background model-spend + timeout risk " + "(RFC Phase 5), so it is opt-in per model."),
|
|
4137
|
+
max_tokens: exports_external.number().int().positive().max(8192).optional().describe("Cap on the synthesized model's token size. Upper-bounded at " + "8192 — a mental model is a standing summary, not a corpus; the " + "ceiling also caps what an agent-proposed model can request.")
|
|
4138
|
+
})).superRefine((models, ctx) => {
|
|
4139
|
+
const seen = new Set;
|
|
4140
|
+
for (let i = 0;i < models.length; i++) {
|
|
4141
|
+
const key = models[i].name;
|
|
4142
|
+
if (seen.has(key)) {
|
|
4143
|
+
ctx.addIssue({
|
|
4144
|
+
code: exports_external.ZodIssueCode.custom,
|
|
4145
|
+
path: [i, "name"],
|
|
4146
|
+
message: `duplicate mental_models name "${key}" — model names must be ` + `unique within an agent (they are the idempotent-ensure key)`
|
|
4147
|
+
});
|
|
4148
|
+
}
|
|
4149
|
+
seen.add(key);
|
|
4150
|
+
}
|
|
4151
|
+
}).optional().describe("Operator-declared, per-specialist Hindsight mental models (RFC " + "Phase 5). Named, opt-in curated reflections this agent's bank should " + "carry — e.g. a coach's 'training-plan-state' or a lawyer's " + "'open-matters'. Ensured idempotently at scaffold/reconcile: NOTHING " + "is created unless declared here (zero declarations = zero models, " + "matching post-#2447 behaviour), and no fixed identity model is " + "reintroduced — 'who the user is' stays owned by dedicated profile " + "banks (users.*.profile_bank), never a per-agent model. Per-agent " + "ONLY: intentionally not accepted at the defaults/profile tier, so a " + "model can never be fleet-seeded — each specialist opts in on its own " + "(the invariant-clean inverse of the retired blind auto-seeding)."),
|
|
4152
|
+
observations_mission: exports_external.string().optional().describe("Steers what the observation-consolidation LLM synthesises from raw " + "facts (the higher-order 'what patterns matter' lens). Cascade: override."),
|
|
4153
|
+
disposition: exports_external.object({
|
|
4154
|
+
skepticism: exports_external.number().int().min(1).max(5).optional().describe("How much the bank doubts unverified claims (1-5; engine default 3)."),
|
|
4155
|
+
literalism: exports_external.number().int().min(1).max(5).optional().describe("How literally the bank reads statements vs inferring intent (1-5; engine default 3)."),
|
|
4156
|
+
empathy: exports_external.number().int().min(1).max(5).optional().describe("How much the bank weights emotional/relational context (1-5; engine default 3).")
|
|
4157
|
+
}).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`)."),
|
|
4158
|
+
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)."),
|
|
4103
4159
|
recall: exports_external.object({
|
|
4104
4160
|
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)."),
|
|
4105
4161
|
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."),
|
|
@@ -4364,6 +4420,7 @@ var init_schema = __esm(() => {
|
|
|
4364
4420
|
auto_recall: exports_external.boolean().optional(),
|
|
4365
4421
|
file: exports_external.boolean().optional(),
|
|
4366
4422
|
isolation: exports_external.enum(["default", "strict"]).optional(),
|
|
4423
|
+
directive_capture_nudge: exports_external.boolean().optional(),
|
|
4367
4424
|
recall: exports_external.object({
|
|
4368
4425
|
max_memories: exports_external.number().int().min(0).optional(),
|
|
4369
4426
|
cache_ttl_secs: exports_external.number().int().min(0).optional(),
|
|
@@ -4827,6 +4884,11 @@ function mergeAgentConfig(defaultsIn, agentIn) {
|
|
|
4827
4884
|
continue;
|
|
4828
4885
|
if (k === "recall" && base.recall && typeof v === "object" && v !== null && !Array.isArray(v)) {
|
|
4829
4886
|
combined[k] = { ...base.recall, ...v };
|
|
4887
|
+
} else if (k === "disposition" && base.disposition && typeof v === "object" && v !== null && !Array.isArray(v)) {
|
|
4888
|
+
combined[k] = {
|
|
4889
|
+
...base.disposition,
|
|
4890
|
+
...v
|
|
4891
|
+
};
|
|
4830
4892
|
} else {
|
|
4831
4893
|
combined[k] = v;
|
|
4832
4894
|
}
|
|
@@ -11999,52 +12061,52 @@ var require_public_api = __commonJS((exports) => {
|
|
|
11999
12061
|
});
|
|
12000
12062
|
|
|
12001
12063
|
// node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/index.js
|
|
12002
|
-
var
|
|
12003
|
-
var
|
|
12004
|
-
|
|
12005
|
-
|
|
12006
|
-
|
|
12007
|
-
|
|
12008
|
-
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
|
|
12012
|
-
|
|
12013
|
-
|
|
12014
|
-
|
|
12015
|
-
|
|
12016
|
-
|
|
12017
|
-
|
|
12018
|
-
|
|
12019
|
-
|
|
12020
|
-
|
|
12021
|
-
|
|
12022
|
-
|
|
12023
|
-
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
|
|
12027
|
-
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
|
|
12031
|
-
|
|
12032
|
-
|
|
12033
|
-
|
|
12034
|
-
|
|
12035
|
-
|
|
12036
|
-
|
|
12037
|
-
|
|
12038
|
-
|
|
12039
|
-
|
|
12040
|
-
|
|
12041
|
-
|
|
12042
|
-
|
|
12043
|
-
|
|
12044
|
-
|
|
12045
|
-
|
|
12046
|
-
|
|
12047
|
-
|
|
12064
|
+
var require_dist = __commonJS((exports) => {
|
|
12065
|
+
var composer = require_composer();
|
|
12066
|
+
var Document = require_Document();
|
|
12067
|
+
var Schema = require_Schema();
|
|
12068
|
+
var errors2 = require_errors();
|
|
12069
|
+
var Alias = require_Alias();
|
|
12070
|
+
var identity = require_identity();
|
|
12071
|
+
var Pair = require_Pair();
|
|
12072
|
+
var Scalar = require_Scalar();
|
|
12073
|
+
var YAMLMap = require_YAMLMap();
|
|
12074
|
+
var YAMLSeq = require_YAMLSeq();
|
|
12075
|
+
var cst = require_cst();
|
|
12076
|
+
var lexer = require_lexer();
|
|
12077
|
+
var lineCounter = require_line_counter();
|
|
12078
|
+
var parser = require_parser();
|
|
12079
|
+
var publicApi = require_public_api();
|
|
12080
|
+
var visit = require_visit();
|
|
12081
|
+
exports.Composer = composer.Composer;
|
|
12082
|
+
exports.Document = Document.Document;
|
|
12083
|
+
exports.Schema = Schema.Schema;
|
|
12084
|
+
exports.YAMLError = errors2.YAMLError;
|
|
12085
|
+
exports.YAMLParseError = errors2.YAMLParseError;
|
|
12086
|
+
exports.YAMLWarning = errors2.YAMLWarning;
|
|
12087
|
+
exports.Alias = Alias.Alias;
|
|
12088
|
+
exports.isAlias = identity.isAlias;
|
|
12089
|
+
exports.isCollection = identity.isCollection;
|
|
12090
|
+
exports.isDocument = identity.isDocument;
|
|
12091
|
+
exports.isMap = identity.isMap;
|
|
12092
|
+
exports.isNode = identity.isNode;
|
|
12093
|
+
exports.isPair = identity.isPair;
|
|
12094
|
+
exports.isScalar = identity.isScalar;
|
|
12095
|
+
exports.isSeq = identity.isSeq;
|
|
12096
|
+
exports.Pair = Pair.Pair;
|
|
12097
|
+
exports.Scalar = Scalar.Scalar;
|
|
12098
|
+
exports.YAMLMap = YAMLMap.YAMLMap;
|
|
12099
|
+
exports.YAMLSeq = YAMLSeq.YAMLSeq;
|
|
12100
|
+
exports.CST = cst;
|
|
12101
|
+
exports.Lexer = lexer.Lexer;
|
|
12102
|
+
exports.LineCounter = lineCounter.LineCounter;
|
|
12103
|
+
exports.Parser = parser.Parser;
|
|
12104
|
+
exports.parse = publicApi.parse;
|
|
12105
|
+
exports.parseAllDocuments = publicApi.parseAllDocuments;
|
|
12106
|
+
exports.parseDocument = publicApi.parseDocument;
|
|
12107
|
+
exports.stringify = publicApi.stringify;
|
|
12108
|
+
exports.visit = visit.visit;
|
|
12109
|
+
exports.visitAsync = visit.visitAsync;
|
|
12048
12110
|
});
|
|
12049
12111
|
|
|
12050
12112
|
// src/config/overlay-schema.ts
|
|
@@ -12124,7 +12186,7 @@ function applyAgentOverlays(config) {
|
|
|
12124
12186
|
for (const file of files) {
|
|
12125
12187
|
try {
|
|
12126
12188
|
const raw = readFileSync(file, "utf-8");
|
|
12127
|
-
const parsed =
|
|
12189
|
+
const parsed = import_yaml.parse(raw);
|
|
12128
12190
|
const doc = OverlayDocSchema.parse(parsed);
|
|
12129
12191
|
const title = deriveOverlayTitle(raw, basename(file));
|
|
12130
12192
|
for (const entry of doc.schedule ?? []) {
|
|
@@ -12165,7 +12227,7 @@ function applyAgentOverlays(config) {
|
|
|
12165
12227
|
for (const file of skillFiles) {
|
|
12166
12228
|
try {
|
|
12167
12229
|
const raw = readFileSync(file, "utf-8");
|
|
12168
|
-
const parsed =
|
|
12230
|
+
const parsed = import_yaml.parse(raw);
|
|
12169
12231
|
const doc = OverlayDocSchema.parse(parsed);
|
|
12170
12232
|
for (const skillName of doc.skills ?? []) {
|
|
12171
12233
|
if (seen.has(skillName))
|
|
@@ -12192,12 +12254,12 @@ function applyAgentOverlays(config) {
|
|
|
12192
12254
|
}
|
|
12193
12255
|
return { config, warnings };
|
|
12194
12256
|
}
|
|
12195
|
-
var OVERLAY_SOURCE, OVERLAY_TITLE;
|
|
12257
|
+
var import_yaml, OVERLAY_SOURCE, OVERLAY_TITLE;
|
|
12196
12258
|
var init_overlay_loader = __esm(() => {
|
|
12197
|
-
init_dist();
|
|
12198
12259
|
init_zod();
|
|
12199
12260
|
init_overlay_schema();
|
|
12200
12261
|
init_paths();
|
|
12262
|
+
import_yaml = __toESM(require_dist(), 1);
|
|
12201
12263
|
OVERLAY_SOURCE = Symbol.for("switchroom.config.overlay-source");
|
|
12202
12264
|
OVERLAY_TITLE = Symbol.for("switchroom.config.overlay-title");
|
|
12203
12265
|
});
|
|
@@ -12327,7 +12389,7 @@ function loadConfig(configPath) {
|
|
|
12327
12389
|
}
|
|
12328
12390
|
let parsed;
|
|
12329
12391
|
try {
|
|
12330
|
-
parsed =
|
|
12392
|
+
parsed = import_yaml2.parse(raw);
|
|
12331
12393
|
} catch (err) {
|
|
12332
12394
|
throw new ConfigError(`Invalid YAML in ${filePath}`, [
|
|
12333
12395
|
` ${err.message}`
|
|
@@ -12393,14 +12455,14 @@ function resolveAgentsDir(config) {
|
|
|
12393
12455
|
function resolvePath(pathStr) {
|
|
12394
12456
|
return resolveDualPath(pathStr);
|
|
12395
12457
|
}
|
|
12396
|
-
var ConfigError;
|
|
12458
|
+
var import_yaml2, ConfigError;
|
|
12397
12459
|
var init_loader = __esm(() => {
|
|
12398
|
-
init_dist();
|
|
12399
12460
|
init_zod();
|
|
12400
12461
|
init_schema();
|
|
12401
12462
|
init_paths();
|
|
12402
12463
|
init_overlay_loader();
|
|
12403
12464
|
init_merge();
|
|
12465
|
+
import_yaml2 = __toESM(require_dist(), 1);
|
|
12404
12466
|
ConfigError = class ConfigError extends Error {
|
|
12405
12467
|
details;
|
|
12406
12468
|
constructor(message, details) {
|
|
@@ -13195,8 +13257,31 @@ var CONTAINER_DEFAULT_UTC_ZONES = new Set([
|
|
|
13195
13257
|
// src/config/users.ts
|
|
13196
13258
|
init_merge();
|
|
13197
13259
|
|
|
13260
|
+
// src/setup/hindsight.ts
|
|
13261
|
+
var HINDSIGHT_DEFAULT_API_PORT = 18888;
|
|
13262
|
+
var HINDSIGHT_DEFAULT_MCP_URL = `http://127.0.0.1:${HINDSIGHT_DEFAULT_API_PORT}/mcp/`;
|
|
13263
|
+
var HINDSIGHT_DEFAULT_API_BASE_URL = HINDSIGHT_DEFAULT_MCP_URL.replace(/\/mcp\/?$/, "");
|
|
13264
|
+
var HINDSIGHT_CONSUMER_NAME = "hindsight";
|
|
13265
|
+
var HINDSIGHT_IMAGE_REPO = "ghcr.io/switchroom/switchroom-hindsight";
|
|
13266
|
+
var HINDSIGHT_IMAGE = `${HINDSIGHT_IMAGE_REPO}:latest`;
|
|
13267
|
+
var HINDSIGHT_BROKER_SOCK_VOLUME = `auth-broker-${HINDSIGHT_CONSUMER_NAME}-sock`;
|
|
13268
|
+
var HINDSIGHT_HEALTHCHECK_PY = 'import urllib.request,sys; sys.exit(0 if urllib.request.urlopen("http://localhost:8888/health",timeout=4).getcode()==200 else 1)';
|
|
13269
|
+
var HINDSIGHT_HEALTHCHECK_CMD = `python3 -c '${HINDSIGHT_HEALTHCHECK_PY}'`;
|
|
13270
|
+
|
|
13198
13271
|
// src/memory/hindsight.ts
|
|
13199
13272
|
var DEFAULT_RETAIN_MISSION = "Extract user preferences, ongoing projects, recurring commitments, " + "important context, and durable facts that should help across future " + "conversations. Skip one-off chatter and temporary task noise.";
|
|
13273
|
+
var PROFILE_MEMORY_DEFAULTS = {
|
|
13274
|
+
"health-coach": {
|
|
13275
|
+
disposition: { skepticism: 2, literalism: 2, empathy: 5 },
|
|
13276
|
+
observations_mission: "Synthesise the person's wellbeing patterns, motivations, and emotional " + "context — how habits, setbacks, and encouragement connect over time."
|
|
13277
|
+
},
|
|
13278
|
+
"executive-assistant": {
|
|
13279
|
+
disposition: { skepticism: 4, literalism: 4, empathy: 3 }
|
|
13280
|
+
},
|
|
13281
|
+
coding: {
|
|
13282
|
+
disposition: { skepticism: 4, literalism: 5, empathy: 2 }
|
|
13283
|
+
}
|
|
13284
|
+
};
|
|
13200
13285
|
|
|
13201
13286
|
// src/agents/reconcile-default-skills.ts
|
|
13202
13287
|
var warnedMissingPool = new Set;
|