switchroom 0.19.40 → 0.19.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-scheduler/index.js +22 -2
- package/dist/auth-broker/index.js +22 -2
- package/dist/cli/notion-write-pretool.mjs +22 -2
- package/dist/cli/switchroom.js +810 -241
- package/dist/host-control/main.js +94 -19
- package/dist/vault/approvals/kernel-server.js +22 -2
- package/dist/vault/broker/server.js +22 -2
- package/package.json +1 -1
- package/telegram-plugin/bridge/bridge.ts +2 -2
- package/telegram-plugin/dist/bridge/bridge.js +2 -2
- package/telegram-plugin/dist/gateway/gateway.js +332 -124
- package/telegram-plugin/dist/server.js +2 -2
- package/telegram-plugin/gateway/approval-callback-consume-record.test.ts +132 -0
- package/telegram-plugin/gateway/checklist-fallback.ts +370 -0
- package/telegram-plugin/gateway/gateway.ts +76 -76
- package/telegram-plugin/gateway/liveness-wiring.ts +12 -0
- package/telegram-plugin/gateway/model-command.ts +21 -109
- package/telegram-plugin/gateway/stream-render.ts +57 -0
- package/telegram-plugin/gateway/turn-record-status.ts +80 -0
- package/telegram-plugin/tests/checklist-fallback.test.ts +317 -0
- package/telegram-plugin/tests/framework-fallback-drains-parked.test.ts +134 -0
- package/telegram-plugin/tests/gateway-outbound-redact.test.ts +10 -6
- package/telegram-plugin/tests/helpers/liveness-wiring-fixture.ts +3 -0
- package/telegram-plugin/tests/turn-record-status.test.ts +62 -0
- 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
|
@@ -14354,11 +14354,11 @@ var init_protocol2 = __esm(() => {
|
|
|
14354
14354
|
OkRevokeGrantResponseSchema,
|
|
14355
14355
|
OkApprovalRequestResponseSchema,
|
|
14356
14356
|
OkApprovalLookupResponseSchema,
|
|
14357
|
+
OkApprovalConsumeRecordResponseSchema,
|
|
14357
14358
|
OkApprovalConsumeResponseSchema,
|
|
14358
14359
|
OkApprovalRevokeResponseSchema,
|
|
14359
14360
|
OkApprovalListResponseSchema,
|
|
14360
14361
|
OkApprovalRecordResponseSchema,
|
|
14361
|
-
OkApprovalConsumeRecordResponseSchema,
|
|
14362
14362
|
ErrorResponseSchema2
|
|
14363
14363
|
]);
|
|
14364
14364
|
});
|
|
@@ -21865,6 +21865,7 @@ var init_schema = __esm(() => {
|
|
|
21865
21865
|
auto_recall: exports_external.boolean().default(true).describe("Auto-search memories before each response"),
|
|
21866
21866
|
file: exports_external.boolean().default(true).describe("Maintain a curated workspace MEMORY.md file (seeded once, " + "auto-loaded every turn). Set false for hindsight-only memory: " + "the file is not seeded or re-created, so once migrated into " + "Hindsight and deleted it stays gone. Recall + directives carry " + "the memory instead. Cascade: override (per-agent wins over default)."),
|
|
21867
21867
|
isolation: exports_external.enum(["default", "strict"]).default("default").describe("strict = never shared cross-agent, default = eligible for reflect"),
|
|
21868
|
+
profile: exports_external.string().optional().describe("Memory profile bank this agent's curated memory defaults key off \u2014 " + "the built-in disposition + observations_mission in PROFILE_MEMORY_DEFAULTS. " + "Decouples the memory profile from `extends` (the filesystem persona " + "profile), so an agent on `extends: default` can opt into the `coding` " + "memory bundle via `memory.profile: coding` without inheriting the coding " + "persona. Resolution: memory.profile \u2192 extends \u2192 DEFAULT_PROFILE (see " + "resolveMemoryProfile). Unset \u21d2 byte-identical to keying off `extends`."),
|
|
21868
21869
|
bank_mission: exports_external.string().optional().describe("Bank-level mission statement used during recall to contextualize " + "results. NOTE: this is an alias for the Hindsight engine's " + "`reflect_mission` field (verified live: switchroom's bank_mission " + "lands in `config.reflect_mission`). Prefer `reflect_mission` going " + "forward; `bank_mission` is retained for back-compat. If both are " + "set, `reflect_mission` wins. Cascade: override."),
|
|
21869
21870
|
reflect_mission: exports_external.string().optional().describe("Mission/context steering Hindsight Reflect operations (the bank's " + "'who am I / what matters' framing applied during recall). The " + "engine-accurate name for what `bank_mission` sets. Cascade: override."),
|
|
21870
21871
|
retain_mission: exports_external.string().optional().describe("Instructions for the fact extraction LLM during retain. Cascade: override."),
|
|
@@ -22158,6 +22159,8 @@ var init_schema = __esm(() => {
|
|
|
22158
22159
|
provider: exports_external.string().min(1).optional().describe("Hindsight LLM provider (upstream `HINDSIGHT_API_LLM_PROVIDER`). " + "Defaults to `claude-code` (subscription-honest, broker-fed OAuth). " + "Any litellm-routable provider the upstream image supports is valid. " + "Serves as the GLOBAL default for every op absent a per-op override."),
|
|
22159
22160
|
model: exports_external.string().min(1).optional().describe("Hindsight LLM model (upstream `HINDSIGHT_API_LLM_MODEL`). Defaults " + "to HINDSIGHT_DEFAULT_MODEL. Any model your LiteLLM proxy can route " + "is valid, e.g. `openrouter/z-ai/glm-5.2` when routing through the " + "fleet proxy. With provider=claude-code this value is ALSO exported " + "as `ANTHROPIC_MODEL` to the claude subprocess. Serves as the GLOBAL " + "default for every op absent a per-op override."),
|
|
22160
22161
|
context_window: exports_external.number().int().positive().optional().describe("GLOBAL context window (tokens) of the backend serving hindsight's " + "LLM ops \u2014 the declared size switchroom derives every token budget " + "from. Set this to the real window of whatever you point " + "`hindsight.llm` at (e.g. 32768 for a llama.cpp slot launched with " + "`-c 65536 -np 2`, 131072 for a large-window OpenRouter model). " + "Absent \u2192 a per-provider default: 200000 for `claude-code`, a " + "conservative 32768 for everything else. Overflowing a local " + "backend's window does NOT error \u2014 llama.cpp context-shift silently " + "drops the system prompt and the model answers conversationally " + "with HTTP 200 \u2014 so this value is what makes the failure " + "detectable at setup time instead of never."),
|
|
22162
|
+
base_url: exports_external.string().min(1).optional().describe("GLOBAL LLM base URL (upstream `HINDSIGHT_API_LLM_BASE_URL`). The " + "default endpoint every op inherits absent a per-op " + "`hindsight.llm.<op>.base_url`. Optional passthrough; unset \u2192 the " + "engine's provider default. When this points at host loopback the " + "hindsight container is forced onto host networking, same as a " + "per-op base URL, so the endpoint stays reachable (#3687)."),
|
|
22163
|
+
api_key: exports_external.string().min(1).optional().describe("GLOBAL LLM API key (upstream `HINDSIGHT_API_LLM_API_KEY`). Literal " + "or `vault:` reference. The default credential every op inherits " + "absent a per-op `hindsight.llm.<op>.api_key`; the engine reads it as " + "a plain env fallback. Optional passthrough (#3687)."),
|
|
22161
22164
|
retain: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `retain` LLM op (memory ingestion). Emits " + "`HINDSIGHT_API_RETAIN_LLM_*`. Absent \u2192 uses the global model/provider."),
|
|
22162
22165
|
reflect: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `reflect` LLM op (synthesis / mental-model " + "refresh). Emits `HINDSIGHT_API_REFLECT_LLM_*`. Absent \u2192 uses global."),
|
|
22163
22166
|
consolidation: HindsightPerOpLlmSchema.optional().describe("Per-op override for the `consolidation` LLM op (background memory " + "merge). Emits `HINDSIGHT_API_CONSOLIDATION_LLM_*`. Absent \u2192 global.")
|
|
@@ -22294,6 +22297,7 @@ var init_schema = __esm(() => {
|
|
|
22294
22297
|
auto_recall: exports_external.boolean().optional(),
|
|
22295
22298
|
file: exports_external.boolean().optional(),
|
|
22296
22299
|
isolation: exports_external.enum(["default", "strict"]).optional(),
|
|
22300
|
+
profile: exports_external.string().optional(),
|
|
22297
22301
|
directive_capture_nudge: exports_external.boolean().optional(),
|
|
22298
22302
|
observation_scopes: ObservationScopesSchema,
|
|
22299
22303
|
observation_scope_strategy: ObservationScopeStrategySchema,
|
|
@@ -22335,7 +22339,23 @@ var init_schema = __esm(() => {
|
|
|
22335
22339
|
max_query_chars: exports_external.number().int().min(1).optional(),
|
|
22336
22340
|
parallel: exports_external.boolean().optional(),
|
|
22337
22341
|
additional_banks: exports_external.array(exports_external.string()).optional(),
|
|
22338
|
-
sender_banks: exports_external.record(exports_external.string(), exports_external.string()).optional()
|
|
22342
|
+
sender_banks: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
22343
|
+
types: exports_external.array(exports_external.string()).optional(),
|
|
22344
|
+
skip_trivial: exports_external.boolean().optional(),
|
|
22345
|
+
topic_filter_mode: exports_external.enum(["soft-preamble", "hard-filter"]).optional()
|
|
22346
|
+
}).optional(),
|
|
22347
|
+
retain: exports_external.object({
|
|
22348
|
+
every_n_turns: exports_external.number().int().min(1).optional(),
|
|
22349
|
+
overlap_turns: exports_external.number().int().min(0).optional()
|
|
22350
|
+
}).optional(),
|
|
22351
|
+
bank_mission: exports_external.string().optional(),
|
|
22352
|
+
reflect_mission: exports_external.string().optional(),
|
|
22353
|
+
retain_mission: exports_external.string().optional(),
|
|
22354
|
+
observations_mission: exports_external.string().optional(),
|
|
22355
|
+
disposition: exports_external.object({
|
|
22356
|
+
skepticism: exports_external.number().int().min(1).max(5).optional(),
|
|
22357
|
+
literalism: exports_external.number().int().min(1).max(5).optional(),
|
|
22358
|
+
empathy: exports_external.number().int().min(1).max(5).optional()
|
|
22339
22359
|
}).optional()
|
|
22340
22360
|
}).optional(),
|
|
22341
22361
|
schedule: exports_external.array(ScheduleEntrySchema).optional(),
|
|
@@ -39504,6 +39524,178 @@ function redactChecklistFields(title, tasks, redact) {
|
|
|
39504
39524
|
};
|
|
39505
39525
|
}
|
|
39506
39526
|
|
|
39527
|
+
// gateway/checklist-fallback.ts
|
|
39528
|
+
var CHECKLIST_MAX_TASKS = 30;
|
|
39529
|
+
function buildChecklistTasks(tasks) {
|
|
39530
|
+
if (tasks.length > CHECKLIST_MAX_TASKS) {
|
|
39531
|
+
throw new Error(`checklist exceeds ${CHECKLIST_MAX_TASKS}-task limit (got ${tasks.length})`);
|
|
39532
|
+
}
|
|
39533
|
+
return tasks.map((t, i) => ({ id: i + 1, text: t.text, done: t.done === true }));
|
|
39534
|
+
}
|
|
39535
|
+
function renderChecklistText(cl, opts) {
|
|
39536
|
+
const header = opts?.literal ? cl.title : `**${cl.title}**`;
|
|
39537
|
+
const lines = cl.tasks.map((t) => `${t.done ? "\u2705" : "\u2b1c"} ${t.text}`);
|
|
39538
|
+
return [header, ...lines].join(`
|
|
39539
|
+
`);
|
|
39540
|
+
}
|
|
39541
|
+
function applyChecklistPatch(cl, patch) {
|
|
39542
|
+
const tasks = cl.tasks.map((t) => ({ ...t }));
|
|
39543
|
+
for (const p of patch.tasks ?? []) {
|
|
39544
|
+
const pid = p.id != null ? Number(p.id) : undefined;
|
|
39545
|
+
const existing = pid != null ? tasks.find((t) => t.id === pid) : undefined;
|
|
39546
|
+
if (existing) {
|
|
39547
|
+
if (p.text != null)
|
|
39548
|
+
existing.text = p.text;
|
|
39549
|
+
if (p.done != null)
|
|
39550
|
+
existing.done = p.done;
|
|
39551
|
+
} else {
|
|
39552
|
+
const nextId = pid != null && Number.isFinite(pid) ? pid : tasks.reduce((m, t) => Math.max(m, t.id), 0) + 1;
|
|
39553
|
+
tasks.push({ id: nextId, text: p.text ?? "", done: p.done === true });
|
|
39554
|
+
}
|
|
39555
|
+
}
|
|
39556
|
+
if (tasks.length > CHECKLIST_MAX_TASKS) {
|
|
39557
|
+
throw new Error(`checklist exceeds ${CHECKLIST_MAX_TASKS}-task limit (got ${tasks.length})`);
|
|
39558
|
+
}
|
|
39559
|
+
return { title: patch.title ?? cl.title, tasks };
|
|
39560
|
+
}
|
|
39561
|
+
function buildNativeChecklistPayload(p) {
|
|
39562
|
+
return {
|
|
39563
|
+
business_connection_id: p.businessConnectionId,
|
|
39564
|
+
chat_id: p.chatId,
|
|
39565
|
+
checklist: {
|
|
39566
|
+
title: p.title,
|
|
39567
|
+
tasks: p.tasks.map((t) => ({ id: t.id, text: t.text }))
|
|
39568
|
+
},
|
|
39569
|
+
...p.replyToMessageId != null ? { reply_parameters: { message_id: p.replyToMessageId } } : {},
|
|
39570
|
+
...p.protectContent === true ? { protect_content: true } : {}
|
|
39571
|
+
};
|
|
39572
|
+
}
|
|
39573
|
+
function buildNativeEditChecklistPayload(p) {
|
|
39574
|
+
return {
|
|
39575
|
+
business_connection_id: p.businessConnectionId,
|
|
39576
|
+
chat_id: p.chatId,
|
|
39577
|
+
message_id: p.messageId,
|
|
39578
|
+
checklist: {
|
|
39579
|
+
title: p.title,
|
|
39580
|
+
tasks: p.tasks.map((t) => ({ id: t.id, text: t.text }))
|
|
39581
|
+
}
|
|
39582
|
+
};
|
|
39583
|
+
}
|
|
39584
|
+
function createChecklistStore(cap = 500) {
|
|
39585
|
+
const map = new Map;
|
|
39586
|
+
return {
|
|
39587
|
+
get: (key) => map.get(key),
|
|
39588
|
+
set: (key, state) => {
|
|
39589
|
+
if (map.has(key))
|
|
39590
|
+
map.delete(key);
|
|
39591
|
+
map.set(key, state);
|
|
39592
|
+
while (map.size > cap) {
|
|
39593
|
+
const oldest = map.keys().next().value;
|
|
39594
|
+
if (oldest == null)
|
|
39595
|
+
break;
|
|
39596
|
+
map.delete(oldest);
|
|
39597
|
+
}
|
|
39598
|
+
}
|
|
39599
|
+
};
|
|
39600
|
+
}
|
|
39601
|
+
function checklistStoreKey(chatId, messageId) {
|
|
39602
|
+
return `${chatId}:${messageId}`;
|
|
39603
|
+
}
|
|
39604
|
+
async function performSendChecklist(deps, args) {
|
|
39605
|
+
const tasks = buildChecklistTasks(args.tasks);
|
|
39606
|
+
if (deps.nativeAvailable && deps.businessConnectionId) {
|
|
39607
|
+
try {
|
|
39608
|
+
const sent2 = await deps.sendNative(buildNativeChecklistPayload({
|
|
39609
|
+
businessConnectionId: deps.businessConnectionId,
|
|
39610
|
+
chatId: args.chatId,
|
|
39611
|
+
title: args.title,
|
|
39612
|
+
tasks,
|
|
39613
|
+
replyToMessageId: args.replyToMessageId,
|
|
39614
|
+
protectContent: args.protectContent
|
|
39615
|
+
}));
|
|
39616
|
+
return {
|
|
39617
|
+
message_id: sent2.message_id,
|
|
39618
|
+
mode: "native",
|
|
39619
|
+
state: { title: args.title, tasks, mode: "native" }
|
|
39620
|
+
};
|
|
39621
|
+
} catch (err) {
|
|
39622
|
+
deps.log(`native sendChecklist failed \u2014 falling back to text render: ${err}
|
|
39623
|
+
`);
|
|
39624
|
+
}
|
|
39625
|
+
}
|
|
39626
|
+
const text = renderChecklistText({ title: args.title, tasks }, { literal: deps.literalText });
|
|
39627
|
+
const sent = await deps.sendText(text);
|
|
39628
|
+
return {
|
|
39629
|
+
message_id: sent.message_id,
|
|
39630
|
+
mode: "text",
|
|
39631
|
+
state: { title: args.title, tasks, mode: "text" }
|
|
39632
|
+
};
|
|
39633
|
+
}
|
|
39634
|
+
function sendChecklistToolText(r) {
|
|
39635
|
+
return JSON.stringify(r.mode === "native" ? { ok: true, message_id: r.message_id, mode: "native" } : {
|
|
39636
|
+
ok: true,
|
|
39637
|
+
message_id: r.message_id,
|
|
39638
|
+
mode: "text",
|
|
39639
|
+
degraded: "text",
|
|
39640
|
+
note: "rendered as a formatted text message (native Telegram checklists require a Business connection) \u2014 tasks are not tappable; use update_checklist with task ids 1..N to tick them"
|
|
39641
|
+
});
|
|
39642
|
+
}
|
|
39643
|
+
async function performUpdateChecklist(deps, patch) {
|
|
39644
|
+
let base = deps.state;
|
|
39645
|
+
if (!base) {
|
|
39646
|
+
const fullReplacement = patch.title != null && (patch.tasks?.length ?? 0) > 0 && (patch.tasks ?? []).every((t) => t.text != null);
|
|
39647
|
+
if (!fullReplacement) {
|
|
39648
|
+
return {
|
|
39649
|
+
ok: false,
|
|
39650
|
+
reason: "unknown_checklist",
|
|
39651
|
+
hint: "no stored state for this checklist (gateway restarted?). Re-send it with send_checklist, or pass a full replacement (title + every task's text) to update_checklist."
|
|
39652
|
+
};
|
|
39653
|
+
}
|
|
39654
|
+
base = { title: patch.title, tasks: [], mode: "text" };
|
|
39655
|
+
}
|
|
39656
|
+
let next;
|
|
39657
|
+
try {
|
|
39658
|
+
next = applyChecklistPatch(base, patch);
|
|
39659
|
+
} catch (err) {
|
|
39660
|
+
return { ok: false, reason: "edit_failed", hint: String(err) };
|
|
39661
|
+
}
|
|
39662
|
+
const state = { title: next.title, tasks: next.tasks, mode: base.mode };
|
|
39663
|
+
if (base.mode === "native") {
|
|
39664
|
+
if (!deps.nativeAvailable || !deps.businessConnectionId) {
|
|
39665
|
+
return {
|
|
39666
|
+
ok: false,
|
|
39667
|
+
reason: "edit_failed",
|
|
39668
|
+
hint: "this checklist was sent natively but the business connection / checklist API is no longer available."
|
|
39669
|
+
};
|
|
39670
|
+
}
|
|
39671
|
+
try {
|
|
39672
|
+
await deps.editNative(buildNativeEditChecklistPayload({
|
|
39673
|
+
businessConnectionId: deps.businessConnectionId,
|
|
39674
|
+
chatId: deps.chatId,
|
|
39675
|
+
messageId: deps.messageId,
|
|
39676
|
+
title: state.title,
|
|
39677
|
+
tasks: state.tasks
|
|
39678
|
+
}));
|
|
39679
|
+
return { ok: true, mode: "native", state };
|
|
39680
|
+
} catch (err) {
|
|
39681
|
+
deps.log(`native editMessageChecklist failed: ${err}
|
|
39682
|
+
`);
|
|
39683
|
+
return { ok: false, reason: "edit_failed", hint: String(err) };
|
|
39684
|
+
}
|
|
39685
|
+
}
|
|
39686
|
+
try {
|
|
39687
|
+
await deps.editText(renderChecklistText(state, { literal: deps.literalText }));
|
|
39688
|
+
return { ok: true, mode: "text", state };
|
|
39689
|
+
} catch (err) {
|
|
39690
|
+
deps.log(`checklist text edit failed: ${err}
|
|
39691
|
+
`);
|
|
39692
|
+
return { ok: false, reason: "edit_failed", hint: String(err) };
|
|
39693
|
+
}
|
|
39694
|
+
}
|
|
39695
|
+
function updateChecklistToolText(r, messageId) {
|
|
39696
|
+
return JSON.stringify(r.ok ? { ok: true, message_id: messageId, mode: r.mode, ...r.mode === "text" ? { degraded: "text" } : {} } : { ok: false, reason: r.reason, hint: r.hint });
|
|
39697
|
+
}
|
|
39698
|
+
|
|
39507
39699
|
// interrupt-marker.ts
|
|
39508
39700
|
function parseInterruptMarker(text) {
|
|
39509
39701
|
const trimmed = text.trimStart();
|
|
@@ -45390,12 +45582,42 @@ function assessThinkingEffortRisk(model, effort) {
|
|
|
45390
45582
|
};
|
|
45391
45583
|
}
|
|
45392
45584
|
|
|
45393
|
-
//
|
|
45394
|
-
var MODEL_ALIASES = ["opus", "sonnet", "haiku", "fable", "default"];
|
|
45585
|
+
// ../src/agents/model-aliases.ts
|
|
45395
45586
|
var CLAUDE_MODEL_ALIASES = {
|
|
45396
45587
|
opus48: "claude-opus-4-8",
|
|
45397
45588
|
"opus-4-8": "claude-opus-4-8"
|
|
45398
45589
|
};
|
|
45590
|
+
var SR_MODEL_ALIASES = {
|
|
45591
|
+
flash: "sr-gemini-2.5-flash",
|
|
45592
|
+
gemini: "sr-gemini-2.5-pro",
|
|
45593
|
+
deepseek: "sr-deepseek-v3",
|
|
45594
|
+
r1: "sr-deepseek-r1",
|
|
45595
|
+
glm: "sr-glm-5",
|
|
45596
|
+
codex: "sr-codex-5.5",
|
|
45597
|
+
grok: "sr-grok-4.5",
|
|
45598
|
+
kimi: "sr-kimi-k3",
|
|
45599
|
+
gpt: "sr-gpt-5.6-sol",
|
|
45600
|
+
sol: "sr-gpt-5.6-sol",
|
|
45601
|
+
terra: "sr-gpt-5.6-terra",
|
|
45602
|
+
luna: "sr-gpt-5.6-luna"
|
|
45603
|
+
};
|
|
45604
|
+
function expandSrAlias(arg) {
|
|
45605
|
+
return SR_MODEL_ALIASES[arg.toLowerCase()] ?? arg;
|
|
45606
|
+
}
|
|
45607
|
+
function expandClaudeAlias(arg) {
|
|
45608
|
+
return CLAUDE_MODEL_ALIASES[arg.trim().toLowerCase()] ?? arg;
|
|
45609
|
+
}
|
|
45610
|
+
function canonicalModelToken(arg) {
|
|
45611
|
+
const trimmed = arg.trim();
|
|
45612
|
+
const lower = trimmed.toLowerCase();
|
|
45613
|
+
return lower.startsWith("claude-") ? lower : trimmed;
|
|
45614
|
+
}
|
|
45615
|
+
function expandModelAlias(arg) {
|
|
45616
|
+
return canonicalModelToken(expandSrAlias(expandClaudeAlias(arg)));
|
|
45617
|
+
}
|
|
45618
|
+
|
|
45619
|
+
// gateway/model-command.ts
|
|
45620
|
+
var MODEL_ALIASES = ["opus", "sonnet", "haiku", "fable", "default"];
|
|
45399
45621
|
var MODEL_ARG_RE = /^[A-Za-z0-9][A-Za-z0-9._/\[\]-]{0,99}$/;
|
|
45400
45622
|
function isValidModelArg(arg) {
|
|
45401
45623
|
return MODEL_ARG_RE.test(arg);
|
|
@@ -45595,34 +45817,6 @@ var SR_MODEL_LABELS = {
|
|
|
45595
45817
|
"sr-gpt-5.6-terra": "GPT-5.6 Terra",
|
|
45596
45818
|
"sr-gpt-5.6-luna": "GPT-5.6 Luna"
|
|
45597
45819
|
};
|
|
45598
|
-
var SR_MODEL_ALIASES = {
|
|
45599
|
-
flash: "sr-gemini-2.5-flash",
|
|
45600
|
-
gemini: "sr-gemini-2.5-pro",
|
|
45601
|
-
deepseek: "sr-deepseek-v3",
|
|
45602
|
-
r1: "sr-deepseek-r1",
|
|
45603
|
-
glm: "sr-glm-5",
|
|
45604
|
-
codex: "sr-codex-5.5",
|
|
45605
|
-
grok: "sr-grok-4.5",
|
|
45606
|
-
kimi: "sr-kimi-k3",
|
|
45607
|
-
gpt: "sr-gpt-5.6-sol",
|
|
45608
|
-
sol: "sr-gpt-5.6-sol",
|
|
45609
|
-
terra: "sr-gpt-5.6-terra",
|
|
45610
|
-
luna: "sr-gpt-5.6-luna"
|
|
45611
|
-
};
|
|
45612
|
-
function expandSrAlias(arg) {
|
|
45613
|
-
return SR_MODEL_ALIASES[arg.toLowerCase()] ?? arg;
|
|
45614
|
-
}
|
|
45615
|
-
function canonicalModelToken(arg) {
|
|
45616
|
-
const trimmed = arg.trim();
|
|
45617
|
-
const lower = trimmed.toLowerCase();
|
|
45618
|
-
return lower.startsWith("claude-") ? lower : trimmed;
|
|
45619
|
-
}
|
|
45620
|
-
function expandClaudeAlias(arg) {
|
|
45621
|
-
return CLAUDE_MODEL_ALIASES[arg.trim().toLowerCase()] ?? arg;
|
|
45622
|
-
}
|
|
45623
|
-
function expandModelAlias(arg) {
|
|
45624
|
-
return canonicalModelToken(expandSrAlias(expandClaudeAlias(arg)));
|
|
45625
|
-
}
|
|
45626
45820
|
function srFriendlyLabel(srName) {
|
|
45627
45821
|
return SR_MODEL_LABELS[srName] ?? srName.replace(/^sr-/, "").replace(/-/g, " ");
|
|
45628
45822
|
}
|
|
@@ -80216,6 +80410,25 @@ function discardParkedTurnStart(rawContent) {
|
|
|
80216
80410
|
}
|
|
80217
80411
|
return null;
|
|
80218
80412
|
}
|
|
80413
|
+
function drainParkedTurnStartsForChat(deps, chatId, threadId) {
|
|
80414
|
+
const wantThread = envThreadIdNum(threadId);
|
|
80415
|
+
const drained = [];
|
|
80416
|
+
for (let i = 0;i < parkedTurnStarts.length; ) {
|
|
80417
|
+
const entry = parkedTurnStarts[i];
|
|
80418
|
+
if (entry.chatId === chatId && envThreadIdNum(entry.threadId) === wantThread) {
|
|
80419
|
+
drained.push(entry);
|
|
80420
|
+
parkedTurnStarts.splice(i, 1);
|
|
80421
|
+
} else {
|
|
80422
|
+
i++;
|
|
80423
|
+
}
|
|
80424
|
+
}
|
|
80425
|
+
for (const env of drained) {
|
|
80426
|
+
process.stderr.write(`telegram gateway: parked-turn-start drained on silence-fallback ` + `chat=${env.chatId ?? "-"} thread=${envThreadIdNum(env.threadId) ?? "-"} ` + `msg=${env.messageId ?? "-"}
|
|
80427
|
+
`);
|
|
80428
|
+
beginTurn(deps, env);
|
|
80429
|
+
}
|
|
80430
|
+
return drained;
|
|
80431
|
+
}
|
|
80219
80432
|
async function openQueuedCard(deps, chatId, threadId, replyToMessageId) {
|
|
80220
80433
|
try {
|
|
80221
80434
|
const sent = await deps.robustApiCall(() => deps.bot.api.sendRichMessage(chatId, richMessage(QUEUED_CARD_HTML), {
|
|
@@ -83955,10 +84168,6 @@ Allowed: \`${deps.escapeHtml(allow)}\``, { html: true });
|
|
|
83955
84168
|
|
|
83956
84169
|
// gateway/model-command.ts
|
|
83957
84170
|
var MODEL_ALIASES2 = ["opus", "sonnet", "haiku", "fable", "default"];
|
|
83958
|
-
var CLAUDE_MODEL_ALIASES2 = {
|
|
83959
|
-
opus48: "claude-opus-4-8",
|
|
83960
|
-
"opus-4-8": "claude-opus-4-8"
|
|
83961
|
-
};
|
|
83962
84171
|
var MODEL_ARG_RE2 = /^[A-Za-z0-9][A-Za-z0-9._/\[\]-]{0,99}$/;
|
|
83963
84172
|
function isValidModelArg2(arg) {
|
|
83964
84173
|
return MODEL_ARG_RE2.test(arg);
|
|
@@ -84117,7 +84326,7 @@ function resolveStaleAwareBusy(input) {
|
|
|
84117
84326
|
var PERSIST_NOTE3 = "_A `/model` switch relaunches the session (~30s) on the chosen model. Session-only \u2014 reverts to the configured `model:` on the next restart. `/model default` reverts now. Live scrollback is replaced by a fresh session; memory and the handoff briefing carry the context. To change the default permanently, set `model:` in switchroom.yaml._";
|
|
84118
84327
|
function claudeAliasHints2(prefix) {
|
|
84119
84328
|
const byTarget = new Map;
|
|
84120
|
-
for (const [alias, target] of Object.entries(
|
|
84329
|
+
for (const [alias, target] of Object.entries(CLAUDE_MODEL_ALIASES)) {
|
|
84121
84330
|
const spellings = byTarget.get(target) ?? [];
|
|
84122
84331
|
spellings.push(alias);
|
|
84123
84332
|
byTarget.set(target, spellings);
|
|
@@ -84125,7 +84334,7 @@ function claudeAliasHints2(prefix) {
|
|
|
84125
84334
|
return [...byTarget].map(([target, spellings]) => `${spellings.map((a) => `\`${prefix}${a}\``).join(" \u00b7 ")} \u2192 \`${target}\``).join("; ");
|
|
84126
84335
|
}
|
|
84127
84336
|
function helpText4(deps, reason) {
|
|
84128
|
-
const srAliasExamples = Object.keys(
|
|
84337
|
+
const srAliasExamples = Object.keys(SR_MODEL_ALIASES).map((a) => `\`${a}\``).join(" \u00b7 ");
|
|
84129
84338
|
const claudeAliasExamples = claudeAliasHints2("");
|
|
84130
84339
|
const lines = [];
|
|
84131
84340
|
if (reason)
|
|
@@ -84140,7 +84349,7 @@ async function handleModelCommand2(parsed, deps) {
|
|
|
84140
84349
|
if (parsed.kind === "show") {
|
|
84141
84350
|
const configured = deps.getConfiguredModel();
|
|
84142
84351
|
const shown = configured && configured.length > 0 ? configured : "default";
|
|
84143
|
-
const srAliasExamples = Object.keys(
|
|
84352
|
+
const srAliasExamples = Object.keys(SR_MODEL_ALIASES).map((a) => `\`/model ${a}\``).join(" \u00b7 ");
|
|
84144
84353
|
return {
|
|
84145
84354
|
text: [
|
|
84146
84355
|
`**Model \u2014 ${deps.escapeHtml(deps.getAgentName())}**`,
|
|
@@ -84158,7 +84367,7 @@ async function handleModelCommand2(parsed, deps) {
|
|
|
84158
84367
|
if (!isValidModelArg2(parsed.model)) {
|
|
84159
84368
|
return helpText4(deps, `not a valid model name: ${parsed.model}`);
|
|
84160
84369
|
}
|
|
84161
|
-
const model =
|
|
84370
|
+
const model = expandModelAlias(parsed.model);
|
|
84162
84371
|
if (deps.isBusy()) {
|
|
84163
84372
|
return {
|
|
84164
84373
|
text: "\u23f3 The agent is mid-turn \u2014 a model switch needs an idle session. The switch was not applied.",
|
|
@@ -84185,10 +84394,10 @@ function relaunchErrorReply2(deps, model, err) {
|
|
|
84185
84394
|
return { text: `\u274c Could not schedule model switch: ${deps.escapeHtml(msg)}`, html: true };
|
|
84186
84395
|
}
|
|
84187
84396
|
function unvalidatedIdCaveat2(deps, model) {
|
|
84188
|
-
const lower =
|
|
84397
|
+
const lower = canonicalModelToken(model).toLowerCase();
|
|
84189
84398
|
if (!lower.startsWith("claude-"))
|
|
84190
84399
|
return null;
|
|
84191
|
-
if (Object.values(
|
|
84400
|
+
if (Object.values(CLAUDE_MODEL_ALIASES).includes(lower))
|
|
84192
84401
|
return null;
|
|
84193
84402
|
return `_\`${deps.escapeHtml(model)}\` can't be validated before launch \u2014 if it isn't a real Claude model id, claude will silently serve the configured fallback model instead. I check the first reply and will warn if that happens._`;
|
|
84194
84403
|
}
|
|
@@ -84273,45 +84482,17 @@ var SR_MODEL_LABELS2 = {
|
|
|
84273
84482
|
"sr-gpt-5.6-terra": "GPT-5.6 Terra",
|
|
84274
84483
|
"sr-gpt-5.6-luna": "GPT-5.6 Luna"
|
|
84275
84484
|
};
|
|
84276
|
-
var SR_MODEL_ALIASES2 = {
|
|
84277
|
-
flash: "sr-gemini-2.5-flash",
|
|
84278
|
-
gemini: "sr-gemini-2.5-pro",
|
|
84279
|
-
deepseek: "sr-deepseek-v3",
|
|
84280
|
-
r1: "sr-deepseek-r1",
|
|
84281
|
-
glm: "sr-glm-5",
|
|
84282
|
-
codex: "sr-codex-5.5",
|
|
84283
|
-
grok: "sr-grok-4.5",
|
|
84284
|
-
kimi: "sr-kimi-k3",
|
|
84285
|
-
gpt: "sr-gpt-5.6-sol",
|
|
84286
|
-
sol: "sr-gpt-5.6-sol",
|
|
84287
|
-
terra: "sr-gpt-5.6-terra",
|
|
84288
|
-
luna: "sr-gpt-5.6-luna"
|
|
84289
|
-
};
|
|
84290
84485
|
function isOfflineTrustedModelToken(token) {
|
|
84291
84486
|
const lower = token.toLowerCase();
|
|
84292
84487
|
if (MODEL_ALIASES2.includes(lower))
|
|
84293
84488
|
return true;
|
|
84294
|
-
if (lower in
|
|
84489
|
+
if (lower in SR_MODEL_ALIASES)
|
|
84295
84490
|
return true;
|
|
84296
|
-
if (Object.values(
|
|
84491
|
+
if (Object.values(SR_MODEL_ALIASES).includes(lower))
|
|
84297
84492
|
return true;
|
|
84298
|
-
if (lower in
|
|
84493
|
+
if (lower in CLAUDE_MODEL_ALIASES)
|
|
84299
84494
|
return true;
|
|
84300
|
-
return Object.values(
|
|
84301
|
-
}
|
|
84302
|
-
function expandSrAlias2(arg) {
|
|
84303
|
-
return SR_MODEL_ALIASES2[arg.toLowerCase()] ?? arg;
|
|
84304
|
-
}
|
|
84305
|
-
function canonicalModelToken2(arg) {
|
|
84306
|
-
const trimmed = arg.trim();
|
|
84307
|
-
const lower = trimmed.toLowerCase();
|
|
84308
|
-
return lower.startsWith("claude-") ? lower : trimmed;
|
|
84309
|
-
}
|
|
84310
|
-
function expandClaudeAlias2(arg) {
|
|
84311
|
-
return CLAUDE_MODEL_ALIASES2[arg.trim().toLowerCase()] ?? arg;
|
|
84312
|
-
}
|
|
84313
|
-
function expandModelAlias2(arg) {
|
|
84314
|
-
return canonicalModelToken2(expandSrAlias2(expandClaudeAlias2(arg)));
|
|
84495
|
+
return Object.values(CLAUDE_MODEL_ALIASES).includes(lower);
|
|
84315
84496
|
}
|
|
84316
84497
|
function srFriendlyLabel2(srName) {
|
|
84317
84498
|
return SR_MODEL_LABELS2[srName] ?? srName.replace(/^sr-/, "").replace(/-/g, " ");
|
|
@@ -84391,7 +84572,7 @@ function headerRow2(label) {
|
|
|
84391
84572
|
return [{ text: label, callback_data: MODEL_CALLBACK_HEADER2 }];
|
|
84392
84573
|
}
|
|
84393
84574
|
function externalModelNames2(discovered) {
|
|
84394
|
-
const set = new Set(Object.values(
|
|
84575
|
+
const set = new Set(Object.values(SR_MODEL_ALIASES));
|
|
84395
84576
|
for (const n of discovered) {
|
|
84396
84577
|
if (isSrModel2(n))
|
|
84397
84578
|
set.add(n);
|
|
@@ -84509,7 +84690,7 @@ async function handleModelMenuCallback(data, deps) {
|
|
|
84509
84690
|
if (!isValidModelArg2(token)) {
|
|
84510
84691
|
return { answer: "Invalid model name", reply: await buildModelMenu2(deps) };
|
|
84511
84692
|
}
|
|
84512
|
-
token =
|
|
84693
|
+
token = expandModelAlias(token);
|
|
84513
84694
|
if (!isRecognizedSwitchToken(token)) {
|
|
84514
84695
|
return { answer: "Model list changed \u2014 menu refreshed", reply: await buildModelMenu2(deps) };
|
|
84515
84696
|
}
|
|
@@ -85615,7 +85796,9 @@ function resolveMainModel(model) {
|
|
|
85615
85796
|
return normalizeModelAlias(model);
|
|
85616
85797
|
}
|
|
85617
85798
|
function normalizeModelAlias(model) {
|
|
85618
|
-
|
|
85799
|
+
if (model === "claude-fable-5")
|
|
85800
|
+
return "fable";
|
|
85801
|
+
return expandModelAlias(model);
|
|
85619
85802
|
}
|
|
85620
85803
|
var CLAUDE_MD_YOURS_PLACEHOLDER = "This space is yours. Add per-agent rules, exceptions, or context the " + "Switchroom template doesn't capture. Everything above the marker line is " + "regenerated on every apply; this section is preserved.";
|
|
85621
85804
|
var pendingBankOps = new Set;
|
|
@@ -91772,6 +91955,18 @@ function computeTurnStatus(turn) {
|
|
|
91772
91955
|
return turn.finalAnswerDelivered ? "complete" : "no_reply";
|
|
91773
91956
|
}
|
|
91774
91957
|
}
|
|
91958
|
+
function computeTurnRoute(turn) {
|
|
91959
|
+
switch (turn.deliveryOutcome) {
|
|
91960
|
+
case "failed":
|
|
91961
|
+
return "none";
|
|
91962
|
+
case "delivered":
|
|
91963
|
+
return "flush";
|
|
91964
|
+
case "suppressed":
|
|
91965
|
+
return "reply";
|
|
91966
|
+
default:
|
|
91967
|
+
return turn.finalAnswerDelivered ? turn.replyCalled ? "reply" : "stream" : "none";
|
|
91968
|
+
}
|
|
91969
|
+
}
|
|
91775
91970
|
function buildTurnRecord(turn, endedAt) {
|
|
91776
91971
|
return {
|
|
91777
91972
|
ts: Math.floor(endedAt / 1000),
|
|
@@ -91780,6 +91975,11 @@ function buildTurnRecord(turn, endedAt) {
|
|
|
91780
91975
|
tools: turn.toolCallCount ?? 0,
|
|
91781
91976
|
status: computeTurnStatus(turn),
|
|
91782
91977
|
turn_id: turn.turnId,
|
|
91978
|
+
route: computeTurnRoute({
|
|
91979
|
+
finalAnswerDelivered: turn.finalAnswerDelivered,
|
|
91980
|
+
replyCalled: turn.replyCalled ?? false,
|
|
91981
|
+
deliveryOutcome: turn.deliveryOutcome
|
|
91982
|
+
}),
|
|
91783
91983
|
...turn.landedUnconfirmed != null && turn.landedUnconfirmed > 0 ? { landed_unconfirmed: turn.landedUnconfirmed } : {}
|
|
91784
91984
|
};
|
|
91785
91985
|
}
|
|
@@ -93426,6 +93626,7 @@ function buildSilencePokeOptions(deps) {
|
|
|
93426
93626
|
endCurrentTurnForKey,
|
|
93427
93627
|
getPendingInboundBuffer,
|
|
93428
93628
|
trackRedeliveredInbound,
|
|
93629
|
+
drainParkedTurnStarts,
|
|
93429
93630
|
closeActivityLane,
|
|
93430
93631
|
closeProgressLane,
|
|
93431
93632
|
hangRestart
|
|
@@ -93619,7 +93820,8 @@ function buildSilencePokeOptions(deps) {
|
|
|
93619
93820
|
} catch {}
|
|
93620
93821
|
const fbSelfAgent = process.env.SWITCHROOM_AGENT_NAME ?? "";
|
|
93621
93822
|
const fbRedeliver = redeliverBufferedInbound2(getPendingInboundBuffer(), fbSelfAgent, (m) => sendToAgent(fbSelfAgent, m), getInboundSpool(), trackRedeliveredInbound);
|
|
93622
|
-
|
|
93823
|
+
const fbDrainedParked = drainParkedTurnStarts?.(fbChatId, fbThreadId ?? null) ?? 0;
|
|
93824
|
+
process.stderr.write(`telegram gateway: silence-poke framework-fallback ended wedged turn ` + `chat=${fbChatId} thread=${ctx.threadId ?? "-"} silence_ms=${ctx.silenceMs} ` + `currentTurn_nulled=${tearsDownLiveTurn} ` + `drained_buffered=${fbRedeliver.redelivered}/${fbRedeliver.drained}` + `${fbDrainedParked > 0 ? ` drained_parked=${fbDrainedParked}` : ""}` + `${fbRedeliver.rebuffered > 0 ? ` rebuffered=${fbRedeliver.rebuffered}` : ""}` + `${fbExtraPurge.purged.length > 0 ? ` extra_keys_purged=${fbExtraPurge.purged.length}` : ""}
|
|
93623
93825
|
`);
|
|
93624
93826
|
}
|
|
93625
93827
|
};
|
|
@@ -99917,10 +100119,10 @@ function startOutboxSweep(deps) {
|
|
|
99917
100119
|
}
|
|
99918
100120
|
|
|
99919
100121
|
// ../src/build-info.ts
|
|
99920
|
-
var VERSION2 = "0.19.
|
|
99921
|
-
var COMMIT_SHA = "
|
|
99922
|
-
var COMMIT_DATE = "2026-
|
|
99923
|
-
var LATEST_PR =
|
|
100122
|
+
var VERSION2 = "0.19.42";
|
|
100123
|
+
var COMMIT_SHA = "e288dac2";
|
|
100124
|
+
var COMMIT_DATE = "2026-08-01T02:20:24Z";
|
|
100125
|
+
var LATEST_PR = 4094;
|
|
99924
100126
|
var COMMITS_AHEAD_OF_TAG = 0;
|
|
99925
100127
|
|
|
99926
100128
|
// gateway/boot-version.ts
|
|
@@ -101975,40 +102177,21 @@ var GRAMMY_VERSION = (() => {
|
|
|
101975
102177
|
var _rawSendChecklist;
|
|
101976
102178
|
var _rawEditMessageChecklist;
|
|
101977
102179
|
var CHECKLIST_API_AVAILABLE = false;
|
|
101978
|
-
async function rawSendChecklist(
|
|
101979
|
-
if (!CHECKLIST_API_AVAILABLE)
|
|
102180
|
+
async function rawSendChecklist(payload) {
|
|
102181
|
+
if (!CHECKLIST_API_AVAILABLE)
|
|
101980
102182
|
throw new Error("sendChecklist is not available in this grammY/Telegram Bot API version");
|
|
101981
|
-
|
|
101982
|
-
const MAX_TASKS = 30;
|
|
101983
|
-
if (args.tasks.length > MAX_TASKS) {
|
|
101984
|
-
throw new Error(`checklist exceeds ${MAX_TASKS}-task limit (got ${args.tasks.length})`);
|
|
101985
|
-
}
|
|
101986
|
-
const result = await _rawSendChecklist({
|
|
101987
|
-
chat_id: Number(args.chat_id),
|
|
101988
|
-
title: args.title,
|
|
101989
|
-
tasks: args.tasks.map((t) => ({ text: t.text, ...t.done != null ? { is_completed: t.done } : {} })),
|
|
101990
|
-
...args.message_thread_id != null ? { message_thread_id: args.message_thread_id } : {},
|
|
101991
|
-
...args.reply_to_message_id != null ? { reply_to_message_id: args.reply_to_message_id } : {},
|
|
101992
|
-
...args.protect_content === true ? { protect_content: true } : {}
|
|
101993
|
-
});
|
|
102183
|
+
const result = await _rawSendChecklist(payload);
|
|
101994
102184
|
return { message_id: result.message_id };
|
|
101995
102185
|
}
|
|
101996
|
-
async function rawEditMessageChecklist(
|
|
101997
|
-
if (!CHECKLIST_API_AVAILABLE)
|
|
102186
|
+
async function rawEditMessageChecklist(payload) {
|
|
102187
|
+
if (!CHECKLIST_API_AVAILABLE)
|
|
101998
102188
|
throw new Error("editMessageChecklist is not available in this grammY/Telegram Bot API version");
|
|
101999
|
-
|
|
102000
|
-
|
|
102001
|
-
|
|
102002
|
-
|
|
102003
|
-
|
|
102004
|
-
|
|
102005
|
-
tasks: args.tasks.map((t) => ({
|
|
102006
|
-
...t.id != null ? { id: Number(t.id) } : {},
|
|
102007
|
-
...t.text != null ? { text: t.text } : {},
|
|
102008
|
-
...t.done != null ? { is_completed: t.done } : {}
|
|
102009
|
-
}))
|
|
102010
|
-
} : {}
|
|
102011
|
-
});
|
|
102189
|
+
await _rawEditMessageChecklist(payload);
|
|
102190
|
+
}
|
|
102191
|
+
var checklistStore = createChecklistStore();
|
|
102192
|
+
function resolveBusinessConnectionId() {
|
|
102193
|
+
const v = process.env.SWITCHROOM_TELEGRAM_BUSINESS_CONNECTION_ID?.trim();
|
|
102194
|
+
return v ? v : undefined;
|
|
102012
102195
|
}
|
|
102013
102196
|
var chatLock = createChatLock();
|
|
102014
102197
|
var lockedBot;
|
|
@@ -103399,6 +103582,7 @@ function emitTurnRecord(turn, endedAt) {
|
|
|
103399
103582
|
toolCallCount: turn.toolCallCount ?? 0,
|
|
103400
103583
|
turnId: turn.turnId,
|
|
103401
103584
|
finalAnswerDelivered: turn.finalAnswerDelivered,
|
|
103585
|
+
replyCalled: turn.replyCalled,
|
|
103402
103586
|
deliveryOutcome: turn.deliveryOutcome,
|
|
103403
103587
|
landedUnconfirmed: turn.landedUnconfirmed
|
|
103404
103588
|
}, endedAt)) + `
|
|
@@ -105478,6 +105662,7 @@ function gatewayLivenessWiringDeps() {
|
|
|
105478
105662
|
endCurrentTurnForKey,
|
|
105479
105663
|
getPendingInboundBuffer: () => pendingInboundBuffer,
|
|
105480
105664
|
trackRedeliveredInbound,
|
|
105665
|
+
drainParkedTurnStarts: (chatId, threadId) => drainParkedTurnStartsForChat(gatewayStreamRenderDeps(), chatId, threadId != null ? String(threadId) : null).length,
|
|
105481
105666
|
closeActivityLane,
|
|
105482
105667
|
closeProgressLane,
|
|
105483
105668
|
hangRestart: {
|
|
@@ -106723,17 +106908,24 @@ async function executeSendChecklist(args) {
|
|
|
106723
106908
|
const protectContent = args.protect_content === true;
|
|
106724
106909
|
assertAllowedChat(chat_id);
|
|
106725
106910
|
const { title: redactedTitle, tasks: redactedTasks } = redactChecklistFields(title, tasks, (t) => redactOutboundText(t, "send_checklist"));
|
|
106726
|
-
const
|
|
106727
|
-
|
|
106728
|
-
title: redactedTitle,
|
|
106729
|
-
tasks: redactedTasks,
|
|
106911
|
+
const literal = (loadAccess().parseMode ?? "html") === "text";
|
|
106912
|
+
const sendOpts = {
|
|
106730
106913
|
...threadId != null ? { message_thread_id: threadId } : {},
|
|
106731
|
-
...replyTo != null ? {
|
|
106914
|
+
...replyTo != null ? { reply_parameters: { message_id: replyTo } } : {},
|
|
106732
106915
|
...protectContent ? { protect_content: true } : {}
|
|
106733
|
-
}
|
|
106734
|
-
|
|
106916
|
+
};
|
|
106917
|
+
const result = await performSendChecklist({
|
|
106918
|
+
businessConnectionId: resolveBusinessConnectionId(),
|
|
106919
|
+
nativeAvailable: CHECKLIST_API_AVAILABLE,
|
|
106920
|
+
sendNative: rawSendChecklist,
|
|
106921
|
+
sendText: (text5) => robustApiCall(() => literal ? lockedBot.api.sendMessage(chat_id, text5, sendOpts) : lockedBot.api.sendRichMessage(chat_id, richMessage2(text5), sendOpts), { verb: "sendMessage", chat_id, threadId }),
|
|
106922
|
+
literalText: literal,
|
|
106923
|
+
log: (l) => process.stderr.write(`telegram gateway: ${l}`)
|
|
106924
|
+
}, { title: redactedTitle, tasks: redactedTasks, chatId: Number(chat_id), replyToMessageId: replyTo, protectContent });
|
|
106925
|
+
checklistStore.set(checklistStoreKey(chat_id, result.message_id), result.state);
|
|
106926
|
+
process.stderr.write(`telegram gateway: send_checklist: sent chatId=${chat_id} messageId=${result.message_id} tasks=${tasks.length} mode=${result.mode}
|
|
106735
106927
|
`);
|
|
106736
|
-
return { content: [{ type: "text", text:
|
|
106928
|
+
return { content: [{ type: "text", text: sendChecklistToolText(result) }] };
|
|
106737
106929
|
}
|
|
106738
106930
|
var linearAuthAlertLast = new Map;
|
|
106739
106931
|
var LINEAR_AUTH_ALERT_COOLDOWN_MS = 21600000;
|
|
@@ -106785,10 +106977,26 @@ async function executeUpdateChecklist(args) {
|
|
|
106785
106977
|
const tasks = args.tasks;
|
|
106786
106978
|
assertAllowedChat(chat_id);
|
|
106787
106979
|
const { title: redactedTitle, tasks: redactedTasks } = redactChecklistFields(title, tasks, (t) => redactOutboundText(t, "update_checklist"));
|
|
106788
|
-
|
|
106789
|
-
|
|
106980
|
+
const literal = (loadAccess().parseMode ?? "html") === "text";
|
|
106981
|
+
const key = checklistStoreKey(chat_id, message_id);
|
|
106982
|
+
const result = await performUpdateChecklist({
|
|
106983
|
+
state: checklistStore.get(key),
|
|
106984
|
+
businessConnectionId: resolveBusinessConnectionId(),
|
|
106985
|
+
nativeAvailable: CHECKLIST_API_AVAILABLE,
|
|
106986
|
+
editNative: rawEditMessageChecklist,
|
|
106987
|
+
editText: async (text5) => {
|
|
106988
|
+
await robustApiCall(() => lockedBot.api.editMessageText(chat_id, Number(message_id), literal ? text5 : richMessage2(text5)));
|
|
106989
|
+
},
|
|
106990
|
+
literalText: literal,
|
|
106991
|
+
log: (l) => process.stderr.write(`telegram gateway: ${l}`),
|
|
106992
|
+
chatId: Number(chat_id),
|
|
106993
|
+
messageId: Number(message_id)
|
|
106994
|
+
}, { title: redactedTitle, tasks: redactedTasks });
|
|
106995
|
+
if (result.ok)
|
|
106996
|
+
checklistStore.set(key, result.state);
|
|
106997
|
+
process.stderr.write(`telegram gateway: update_checklist: ${result.ok ? `updated mode=${result.mode}` : `failed reason=${result.reason}`} chatId=${chat_id} messageId=${message_id}
|
|
106790
106998
|
`);
|
|
106791
|
-
return { content: [{ type: "text", text:
|
|
106999
|
+
return { content: [{ type: "text", text: updateChecklistToolText(result, Number(message_id)) }] };
|
|
106792
107000
|
}
|
|
106793
107001
|
function redactOutboundText(text5, site) {
|
|
106794
107002
|
const masked = redact2(text5);
|
|
@@ -109590,7 +109798,7 @@ function persistQueuedCommandForRestart(action) {
|
|
|
109590
109798
|
return `\u21A9\uFE0F Couldn\u2019t verify \`${escapeHtmlForTg2(action.cmd.targetLabel || action.arg)}\` as a known model without the live session \u2014 it was NOT saved. Re-issue \`/model ${escapeHtmlForTg2(action.arg)}\` once the agent is back.`;
|
|
109591
109799
|
}
|
|
109592
109800
|
const configured = readConfiguredDefaultModel(agentDir) ?? resolveMainModel(undefined);
|
|
109593
|
-
writeSessionModelFile(agentDir,
|
|
109801
|
+
writeSessionModelFile(agentDir, expandModelAlias(action.arg), configured);
|
|
109594
109802
|
break;
|
|
109595
109803
|
}
|
|
109596
109804
|
case "clear-model":
|