@llblab/pi-telegram 0.41.1 → 0.42.0
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/CHANGELOG.md +7 -0
- package/README.md +3 -3
- package/docs/architecture.md +3 -3
- package/docs/compact-matrix-literal.md +16 -14
- package/docs/outbound.md +11 -20
- package/docs/public-api.md +2 -2
- package/lib/outbound-buttons.ts +9 -8
- package/lib/outbound-markup.ts +212 -82
- package/lib/routing.ts +44 -28
- package/package.json +1 -1
- package/skills/generated-control-surface/SKILL.md +61 -207
- package/skills/generated-control-surface/references/capability-adapters.md +27 -0
- package/skills/generated-control-surface/references/layout-and-state.md +35 -0
- package/skills/telegram-bridge/SKILL.md +70 -110
- package/skills/telegram-bridge/references/configuration.md +15 -0
- package/skills/telegram-bridge/references/delivery-and-threads.md +27 -0
- package/skills/telegram-bridge/references/diagnosis.md +14 -0
package/lib/outbound-markup.ts
CHANGED
|
@@ -153,63 +153,153 @@ export function parseTopLevelTelegramComment(
|
|
|
153
153
|
};
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
function
|
|
156
|
+
function parseTolerantTelegramAttributes(
|
|
157
157
|
source: string,
|
|
158
|
+
names: readonly string[],
|
|
158
159
|
): Record<string, string> | undefined {
|
|
159
160
|
const attributes: Record<string, string> = {};
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const value = match[2].trim();
|
|
167
|
-
if (value) attributes[match[1]] = value;
|
|
168
|
-
offset = pattern.lastIndex;
|
|
161
|
+
const namePattern = names.join("|");
|
|
162
|
+
const pattern = new RegExp(
|
|
163
|
+
`\\b(${namePattern})\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s]+))`,
|
|
164
|
+
"gu",
|
|
165
|
+
);
|
|
166
|
+
for (const match of source.matchAll(pattern)) {
|
|
167
|
+
const value = (match[2] ?? match[3] ?? match[4] ?? "").trim();
|
|
168
|
+
if (value) attributes[match[1]!] = value;
|
|
169
169
|
}
|
|
170
170
|
return Object.keys(attributes).length > 0 ? attributes : undefined;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
function getTelegramActionPayloadSource(
|
|
174
|
-
comment: TelegramTopLevelHtmlComment,
|
|
175
|
-
command: string,
|
|
176
|
-
): { source: string; hasBody: boolean } | undefined {
|
|
177
|
-
const parsed = parseTopLevelTelegramComment(comment, command);
|
|
178
|
-
if (!parsed || parsed.head.trimStart().startsWith(":")) return undefined;
|
|
179
|
-
const source = [parsed.head, parsed.body]
|
|
180
|
-
.filter((part): part is string => part !== undefined)
|
|
181
|
-
.join("\n")
|
|
182
|
-
.trim();
|
|
183
|
-
return source ? { source, hasBody: parsed.body !== undefined } : undefined;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
173
|
function isTelegramActionPayload(value: unknown): value is Record<string, unknown> {
|
|
187
174
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
188
175
|
}
|
|
189
176
|
|
|
177
|
+
function removeTelegramJsonTrailingCommas(source: string): string {
|
|
178
|
+
let normalized = "";
|
|
179
|
+
let inString = false;
|
|
180
|
+
let escaped = false;
|
|
181
|
+
for (let offset = 0; offset < source.length; offset += 1) {
|
|
182
|
+
const character = source[offset]!;
|
|
183
|
+
if (inString) {
|
|
184
|
+
normalized += character;
|
|
185
|
+
if (escaped) escaped = false;
|
|
186
|
+
else if (character === "\\") escaped = true;
|
|
187
|
+
else if (character === '"') inString = false;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (character === '"') {
|
|
191
|
+
inString = true;
|
|
192
|
+
normalized += character;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (character === ",") {
|
|
196
|
+
let next = offset + 1;
|
|
197
|
+
while (/\s/u.test(source[next] ?? "")) next += 1;
|
|
198
|
+
if (source[next] === "}" || source[next] === "]") continue;
|
|
199
|
+
}
|
|
200
|
+
normalized += character;
|
|
201
|
+
}
|
|
202
|
+
return normalized;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function parseTelegramJsonObjectCandidate(
|
|
206
|
+
source: string,
|
|
207
|
+
): Record<string, unknown> | undefined {
|
|
208
|
+
const normalized = removeTelegramJsonTrailingCommas(source);
|
|
209
|
+
for (const candidate of normalized === source ? [source] : [source, normalized]) {
|
|
210
|
+
try {
|
|
211
|
+
const value: unknown = JSON.parse(candidate);
|
|
212
|
+
if (isTelegramActionPayload(value)) return value;
|
|
213
|
+
} catch {
|
|
214
|
+
// Try the bounded trailing-comma normalization before rejecting JSON.
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function looksLikeTelegramNamedJsonObject(
|
|
221
|
+
source: string,
|
|
222
|
+
offset: number,
|
|
223
|
+
): boolean {
|
|
224
|
+
return /^\{\s*"(?:[^"\\]|\\.)*"\s*:/u.test(source.slice(offset));
|
|
225
|
+
}
|
|
226
|
+
|
|
190
227
|
export function parseTelegramActionPayload(
|
|
191
228
|
comment: TelegramTopLevelHtmlComment,
|
|
192
229
|
command: string,
|
|
193
230
|
): Record<string, unknown> | undefined {
|
|
194
|
-
|
|
195
|
-
if (!
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
231
|
+
let content = comment.content.replace(/^\s+/, "").replace(/^!/, "");
|
|
232
|
+
if (!content.startsWith(command)) return undefined;
|
|
233
|
+
content = content.slice(command.length);
|
|
234
|
+
let attributeEnvelope = content;
|
|
235
|
+
for (let offset = 0; offset < content.length; offset += 1) {
|
|
236
|
+
if (content[offset] !== "{" && content[offset] !== "[") continue;
|
|
237
|
+
if (
|
|
238
|
+
content[offset] === "[" &&
|
|
239
|
+
!isPlausibleTelegramMatrixStart(content, offset)
|
|
240
|
+
) {
|
|
241
|
+
const noiseEnd = findTelegramStructuredPayloadEnd(content, offset);
|
|
242
|
+
if (noiseEnd !== undefined) {
|
|
243
|
+
attributeEnvelope = `${attributeEnvelope.slice(0, offset)}${" ".repeat(noiseEnd - offset)}${attributeEnvelope.slice(noiseEnd)}`;
|
|
244
|
+
offset = noiseEnd - 1;
|
|
245
|
+
}
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
if (content[offset] === "{") {
|
|
249
|
+
const parsed = parseTelegramAdaptiveActionPayloadRows(
|
|
250
|
+
content.slice(offset),
|
|
251
|
+
parseTelegramVoiceCompactActionPayload,
|
|
252
|
+
{ allowTrailing: true },
|
|
253
|
+
);
|
|
254
|
+
if (parsed) return parsed.rows[0]![0];
|
|
202
255
|
}
|
|
256
|
+
const end = findTelegramStructuredPayloadEnd(content, offset);
|
|
257
|
+
if (end === undefined) continue;
|
|
258
|
+
attributeEnvelope = `${attributeEnvelope.slice(0, offset)}${" ".repeat(end - offset)}${attributeEnvelope.slice(end)}`;
|
|
259
|
+
offset = end - 1;
|
|
203
260
|
}
|
|
204
|
-
|
|
205
|
-
|
|
261
|
+
return parseTolerantTelegramAttributes(attributeEnvelope, [
|
|
262
|
+
"text",
|
|
263
|
+
"value",
|
|
264
|
+
"lang",
|
|
265
|
+
"rate",
|
|
266
|
+
]);
|
|
206
267
|
}
|
|
207
268
|
|
|
208
269
|
const TELEGRAM_COMPACT_ACTION_CONTROL_PATTERN = /[\u0000-\u001f\u007f-\u009f]/u;
|
|
209
270
|
|
|
271
|
+
type TelegramCompactActionPayloadParser = (
|
|
272
|
+
atoms: readonly string[],
|
|
273
|
+
) => Record<string, unknown> | undefined;
|
|
274
|
+
|
|
275
|
+
function parseTelegramButtonCompactActionPayload(
|
|
276
|
+
atoms: readonly string[],
|
|
277
|
+
): Record<string, unknown> | undefined {
|
|
278
|
+
const [label, prompt, selectedStyle] = atoms;
|
|
279
|
+
if (atoms.length === 1) return { value: label };
|
|
280
|
+
if (atoms.length === 2) return { label, prompt };
|
|
281
|
+
if (
|
|
282
|
+
selectedStyle !== "primary" &&
|
|
283
|
+
selectedStyle !== "success" &&
|
|
284
|
+
selectedStyle !== "danger"
|
|
285
|
+
) return undefined;
|
|
286
|
+
return { label, prompt, selected_style: selectedStyle };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function parseTelegramVoiceCompactActionPayload(
|
|
290
|
+
atoms: readonly string[],
|
|
291
|
+
): Record<string, unknown> | undefined {
|
|
292
|
+
const [text, lang, rate] = atoms;
|
|
293
|
+
if (atoms.length === 1) return { text };
|
|
294
|
+
if (atoms.length === 2) return { text, lang };
|
|
295
|
+
return { text, lang, rate };
|
|
296
|
+
}
|
|
297
|
+
|
|
210
298
|
function parseTelegramAdaptiveActionPayloadRows(
|
|
211
299
|
source: string,
|
|
212
|
-
|
|
300
|
+
parseCompactPayload: TelegramCompactActionPayloadParser,
|
|
301
|
+
options: { allowTrailing?: boolean } = {},
|
|
302
|
+
): { rows: Record<string, unknown>[][]; end: number } | undefined {
|
|
213
303
|
let offset = 0;
|
|
214
304
|
const isStructuralWhitespace = (character: string | undefined): boolean =>
|
|
215
305
|
character === " " ||
|
|
@@ -224,7 +314,7 @@ function parseTelegramAdaptiveActionPayloadRows(
|
|
|
224
314
|
if (source[offset] !== ",") return true;
|
|
225
315
|
offset += 1;
|
|
226
316
|
skipWhitespace();
|
|
227
|
-
return source[offset] !== ","
|
|
317
|
+
return source[offset] !== ",";
|
|
228
318
|
};
|
|
229
319
|
const normalizeAtom = (value: string): string | undefined => {
|
|
230
320
|
const normalized = value.trim();
|
|
@@ -259,15 +349,7 @@ function parseTelegramAdaptiveActionPayloadRows(
|
|
|
259
349
|
normalizeAtom(atom.join("")),
|
|
260
350
|
);
|
|
261
351
|
if (atoms.some((atom) => atom === undefined)) return undefined;
|
|
262
|
-
|
|
263
|
-
if (atoms.length === 1) return { value: label };
|
|
264
|
-
if (atoms.length === 2) return { label, prompt };
|
|
265
|
-
if (
|
|
266
|
-
selectedStyle !== "primary" &&
|
|
267
|
-
selectedStyle !== "success" &&
|
|
268
|
-
selectedStyle !== "danger"
|
|
269
|
-
) return undefined;
|
|
270
|
-
return { label, prompt, selected_style: selectedStyle };
|
|
352
|
+
return parseCompactPayload(atoms as string[]);
|
|
271
353
|
}
|
|
272
354
|
atomSources.at(-1)!.push(character);
|
|
273
355
|
offset += 1;
|
|
@@ -304,14 +386,10 @@ function parseTelegramAdaptiveActionPayloadRows(
|
|
|
304
386
|
) return undefined;
|
|
305
387
|
if (stack.length > 0) continue;
|
|
306
388
|
const candidate = source.slice(start, index + 1);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
return value;
|
|
312
|
-
} catch {
|
|
313
|
-
return undefined;
|
|
314
|
-
}
|
|
389
|
+
const value = parseTelegramJsonObjectCandidate(candidate);
|
|
390
|
+
if (!value) return undefined;
|
|
391
|
+
offset = index + 1;
|
|
392
|
+
return value;
|
|
315
393
|
}
|
|
316
394
|
return undefined;
|
|
317
395
|
};
|
|
@@ -320,6 +398,7 @@ function parseTelegramAdaptiveActionPayloadRows(
|
|
|
320
398
|
const jsonCell = parseJsonObjectCell();
|
|
321
399
|
if (jsonCell) return jsonCell;
|
|
322
400
|
offset = start;
|
|
401
|
+
if (looksLikeTelegramNamedJsonObject(source, start)) return undefined;
|
|
323
402
|
return parseCompactCell();
|
|
324
403
|
};
|
|
325
404
|
const parseRow = (): Record<string, unknown>[] | undefined => {
|
|
@@ -377,42 +456,92 @@ function parseTelegramAdaptiveActionPayloadRows(
|
|
|
377
456
|
}
|
|
378
457
|
if (!rows) return undefined;
|
|
379
458
|
skipWhitespace();
|
|
380
|
-
|
|
459
|
+
if (!options.allowTrailing && offset !== source.length) return undefined;
|
|
460
|
+
return { rows, end: offset };
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
function findTelegramStructuredPayloadEnd(
|
|
464
|
+
source: string,
|
|
465
|
+
start: number,
|
|
466
|
+
): number | undefined {
|
|
467
|
+
const stack: string[] = [source[start]!];
|
|
468
|
+
let inString = false;
|
|
469
|
+
let escaped = false;
|
|
470
|
+
for (let offset = start + 1; offset < source.length; offset += 1) {
|
|
471
|
+
const character = source[offset]!;
|
|
472
|
+
if (inString) {
|
|
473
|
+
if (escaped) escaped = false;
|
|
474
|
+
else if (character === "\\") escaped = true;
|
|
475
|
+
else if (character === '"') inString = false;
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
if (character === '"') {
|
|
479
|
+
inString = true;
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
if (character === "[" || character === "{") {
|
|
483
|
+
stack.push(character);
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
if (character !== "]" && character !== "}") continue;
|
|
487
|
+
const expected = character === "]" ? "[" : "{";
|
|
488
|
+
if (stack.at(-1) === expected) stack.pop();
|
|
489
|
+
if (stack.length === 0) return offset + 1;
|
|
490
|
+
}
|
|
491
|
+
return undefined;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
function isPlausibleTelegramMatrixStart(
|
|
495
|
+
source: string,
|
|
496
|
+
start: number,
|
|
497
|
+
): boolean {
|
|
498
|
+
let offset = start + 1;
|
|
499
|
+
while (/\s/u.test(source[offset] ?? "")) offset += 1;
|
|
500
|
+
return (
|
|
501
|
+
source[offset] === "{" ||
|
|
502
|
+
source[offset] === "[" ||
|
|
503
|
+
source[offset] === "]"
|
|
504
|
+
);
|
|
381
505
|
}
|
|
382
506
|
|
|
383
507
|
export function parseTelegramActionPayloadRows(
|
|
384
508
|
comment: TelegramTopLevelHtmlComment,
|
|
385
509
|
command: string,
|
|
386
510
|
): Record<string, unknown>[][] | undefined {
|
|
387
|
-
|
|
388
|
-
if (!
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
!Array.isArray(entry) ||
|
|
402
|
-
entry.length === 0 ||
|
|
403
|
-
!entry.every(isTelegramActionPayload)
|
|
404
|
-
) {
|
|
405
|
-
return undefined;
|
|
406
|
-
}
|
|
407
|
-
rows.push(entry);
|
|
511
|
+
let content = comment.content.replace(/^\s+/, "").replace(/^!/, "");
|
|
512
|
+
if (!content.startsWith(command)) return undefined;
|
|
513
|
+
content = content.slice(command.length);
|
|
514
|
+
let attributeEnvelope = content;
|
|
515
|
+
for (let offset = 0; offset < content.length; offset += 1) {
|
|
516
|
+
if (content[offset] !== "[" && content[offset] !== "{") continue;
|
|
517
|
+
if (
|
|
518
|
+
content[offset] === "[" &&
|
|
519
|
+
!isPlausibleTelegramMatrixStart(content, offset)
|
|
520
|
+
) {
|
|
521
|
+
const noiseEnd = findTelegramStructuredPayloadEnd(content, offset);
|
|
522
|
+
if (noiseEnd !== undefined) {
|
|
523
|
+
attributeEnvelope = `${attributeEnvelope.slice(0, offset)}${" ".repeat(noiseEnd - offset)}${attributeEnvelope.slice(noiseEnd)}`;
|
|
524
|
+
offset = noiseEnd - 1;
|
|
408
525
|
}
|
|
409
|
-
|
|
410
|
-
} catch {
|
|
411
|
-
return parseTelegramAdaptiveActionPayloadRows(payload.source);
|
|
526
|
+
continue;
|
|
412
527
|
}
|
|
528
|
+
const parsed = parseTelegramAdaptiveActionPayloadRows(
|
|
529
|
+
content.slice(offset),
|
|
530
|
+
parseTelegramButtonCompactActionPayload,
|
|
531
|
+
{ allowTrailing: true },
|
|
532
|
+
);
|
|
533
|
+
if (parsed) return parsed.rows;
|
|
534
|
+
const end = findTelegramStructuredPayloadEnd(content, offset);
|
|
535
|
+
if (end === undefined) continue;
|
|
536
|
+
attributeEnvelope = `${attributeEnvelope.slice(0, offset)}${" ".repeat(end - offset)}${attributeEnvelope.slice(end)}`;
|
|
537
|
+
offset = end - 1;
|
|
413
538
|
}
|
|
414
|
-
|
|
415
|
-
|
|
539
|
+
const attributes = parseTolerantTelegramAttributes(attributeEnvelope, [
|
|
540
|
+
"label",
|
|
541
|
+
"prompt",
|
|
542
|
+
"value",
|
|
543
|
+
"selected_style",
|
|
544
|
+
]);
|
|
416
545
|
return attributes ? [[attributes]] : undefined;
|
|
417
546
|
}
|
|
418
547
|
|
|
@@ -481,9 +610,10 @@ export function planTelegramVoiceReply(
|
|
|
481
610
|
let lang: string | undefined;
|
|
482
611
|
let rate: string | undefined;
|
|
483
612
|
const stripped = replaceTopLevelHtmlComments(markdown, (comment) => {
|
|
484
|
-
const command =
|
|
485
|
-
|
|
486
|
-
|
|
613
|
+
const command = "telegram_voice";
|
|
614
|
+
const normalizedContent = comment.content.replace(/^\s+/, "").replace(/^!/, "");
|
|
615
|
+
if (!normalizedContent.startsWith(command)) return comment.raw;
|
|
616
|
+
const payload = parseTelegramActionPayload(comment, command);
|
|
487
617
|
if (!payload) return "";
|
|
488
618
|
const text =
|
|
489
619
|
getTelegramActionString(payload, "text") ??
|
package/lib/routing.ts
CHANGED
|
@@ -759,6 +759,42 @@ export function createTelegramInboundRouteRuntime<
|
|
|
759
759
|
);
|
|
760
760
|
}
|
|
761
761
|
};
|
|
762
|
+
const resolveTelegramThreadLabel = (message: {
|
|
763
|
+
chat: { id: number };
|
|
764
|
+
message_thread_id?: number;
|
|
765
|
+
}): string | undefined => {
|
|
766
|
+
const chatId = message.chat.id;
|
|
767
|
+
const threadId = message.message_thread_id;
|
|
768
|
+
if (!threadId) return undefined;
|
|
769
|
+
const localLabel = deps.getLocalThreadLabelForTarget?.({ chatId, threadId });
|
|
770
|
+
if (localLabel) return localLabel;
|
|
771
|
+
if (!deps.threadStore) return undefined;
|
|
772
|
+
const records = deps.threadStore.list();
|
|
773
|
+
const currentInstanceId = deps.getCurrentInstanceId?.();
|
|
774
|
+
for (const record of records) {
|
|
775
|
+
if (
|
|
776
|
+
record.target.chatId !== chatId ||
|
|
777
|
+
record.target.threadId !== threadId
|
|
778
|
+
) {
|
|
779
|
+
continue;
|
|
780
|
+
}
|
|
781
|
+
if (
|
|
782
|
+
currentInstanceId &&
|
|
783
|
+
record.instanceId &&
|
|
784
|
+
record.instanceId !== currentInstanceId
|
|
785
|
+
) {
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
return record.threadName &&
|
|
789
|
+
Threads.isTelegramTopicThreadNameValidForSlot(
|
|
790
|
+
record.threadName,
|
|
791
|
+
record.slot,
|
|
792
|
+
)
|
|
793
|
+
? record.threadName
|
|
794
|
+
: getRestoredThreadName(record, record.slot ?? "");
|
|
795
|
+
}
|
|
796
|
+
return undefined;
|
|
797
|
+
};
|
|
762
798
|
const createAdmissionReceipts = (
|
|
763
799
|
queueKind: Queue.TelegramQueueItemKind,
|
|
764
800
|
sources: readonly unknown[],
|
|
@@ -1628,6 +1664,13 @@ export function createTelegramInboundRouteRuntime<
|
|
|
1628
1664
|
replyToMessageId: messageId,
|
|
1629
1665
|
queueOrder,
|
|
1630
1666
|
action,
|
|
1667
|
+
telegramPrefix: Turns.createTelegramTurnPrefix({
|
|
1668
|
+
thread: resolveTelegramThreadLabel({
|
|
1669
|
+
chat: { id: chatId },
|
|
1670
|
+
message_thread_id:
|
|
1671
|
+
buttonQuery.message?.message_thread_id,
|
|
1672
|
+
}),
|
|
1673
|
+
}),
|
|
1631
1674
|
}),
|
|
1632
1675
|
...(admissionReceipts.length > 0 ? { admissionReceipts } : {}),
|
|
1633
1676
|
};
|
|
@@ -1770,34 +1813,7 @@ export function createTelegramInboundRouteRuntime<
|
|
|
1770
1813
|
|
|
1771
1814
|
// Voice policy resolves missing, invalid, and legacy manual config to hidden.
|
|
1772
1815
|
getVoiceReplyMode: () => getTelegramVoiceReplyMode(deps.configStore.get()),
|
|
1773
|
-
getTelegramThreadLabel
|
|
1774
|
-
if (!deps.threadStore) return undefined;
|
|
1775
|
-
const chatId = message.chat.id;
|
|
1776
|
-
const threadId = message.message_thread_id;
|
|
1777
|
-
if (!threadId) return undefined;
|
|
1778
|
-
const localLabel = deps.getLocalThreadLabelForTarget?.({
|
|
1779
|
-
chatId,
|
|
1780
|
-
threadId,
|
|
1781
|
-
});
|
|
1782
|
-
if (localLabel) return localLabel;
|
|
1783
|
-
const records = deps.threadStore.list();
|
|
1784
|
-
const currentInstanceId = deps.getCurrentInstanceId?.();
|
|
1785
|
-
for (const r of records) {
|
|
1786
|
-
if (r.target.chatId !== chatId || r.target.threadId !== threadId)
|
|
1787
|
-
continue;
|
|
1788
|
-
if (
|
|
1789
|
-
currentInstanceId &&
|
|
1790
|
-
r.instanceId &&
|
|
1791
|
-
r.instanceId !== currentInstanceId
|
|
1792
|
-
)
|
|
1793
|
-
continue;
|
|
1794
|
-
return r.threadName &&
|
|
1795
|
-
Threads.isTelegramTopicThreadNameValidForSlot(r.threadName, r.slot)
|
|
1796
|
-
? r.threadName
|
|
1797
|
-
: getRestoredThreadName(r, r.slot ?? "");
|
|
1798
|
-
}
|
|
1799
|
-
return undefined;
|
|
1800
|
-
},
|
|
1816
|
+
getTelegramThreadLabel: resolveTelegramThreadLabel,
|
|
1801
1817
|
});
|
|
1802
1818
|
const enqueueContinueTurn = async (
|
|
1803
1819
|
message: TMessage,
|