@segmentstream/agent 0.17.13 → 0.17.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +10 -4
  2. package/dist/_chunks/{build-metadata-DfGc35Vd.mjs → build-metadata-CfQ3J5Jk.mjs} +1 -1
  3. package/dist/_chunks/{inbound-request-DxRm5LC8.mjs → inbound-request-Buuv7b1I.mjs} +15 -14
  4. package/dist/_chunks/{principal-B6u41vIf.mjs → principal-Dmm-cXNF.mjs} +1 -1
  5. package/dist/extension/hooks/authorization.mjs +1 -1
  6. package/dist/extension/lib/attachment-tools.mjs +1 -1
  7. package/dist/extension/lib/build-metadata.mjs +1 -1
  8. package/dist/extension/lib/confirmations.mjs +1 -1
  9. package/dist/extension/lib/conversation-runtime.mjs +1 -1
  10. package/dist/extension/lib/customer-text-safety.mjs +1 -0
  11. package/dist/extension/lib/deferred-confirmations.mjs +1 -1
  12. package/dist/extension/lib/group-routing/cancellation.d.ts +4 -0
  13. package/dist/extension/lib/group-routing/cancellation.mjs +22 -0
  14. package/dist/extension/lib/group-routing/conversation.mjs +11 -4
  15. package/dist/extension/lib/group-routing/dequeue.mjs +1 -1
  16. package/dist/extension/lib/group-routing/routing-context.mjs +1 -1
  17. package/dist/extension/lib/group-routing/signals.d.ts +1 -0
  18. package/dist/extension/lib/group-routing/signals.mjs +1 -1
  19. package/dist/extension/lib/ontology-connection.mjs +1 -1
  20. package/dist/extension/lib/ontology-gateway.mjs +1 -1
  21. package/dist/extension/lib/ontology-metadata-read.mjs +1 -1
  22. package/dist/extension/lib/ontology-tools.mjs +1 -1
  23. package/dist/extension/lib/runtime-envelope.mjs +1 -1
  24. package/dist/extension/lib/stored-files.mjs +1 -1
  25. package/dist/extension/lib/telegram/adapter.mjs +13 -6
  26. package/dist/extension/lib/telegram/attachment-description.mjs +1 -1
  27. package/dist/extension/lib/telegram/attachments-send.mjs +2 -2
  28. package/dist/extension/lib/telegram/callbacks.mjs +2 -2
  29. package/dist/extension/lib/telegram/confirmation-expiry.mjs +1 -1
  30. package/dist/extension/lib/telegram/confirmations.mjs +6 -5
  31. package/dist/extension/lib/telegram/conversations.mjs +2 -2
  32. package/dist/extension/lib/telegram/customer-text.mjs +1 -1
  33. package/dist/extension/lib/telegram/deferred-confirmations.mjs +3 -3
  34. package/dist/extension/lib/telegram/delivery-diagnostics.d.ts +12 -0
  35. package/dist/extension/lib/telegram/delivery-diagnostics.mjs +46 -0
  36. package/dist/extension/lib/telegram/diagnostic-redaction.d.ts +2 -0
  37. package/dist/extension/lib/telegram/diagnostic-redaction.mjs +18 -0
  38. package/dist/extension/lib/telegram/files.mjs +2 -2
  39. package/dist/extension/lib/telegram/health.mjs +1 -1
  40. package/dist/extension/lib/telegram/images.mjs +1 -1
  41. package/dist/extension/lib/telegram/inbound-request.mjs +1 -1
  42. package/dist/extension/lib/telegram/inbound.mjs +3 -3
  43. package/dist/extension/lib/telegram/lifecycle.mjs +5 -4
  44. package/dist/extension/lib/telegram/media-policy.mjs +1 -1
  45. package/dist/extension/lib/telegram/principal.mjs +1 -1
  46. package/dist/extension/lib/telegram/session-recovery.mjs +1 -1
  47. package/dist/extension/lib/telegram/signals.mjs +1 -0
  48. package/dist/extension/lib/telegram/silent.mjs +2 -2
  49. package/dist/extension/lib/telegram/structured.mjs +1 -1
  50. package/dist/extension/lib/telegram/turn-errors.mjs +23 -3
  51. package/dist/extension/lib/telegram/voice.mjs +1 -1
  52. package/dist/extension/model.mjs +1 -1
  53. package/dist/extension/tools/attachments_promote.mjs +1 -1
  54. package/dist/extension/tools/ontology.mjs +1 -1
  55. package/dist/extension/tools/questions_ask.mjs +1 -1
  56. package/package.json +2 -2
package/README.md CHANGED
@@ -311,7 +311,10 @@ share a group chat's session never share a client.
311
311
  messages steer one chat/topic session and other callers are rechecked when dequeued. A durable
312
312
  burst fence prevents a second accepted turn. Claimed mentions and commands survive later
313
313
  human-directed messages in the burst, recorded as `dequeue_explicit_kept`; archive failures
314
- and duplicate claims still cancel. See [group configuration](../../docs/agent.md#groups).
314
+ and duplicate claims still cancel. Duplicate and observe cancellations remain silent
315
+ at Telegram delivery, including callback replay. Other turn cancellations use `texts.notice.cancelled` with a symbol fallback; an unconfigured
316
+ failure notice never consists only of a reference. Diagnostics remain in operator logs.
317
+ See [group configuration](../../docs/agent.md#groups).
315
318
  - **Voice.** Voice messages, audio files and video notes are downloaded through the connection and
316
319
  transcribed with `models.stt` through AI Gateway before the turn.
317
320
  The transcript becomes the message, with a note such as `[voice message, 12 s]` in
@@ -576,7 +579,9 @@ applies bounded credential and file-byte redaction, and ingestion preserves the
576
579
  Deploy backend migration 0043/API before upgrading to agent SDK 0.6.10.
577
580
  `segmentstream agent logs` and its `show`/`call` commands read this content
578
581
  with a human Cloud session; all members with workspace access can read DMs too.
579
- Runtime/model/MCP conversation readers never receive these new fields.
582
+ Runtime/model/MCP conversation readers never receive these new fields. Telegram delivery diagnostics
583
+ retain their correlation reference, operation and redacted error in the same archive before the
584
+ channel callback returns, so a notice remains diagnosable after runtime logs expire.
580
585
 
581
586
  Archive metadata and message text retain the workspace policy (365 days by default).
582
587
  Platform REST reads, the workspace ontology's
@@ -673,10 +678,11 @@ before business completion. Persist bill/result receipts and resume by business
673
678
  identity after later uploads; a collection timer alone is insufficient.
674
679
 
675
680
  The adapter retains the queued-turn policy, checks durable inbox acknowledgement,
676
- and anchors delivery to the immutable source message/topic. An intake webhook
681
+ and anchors delivery to the immutable source message/topic. Every admitted text or intake webhook
677
682
  uses its host `waitUntil` lifetime to follow the durable session stream and refresh
678
683
  Telegram typing every four seconds; completion, human input, cancellation,
679
- failure, abort and the ten-minute observation bound close the reader and timer.
684
+ failure or abort close the reader and timer. There is no fixed ten-minute cutoff;
685
+ monitoring remains bounded by the host request lifetime. This is not a separate durable heartbeat workflow.
680
686
  Safe phase telemetry distinguishes admission, storage, queue acceptance and the
681
687
  owning turn without recording file contents or grants.
682
688
 
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- var version = "0.17.13";
7
+ var version = "0.17.15";
8
8
  function agentBuild(environment = process.env) {
9
9
  return {
10
10
  agent: version,
@@ -6,11 +6,12 @@ __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { telegramText } from "../extension/lib/telegram/texts.mjs";
8
8
  import { isTechnicalText } from "../extension/lib/customer-text-safety.mjs";
9
- import { redactDiagnostic } from "../extension/lib/diagnostics.mjs";
9
+ import { redactTelegramDiagnostic } from "../extension/lib/telegram/diagnostic-redaction.mjs";
10
10
  import { isConfirmationText } from "../extension/lib/telegram/confirmation-text.mjs";
11
11
  import { chatPostCardLinks, isExactChatPostCard } from "../extension/lib/telegram/chat-post-card.mjs";
12
12
  import { plainTelegramText, splitTelegramText, telegramMarkdown } from "../extension/lib/telegram/format.mjs";
13
13
  import { inTelegramSendQueue } from "../extension/lib/telegram/send-queue.mjs";
14
+ import { retainDeliveryDiagnostic } from "../extension/lib/telegram/delivery-diagnostics.mjs";
14
15
  import { randomBytes, randomUUID } from "node:crypto";
15
16
  import { AsyncLocalStorage } from "node:async_hooks";
16
17
  import { telegramPreviewOptions, telegramTextLinks } from "@segmentstream-cloud/ontology/telegram";
@@ -41,26 +42,26 @@ function customerCopy(locale = currentLocale()) {
41
42
  cancelled: telegramText("notice", "cancelled", locale)
42
43
  };
43
44
  }
44
- function redactCredentials(value) {
45
- if (typeof value === "string") return value.replace(/\bBearer [A-Za-z0-9_.~+/-]+=*/giu, "Bearer [redacted]").replace(/(https?:\/\/)[^/@\s]+:[^/@\s]+@/gu, "$1[redacted]@").replace(/([?&](?:token|access_token|api_key|secret|password)=)[^&#\s]*/giu, "$1[redacted]").replace(/("(?:token|api_key|password|secret)"\s*:\s*)"(?:\\.|[^"\\])*"/giu, "$1\"[redacted]\"");
46
- if (Array.isArray(value)) return value.map(redactCredentials);
47
- if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, /^(?:token|password|secret|authorization|cookie|api_?key|access_?token|refresh_?token)$/iu.test(key) && typeof item === "string" ? "[redacted]" : redactCredentials(item)]));
48
- return value;
49
- }
50
45
  function reportTelegramError(operation, error, metadata = {}, secrets = new Set()) {
51
46
  const errorId = randomBytes(4).toString("hex");
52
- const credentials = new Set([...secrets, ...[process.env.AI_GATEWAY_API_KEY, process.env.VERCEL_OIDC_TOKEN].filter((value) => value !== void 0)]);
47
+ const redactedError = redactTelegramDiagnostic(error, secrets);
48
+ const redactedMetadata = redactTelegramDiagnostic(metadata, secrets);
53
49
  console.error("[segmentstream] Telegram delivery diagnostic", {
54
- ...metadata,
50
+ ...redactedMetadata,
51
+ errorId,
52
+ operation,
53
+ error: redactedError
54
+ });
55
+ retainDeliveryDiagnostic({
55
56
  errorId,
56
57
  operation,
57
- error: redactCredentials(redactDiagnostic(error, credentials))
58
+ error: redactedError,
59
+ metadata: redactedMetadata
58
60
  });
59
61
  return errorId;
60
62
  }
61
63
  function failureText(errorId, kind = "failed", _locale = currentLocale()) {
62
- const text = customerCopy(_locale)[kind];
63
- return text === void 0 ? errorId : `${text} ${errorId}`;
64
+ return `${customerCopy(_locale)[kind] ?? (kind === "cancelled" ? "⏹" : "⚠️")} ${errorId}`;
64
65
  }
65
66
  function customerText(text, locale = currentLocale()) {
66
67
  if (!isTechnicalText(text)) return text;
@@ -324,8 +325,8 @@ function withReplacedText(source, request) {
324
325
  return {
325
326
  ...source,
326
327
  async send(message, options) {
327
- const marker = request.lifecycleKey === void 0 || request.replyTo === void 0 ? void 0 : `[source-message:${request.replyTo};trigger:${request.triggeringMessageId ?? request.replyTo}]`;
328
- const replacement = marker === void 0 ? request.text : `${marker}\n${request.text ?? (typeof message === "string" ? message : "")}`;
328
+ const marker = request.replyTo === void 0 ? void 0 : `[source-message:${request.replyTo};trigger:${request.triggeringMessageId ?? request.replyTo}]`;
329
+ const replacement = marker === void 0 ? request.text : `${marker}\n${request.text ?? (typeof message === "string" ? message : message.filter((part) => part.type === "text").map((part) => part.text).join("\n"))}`;
329
330
  const text = replacement === void 0 ? message : replaceText(message, replacement);
330
331
  const files = request.files === void 0 ? text : replaceFiles(text, request.files);
331
332
  const content = request.extraFiles === void 0 || request.extraFiles.length === 0 ? files : [...typeof files === "string" ? [{
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { n as currentInboundRequest } from "./inbound-request-DxRm5LC8.mjs";
7
+ import { n as currentInboundRequest } from "./inbound-request-Buuv7b1I.mjs";
8
8
  import { randomUUID } from "node:crypto";
9
9
  function telegramRuntimeSource(message, files, callbackQueryId) {
10
10
  const attachments = [];
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { localizedText } from "../lib/admission.mjs";
8
- import "../../_chunks/principal-B6u41vIf.mjs";
8
+ import "../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { confirmationLocale } from "../lib/telegram/confirmation-text.mjs";
10
10
  import segmentstream from "../extension.mjs";
11
11
  import { defineHook } from "eve/hooks";
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
- import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { runtimeToken } from "./runtime-token.mjs";
10
10
  import { agentAttachments } from "./attachments.mjs";
11
11
  import { telegramConversation } from "./telegram/files.mjs";
@@ -4,5 +4,5 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { t as agentBuild } from "../../_chunks/build-metadata-DfGc35Vd.mjs";
7
+ import { t as agentBuild } from "../../_chunks/build-metadata-CfQ3J5Jk.mjs";
8
8
  export { agentBuild };
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { withTelegramTexts } from "./telegram/texts.mjs";
8
- import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { confirmationCopy, confirmationLocale, renderConfirmation } from "./telegram/confirmation-text.mjs";
10
10
  import { chatPostCard } from "./telegram/chat-post-card.mjs";
11
11
  import { chatPostDigest, isChatPost } from "./chat-post-confirmation.mjs";
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { ENDS_CONVERSATION_INSTRUCTIONS } from "./group-routing/conversation-prompt.mjs";
8
- import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { n as contentText, t as CONTENT_CAPS } from "../../_chunks/content-TRaZitQZ.mjs";
10
10
  import { conversationEvent, conversations, sessionFailureEventId, summarizeArguments } from "./conversations.mjs";
11
11
  import { parseAddress } from "./telegram/sessions.mjs";
@@ -5,6 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  const TECHNICAL_PATTERNS = [
8
+ /^\s*(?=[0-9a-f]*[a-f])[0-9a-f]{8}\s*$/iu,
8
9
  /[{}]|```/u,
9
10
  /\b(?:hq:)?[0-9a-f]{64}\b/iu,
10
11
  /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/iu,
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
- import { i as memberIdOf, l as principalRuntimeSource, u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
8
+ import { i as memberIdOf, l as principalRuntimeSource, u as runtimeEnvelope } from "../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { redactDiagnostic } from "./diagnostics.mjs";
10
10
  import { humanText, object } from "./confirmation-description.mjs";
11
11
  import { runtimeToken } from "./runtime-token.mjs";
@@ -0,0 +1,4 @@
1
+ import type { SessionContext } from "eve/context";
2
+ import type { Conversations } from "../conversations.js";
3
+ /** The durable routing verdict owns silence, including after a channel callback is replayed. */
4
+ export declare function isSilentRoutingCancellation(archive: Conversations, context: SessionContext, turnId: string): Promise<boolean>;
@@ -0,0 +1,22 @@
1
+ import { fileURLToPath as __eveFileURLToPath } from "node:url";
2
+ import { dirname as __eveDirname } from "node:path";
3
+ import { createRequire as __eveCreateRequire } from "node:module";
4
+ const __filename = __eveFileURLToPath(import.meta.url);
5
+ __eveDirname(__filename);
6
+ __eveCreateRequire(import.meta.url);
7
+ async function isSilentRoutingCancellation(archive, context, turnId) {
8
+ const principal = context.session.auth.current;
9
+ const attributes = principal?.attributes;
10
+ if (principal?.authenticator !== "segmentstream-telegram" || typeof attributes?.groupRouting !== "string" || attributes.chatType !== "group" && attributes.chatType !== "supergroup" || typeof attributes.chatId !== "string") return false;
11
+ const { events } = await archive.context({
12
+ provider: "telegram",
13
+ chatId: attributes.chatId,
14
+ ...typeof attributes.messageThreadId === "string" ? { threadId: attributes.messageThreadId } : {},
15
+ limit: 200,
16
+ includeDecisions: true,
17
+ ...typeof attributes.replyToMessageId === "string" ? { messageId: attributes.replyToMessageId } : {}
18
+ });
19
+ const scoped = events.filter((event) => event.provider === "telegram" && event.chatId === attributes.chatId && event.threadId === (attributes.messageThreadId ?? null) && event.sessionId === context.session.id && event.turnId === turnId && event.kind === "decision");
20
+ return scoped.some((event) => event.decision === "silent" && (event.reason === "burst_already_answered" || event.reason === "dequeue_observe")) || !scoped.some((event) => event.decision === "reply" && (event.reason === "burst_turn_started" || event.reason === "dequeue_reply"));
21
+ }
22
+ export { isSilentRoutingCancellation };
@@ -38,14 +38,20 @@ function conversationAddressing(signals, recent, policy, agentNames = []) {
38
38
  const trailing = /,\s*([\p{L}\p{N}_-]{2,})\s*[?!.)»"”]*\s*$/u.exec(signals.derived?.transcript ?? signals.message.text)?.[1];
39
39
  const named = signals.addressing.agentMentioned || signals.addressing.command || [punctuated, trailing].some((n) => n !== void 0 && agents.has(norm(n))) || mentions.some((m) => m.kind === "bot" || agents.has(norm(m.username ?? m.externalId ?? "")));
40
40
  const humans = new Set();
41
- for (const m of mentions) if (m.kind !== "bot" && !agents.has(norm(m.username ?? m.externalId ?? ""))) humans.add(canonical(m.externalId ?? m.username ?? "unknown"));
41
+ const terminalMention = /@([A-Za-z0-9_]+)\s*[.!?]*\s*$/u.exec(signals.message.text)?.[1];
42
+ const replyToAgent = signals.addressing.replyTo?.author === "agent" || signals.addressing.threadWithAgent === true;
43
+ let soft;
44
+ for (const m of mentions) if (m.kind !== "bot" && !agents.has(norm(m.username ?? m.externalId ?? ""))) {
45
+ const target = canonical(m.externalId ?? m.username ?? "unknown");
46
+ if (replyToAgent && m.type !== "text_mention" && m.username !== void 0 && !names.some((name) => canonical(name) === target) && (terminalMention === void 0 || canonical(terminalMention) !== target)) soft = target;
47
+ else humans.add(target);
48
+ }
42
49
  const known = new Set([...Object.keys(policy.participants), ...recent.filter((m) => !own(m)).map((m) => canonical(m.authorId ?? m.username ?? m.author))]);
43
50
  for (const name of names) {
44
51
  const id = canonical(name);
45
52
  if (known.has(id) && id !== sender && !agents.has(name)) humans.add(id);
46
53
  }
47
54
  const reply = signals.addressing.replyTo;
48
- let soft;
49
55
  if (reply && reply.author !== "agent" && !reply.self) {
50
56
  const parent = recent.find((m) => m.messageId === reply.messageId);
51
57
  const id = canonical(reply.authorExternalId ?? reply.authorUsername ?? parent?.authorId ?? parent?.username ?? reply.authorName ?? "unknown");
@@ -58,7 +64,7 @@ function conversationAddressing(signals, recent, policy, agentNames = []) {
58
64
  }
59
65
  return {
60
66
  agent_named: named,
61
- reply_to_agent: reply?.author === "agent" || signals.addressing.threadWithAgent === true,
67
+ reply_to_agent: replyToAgent,
62
68
  human_targets: [...humans],
63
69
  ...soft ? { soft_target: soft } : {}
64
70
  };
@@ -86,6 +92,7 @@ function recordedMessageSignals(m, current) {
86
92
  command: m.invitation === "command",
87
93
  threadWithAgent: m.invitation === "thread-with-agent",
88
94
  mentions: (m.taggedUsers ?? []).map((t) => ({
95
+ type: t.type,
89
96
  externalId: t.id,
90
97
  username: t.username,
91
98
  kind: t.kind
@@ -160,7 +167,7 @@ function conversationState(input) {
160
167
  let state = states.get(person);
161
168
  expire(state, t);
162
169
  const wasActive = state?.status === "active";
163
- const explicit = evidence.agent_named || evidence.reply_to_agent && evidence.human_targets.length === 0;
170
+ const explicit = evidence.agent_named || evidence.reply_to_agent && evidence.human_targets.length === 0 && evidence.soft_target === void 0;
164
171
  let path;
165
172
  if (explicit) {
166
173
  path = "A";
@@ -4,11 +4,11 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
+ import { conversationEvent, conversations } from "../conversations.mjs";
7
8
  import { addressingReason } from "./signals.mjs";
8
9
  import { recordedMessageSignals } from "./conversation.mjs";
9
10
  import { conversationDecisionRouter } from "./conversation-router.mjs";
10
11
  import { routeMessage } from "./router.mjs";
11
- import { conversationEvent, conversations } from "../conversations.mjs";
12
12
  import { archivedRoutingMessages } from "./routing-context.mjs";
13
13
  import { routingBurst } from "./burst.mjs";
14
14
  import { conversationCoordinates } from "../conversation-runtime.mjs";
@@ -4,8 +4,8 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { agentMessage } from "./observed.mjs";
8
7
  import { collapseConversationEvents } from "../conversations.mjs";
8
+ import { agentMessage } from "./observed.mjs";
9
9
  function archivedMetadata(event) {
10
10
  try {
11
11
  return JSON.parse(event.argsSummary ?? "null")?.routing ?? {};
@@ -53,6 +53,7 @@ export interface GroupMessageSignals {
53
53
  readonly self?: boolean;
54
54
  };
55
55
  readonly mentions: ReadonlyArray<{
56
+ readonly type?: "mention" | "text_mention";
56
57
  readonly externalId?: string;
57
58
  readonly username?: string;
58
59
  readonly kind: "human" | "bot" | "other_bot" | "unknown";
@@ -17,7 +17,7 @@ function signalAudience(signals) {
17
17
  kind: m.kind,
18
18
  id: m.externalId,
19
19
  username: m.username,
20
- type: "mention",
20
+ type: m.type ?? "mention",
21
21
  text: m.username === void 0 ? "" : `@${m.username}`
22
22
  })),
23
23
  replyTo: reply === void 0 ? null : {
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
- import { c as compatibleRuntimeEnvelope, i as memberIdOf, r as identityProviderOf, u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
8
+ import { c as compatibleRuntimeEnvelope, i as memberIdOf, r as identityProviderOf, u as runtimeEnvelope } from "../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { runtimeToken, tokenExpiry } from "./runtime-token.mjs";
10
10
  import { CHAT_POST_ENVELOPE, chatPostDigest, chatPostOperationId, isChatPost } from "./chat-post-confirmation.mjs";
11
11
  import { actionApproval, confirmations } from "./confirmations.mjs";
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { i as memberIdOf, u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
7
+ import { i as memberIdOf, u as runtimeEnvelope } from "../../_chunks/principal-Dmm-cXNF.mjs";
8
8
  import { object } from "./confirmation-description.mjs";
9
9
  import { readOntologyMetadata } from "./ontology-metadata-read.mjs";
10
10
  async function ontologyMetadata(memberId, operation, input, context, options = {}) {
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
- import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { redactDiagnostic } from "./diagnostics.mjs";
10
10
  import { object } from "./confirmation-description.mjs";
11
11
  import { OntologyToolRejected, ontologyTools } from "./ontology-tools.mjs";
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
- import { c as compatibleRuntimeEnvelope, i as memberIdOf, r as identityProviderOf, s as RUNTIME_SOURCE_PROTOCOL, u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
8
+ import { c as compatibleRuntimeEnvelope, i as memberIdOf, r as identityProviderOf, s as RUNTIME_SOURCE_PROTOCOL, u as runtimeEnvelope } from "../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { redactDiagnostic } from "./diagnostics.mjs";
10
10
  import { describeConfirmation, object } from "./confirmation-description.mjs";
11
11
  import { runtimeToken } from "./runtime-token.mjs";
@@ -4,5 +4,5 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { c as compatibleRuntimeEnvelope, d as telegramRuntimeSource, l as principalRuntimeSource, s as RUNTIME_SOURCE_PROTOCOL, u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
7
+ import { c as compatibleRuntimeEnvelope, d as telegramRuntimeSource, l as principalRuntimeSource, s as RUNTIME_SOURCE_PROTOCOL, u as runtimeEnvelope } from "../../_chunks/principal-Dmm-cXNF.mjs";
8
8
  export { RUNTIME_SOURCE_PROTOCOL, compatibleRuntimeEnvelope, principalRuntimeSource, runtimeEnvelope, telegramRuntimeSource };
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
7
+ import { i as memberIdOf } from "../../_chunks/principal-Dmm-cXNF.mjs";
8
8
  import { redactDiagnostic } from "./diagnostics.mjs";
9
9
  import { object } from "./confirmation-description.mjs";
10
10
  import { OntologyFileUnavailable, ontologyTools } from "./ontology-tools.mjs";
@@ -7,20 +7,21 @@ __eveCreateRequire(import.meta.url);
7
7
  import { telegramText, withTelegramTexts } from "./texts.mjs";
8
8
  import { manifestOf } from "../../config.mjs";
9
9
  import { appOrigin, channelsEnabled, proxyEnvironment, runtimeIdentityEnvironment, webhookSecret } from "../environment.mjs";
10
- import { n as conversationLanguage, o as telegramPrincipal } from "../../../_chunks/principal-B6u41vIf.mjs";
10
+ import { n as conversationLanguage, o as telegramPrincipal } from "../../../_chunks/principal-Dmm-cXNF.mjs";
11
11
  import { confirmationLocale } from "./confirmation-text.mjs";
12
12
  import { telegramSendScope } from "./send-queue.mjs";
13
- import { d as failureText, h as withDeliveryLocale, i as withReplacedText, m as safeTelegramFetch, n as currentInboundRequest, o as currentLocale, p as reportTelegramError, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
13
+ import { runtimeToken } from "../runtime-token.mjs";
14
+ import { conversations } from "../conversations.mjs";
15
+ import { withDeliveryDiagnostics } from "./delivery-diagnostics.mjs";
16
+ import { d as failureText, h as withDeliveryLocale, i as withReplacedText, m as safeTelegramFetch, n as currentInboundRequest, o as currentLocale, p as reportTelegramError, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
14
17
  import { chooseModel } from "../../model.mjs";
15
18
  import { groupRoutingHealth } from "../group-routing/health.mjs";
16
19
  import { decisionRouter } from "../group-routing/router.mjs";
17
- import { runtimeToken } from "../runtime-token.mjs";
18
- import { conversations } from "../conversations.mjs";
19
20
  import { archivedRoutingMessages } from "../group-routing/routing-context.mjs";
20
21
  import { dispatchStructuredMessage, structuredMessage } from "./structured.mjs";
21
22
  import { scopedAddress, sessionPolicy } from "./sessions.mjs";
22
23
  import { handleWorkspaceCallback, isWorkspaceCallback } from "./callbacks.mjs";
23
- import { t as agentBuild } from "../../../_chunks/build-metadata-DfGc35Vd.mjs";
24
+ import { t as agentBuild } from "../../../_chunks/build-metadata-CfQ3J5Jk.mjs";
24
25
  import { attachmentLifecycle } from "./lifecycle.mjs";
25
26
  import { observedMessages } from "./observed.mjs";
26
27
  import { expireDeferredCards, handleDeferredCallback, isDeferredCallback } from "./deferred-confirmations.mjs";
@@ -478,7 +479,13 @@ function segmentstreamTelegram(options) {
478
479
  const locale = confirmationLocale(principal ?? null, context.state.customerLocale ?? "en");
479
480
  context.state.customerLocale = locale;
480
481
  await withDeliveryLocale(locale, async () => {
481
- await withTelegramTexts(options.admission?.().texts ?? {}, () => handler(event, context), currentLocale);
482
+ await withTelegramTexts(options.admission?.().texts ?? {}, () => withDeliveryDiagnostics(archive, {
483
+ chatId: String(context.state.chatId),
484
+ chatType: String(context.state.chatId).startsWith("-") ? "group" : "private",
485
+ threadId: context.state.messageThreadId == null ? null : String(context.state.messageThreadId),
486
+ sessionId: context.session?.id ?? null,
487
+ turnId: typeof event === "object" && event !== null && "turnId" in event && typeof event.turnId === "string" ? event.turnId : null
488
+ }, () => handler(event, context)), currentLocale);
482
489
  }, context.state.messageThreadId === null ? void 0 : String(context.state.messageThreadId), typeof principal?.attributes.replyToMessageId === "string" ? principal.attributes.replyToMessageId : void 0, typeof principal?.attributes.chatId === "string" ? principal.attributes.chatId : void 0);
483
490
  }]))
484
491
  } },
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
8
8
  import { describableImage } from "./images.mjs";
9
9
  import { MAXIMUM_ROUTING_PDF_CHARACTERS, extractRoutingPdf } from "./pdf-text.mjs";
10
10
  import { gateway, generateText } from "ai";
@@ -5,12 +5,12 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin, channelsEnabled, proxyEnvironment } from "../environment.mjs";
8
- import "../../../_chunks/principal-B6u41vIf.mjs";
8
+ import "../../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { redactDiagnostic } from "../diagnostics.mjs";
10
10
  import { confirmationLocale } from "./confirmation-text.mjs";
11
11
  import { inTelegramSendQueue, telegramSendScope } from "./send-queue.mjs";
12
- import { d as failureText, f as formattingRefused, l as customerMessage, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
13
12
  import { runtimeToken } from "../runtime-token.mjs";
13
+ import { d as failureText, f as formattingRefused, l as customerMessage, p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
14
14
  import { MAXIMUM_PROXY_BODY_BYTES, connectionProxy } from "../connection-proxy.mjs";
15
15
  import { ACT_AS_HEADER } from "../ontology-connection.mjs";
16
16
  import { AttachmentError, CONVERSATION_HEADER, SESSION_HEADER } from "../attachments.mjs";
@@ -6,9 +6,9 @@ __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { admitMessage } from "../admission.mjs";
8
8
  import { telegramText } from "./texts.mjs";
9
- import { d as telegramRuntimeSource, i as memberIdOf, o as telegramPrincipal, u as runtimeEnvelope } from "../../../_chunks/principal-B6u41vIf.mjs";
9
+ import { d as telegramRuntimeSource, i as memberIdOf, o as telegramPrincipal, u as runtimeEnvelope } from "../../../_chunks/principal-Dmm-cXNF.mjs";
10
10
  import { object } from "../confirmation-description.mjs";
11
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
11
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
12
12
  import { workspaceAction } from "./workspace-action.mjs";
13
13
  import { formatAddress, parseAddress, scopedAddress } from "./sessions.mjs";
14
14
  const isWorkspaceCallback = (data) => data?.startsWith("ws:") === true;
@@ -7,9 +7,9 @@ __eveCreateRequire(import.meta.url);
7
7
  import { withTelegramTexts } from "./texts.mjs";
8
8
  import { proxyEnvironment } from "../environment.mjs";
9
9
  import { telegramSendScope } from "./send-queue.mjs";
10
- import { m as safeTelegramFetch, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
11
10
  import { runtimeToken } from "../runtime-token.mjs";
12
11
  import { conversations } from "../conversations.mjs";
12
+ import { m as safeTelegramFetch, p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
13
13
  import { deferredConfirmations } from "../deferred-confirmations.mjs";
14
14
  import { expireDeferredRecord } from "./deferred-confirmations.mjs";
15
15
  import { connectionProxy } from "../connection-proxy.mjs";
@@ -5,13 +5,13 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { telegramText } from "./texts.mjs";
8
- import { i as memberIdOf, o as telegramPrincipal } from "../../../_chunks/principal-B6u41vIf.mjs";
8
+ import { i as memberIdOf, o as telegramPrincipal } from "../../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { humanText } from "../confirmation-description.mjs";
10
10
  import { renderConfirmation, withConfirmationText } from "./confirmation-text.mjs";
11
11
  import { chatPostCard, chatPostCardStatus, chatPostReceipt, withChatPostCard } from "./chat-post-card.mjs";
12
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
13
- import { agentMessage, observedChatKey, withConfirmationPrompt } from "../group-routing/observed.mjs";
14
12
  import { conversationEvent } from "../conversations.mjs";
13
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
14
+ import { agentMessage, observedChatKey, withConfirmationPrompt } from "../group-routing/observed.mjs";
15
15
  import { chatPostOperationId, isChatPost } from "../chat-post-confirmation.mjs";
16
16
  import { confirmations } from "../confirmations.mjs";
17
17
  import { formatAddress, scopedAddress } from "./sessions.mjs";
@@ -109,8 +109,9 @@ function questionsFromHistory(events) {
109
109
  const candidate = object(result.output).pendingQuestion;
110
110
  if (typeof result.toolName === "string" && result.toolName.endsWith("__questions_ask") && isPendingQuestion(candidate)) pending.set(questionKey(candidate), candidate);
111
111
  }
112
- if (event.type === "message.received" && typeof data.message === "string" && data.message.startsWith("[Answer to pending question ")) {
113
- for (const [key, question] of pending) if (data.message.startsWith(answerMarker(question.id))) pending.delete(key);
112
+ if (event.type === "message.received" && typeof data.message === "string") {
113
+ const message = data.message.replace(/^\[source-message:\d+;trigger:\d+\]\r?\n/u, "");
114
+ for (const [key, question] of pending) if (message.startsWith(answerMarker(question.id))) pending.delete(key);
114
115
  }
115
116
  }
116
117
  return [...pending.values()];
@@ -4,10 +4,10 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { n as currentInboundRequest, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
8
7
  import { n as contentText, t as CONTENT_CAPS } from "../../../_chunks/content-TRaZitQZ.mjs";
9
- import { currentConfirmationPrompt, observedChatKey } from "../group-routing/observed.mjs";
10
8
  import { conversationEvent, sessionFailureEventId } from "../conversations.mjs";
9
+ import { n as currentInboundRequest, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
10
+ import { currentConfirmationPrompt, observedChatKey } from "../group-routing/observed.mjs";
11
11
  import { archivedRoutingMessages } from "../group-routing/routing-context.mjs";
12
12
  import { contentShape, messageContent } from "./content.mjs";
13
13
  import { messageMetadata } from "./observed.mjs";
@@ -5,5 +5,5 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { isTechnicalText } from "../customer-text-safety.mjs";
8
- import { a as TelegramDeliveryError, c as customerCopy, d as failureText, f as formattingRefused, h as withDeliveryLocale, l as customerMessage, m as safeTelegramFetch, o as currentLocale, p as reportTelegramError, s as currentThreadId, u as customerText } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
8
+ import { a as TelegramDeliveryError, c as customerCopy, d as failureText, f as formattingRefused, h as withDeliveryLocale, l as customerMessage, m as safeTelegramFetch, o as currentLocale, p as reportTelegramError, s as currentThreadId, u as customerText } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
9
9
  export { TelegramDeliveryError, currentLocale, currentThreadId, customerCopy, customerMessage, customerText, failureText, formattingRefused, isTechnicalText, reportTelegramError, safeTelegramFetch, withDeliveryLocale };
@@ -5,13 +5,13 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { telegramText, withTelegramLocale } from "./texts.mjs";
8
- import { o as telegramPrincipal } from "../../../_chunks/principal-B6u41vIf.mjs";
8
+ import { o as telegramPrincipal } from "../../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { humanText } from "../confirmation-description.mjs";
10
10
  import { renderConfirmation, withConfirmationText } from "./confirmation-text.mjs";
11
11
  import { chatPostCard, chatPostCardStatus, chatPostReceipt, withChatPostCard } from "./chat-post-card.mjs";
12
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
13
- import { agentMessage, observedChatKey, withConfirmationPrompt } from "../group-routing/observed.mjs";
14
12
  import { conversationEvent } from "../conversations.mjs";
13
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
14
+ import { agentMessage, observedChatKey, withConfirmationPrompt } from "../group-routing/observed.mjs";
15
15
  import { CONFIRMATION_TTL_MS, inputHash } from "../confirmations.mjs";
16
16
  import { OntologyToolRejected } from "../ontology-tools.mjs";
17
17
  import { formatAddress } from "./sessions.mjs";
@@ -0,0 +1,12 @@
1
+ import { type ConversationEvent, type Conversations } from "../conversations.js";
2
+ interface Diagnostic {
3
+ readonly errorId: string;
4
+ readonly operation: string;
5
+ readonly error: unknown;
6
+ readonly metadata: Record<string, unknown>;
7
+ }
8
+ /** Receives the same credential-redacted payload as operator logs, never raw provider errors. */
9
+ export declare function retainDeliveryDiagnostic(diagnostic: Diagnostic): void;
10
+ /** Await archive writes inside the channel callback, including failed or restored callbacks. */
11
+ export declare function withDeliveryDiagnostics<T>(archive: Conversations, scope: Pick<ConversationEvent, "chatId" | "chatType" | "threadId" | "sessionId" | "turnId">, run: () => T | Promise<T>): Promise<T>;
12
+ export {};
@@ -0,0 +1,46 @@
1
+ import { fileURLToPath as __eveFileURLToPath } from "node:url";
2
+ import { dirname as __eveDirname } from "node:path";
3
+ import { createRequire as __eveCreateRequire } from "node:module";
4
+ const __filename = __eveFileURLToPath(import.meta.url);
5
+ __eveDirname(__filename);
6
+ __eveCreateRequire(import.meta.url);
7
+ import { redactTelegramDiagnostic } from "./diagnostic-redaction.mjs";
8
+ import { n as contentText, t as CONTENT_CAPS } from "../../../_chunks/content-TRaZitQZ.mjs";
9
+ import { conversationEvent } from "../conversations.mjs";
10
+ import { AsyncLocalStorage } from "node:async_hooks";
11
+ const pending = new AsyncLocalStorage();
12
+ function retainDeliveryDiagnostic(diagnostic) {
13
+ pending.getStore()?.push(diagnostic);
14
+ }
15
+ async function withDeliveryDiagnostics(archive, scope, run) {
16
+ const diagnostics = [];
17
+ return pending.run(diagnostics, async () => {
18
+ try {
19
+ return await run();
20
+ } finally {
21
+ for (const diagnostic of diagnostics) try {
22
+ await archive.append(conversationEvent({
23
+ ...scope,
24
+ provider: "telegram",
25
+ eventId: `telegram:diagnostic:${diagnostic.errorId}`,
26
+ kind: "decision",
27
+ decision: "silent",
28
+ status: "failed",
29
+ reason: "telegram_delivery_diagnostic",
30
+ argsSummary: JSON.stringify({
31
+ errorId: diagnostic.errorId,
32
+ operation: diagnostic.operation,
33
+ ...diagnostic.metadata
34
+ }),
35
+ errorText: contentText(diagnostic.error, CONTENT_CAPS.error)
36
+ }));
37
+ } catch (error) {
38
+ console.error("[segmentstream] delivery diagnostic archive unavailable", {
39
+ errorId: diagnostic.errorId,
40
+ error: redactTelegramDiagnostic(error)
41
+ });
42
+ }
43
+ }
44
+ });
45
+ }
46
+ export { retainDeliveryDiagnostic, withDeliveryDiagnostics };
@@ -0,0 +1,2 @@
1
+ /** Preserve error stacks and causes while removing credentials from Telegram diagnostics. */
2
+ export declare function redactTelegramDiagnostic(value: unknown, secrets?: ReadonlySet<string>): unknown;
@@ -0,0 +1,18 @@
1
+ import { fileURLToPath as __eveFileURLToPath } from "node:url";
2
+ import { dirname as __eveDirname } from "node:path";
3
+ import { createRequire as __eveCreateRequire } from "node:module";
4
+ const __filename = __eveFileURLToPath(import.meta.url);
5
+ __eveDirname(__filename);
6
+ __eveCreateRequire(import.meta.url);
7
+ import { redactDiagnostic } from "../diagnostics.mjs";
8
+ function redactCredentials(value) {
9
+ if (typeof value === "string") return value.replace(/\bBearer [A-Za-z0-9_.~+/-]+=*/giu, "Bearer [redacted]").replace(/(https?:\/\/)[^/@\s]+:[^/@\s]+@/gu, "$1[redacted]@").replace(/([?&](?:token|access_token|api_key|secret|password)=)[^&#\s]*/giu, "$1[redacted]").replace(/("(?:token|api_key|password|secret)"\s*:\s*)"(?:\\.|[^"\\])*"/giu, "$1\"[redacted]\"");
10
+ if (Array.isArray(value)) return value.map(redactCredentials);
11
+ if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, /^(?:token|password|secret|authorization|cookie|api_?key|access_?token|refresh_?token)$/iu.test(key) && typeof item === "string" ? "[redacted]" : redactCredentials(item)]));
12
+ return value;
13
+ }
14
+ function redactTelegramDiagnostic(value, secrets = new Set()) {
15
+ const credentials = new Set([...secrets, ...[process.env.AI_GATEWAY_API_KEY, process.env.VERCEL_OIDC_TOKEN].filter((item) => item !== void 0)]);
16
+ return redactCredentials(redactDiagnostic(value, credentials));
17
+ }
18
+ export { redactTelegramDiagnostic };
@@ -4,8 +4,8 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { n as conversationLanguage } from "../../../_chunks/principal-B6u41vIf.mjs";
8
- import { d as failureText, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
7
+ import { n as conversationLanguage } from "../../../_chunks/principal-Dmm-cXNF.mjs";
8
+ import { d as failureText, p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
9
9
  import { describableImage, describeReceivedImage } from "./images.mjs";
10
10
  import { MAXIMUM_ATTACHMENT_BYTES, attachmentUrl } from "../attachments.mjs";
11
11
  function telegramConversation(chatId) {
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { t as agentBuild } from "../../../_chunks/build-metadata-DfGc35Vd.mjs";
7
+ import { t as agentBuild } from "../../../_chunks/build-metadata-CfQ3J5Jk.mjs";
8
8
  import { runtimeRequestFailure } from "./runtime-request.mjs";
9
9
  import { GET } from "eve/channels";
10
10
  const HEALTH_ROUTE = "/eve/v1/telegram/health";
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
8
8
  import { gateway, generateText } from "ai";
9
9
  const MAXIMUM_IMAGE_DESCRIPTION_BYTES = 5242880;
10
10
  const MAXIMUM_NATIVE_IMAGE_BYTES = 3145728;
@@ -4,5 +4,5 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { i as withReplacedText, n as currentInboundRequest, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
7
+ import { i as withReplacedText, n as currentInboundRequest, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
8
8
  export { InboundRequest, currentInboundRequest, runInboundRequest, withReplacedText };
@@ -6,8 +6,8 @@ __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { effectiveGroupPolicy, groupPolicy } from "../group-routing/policy.mjs";
8
8
  import { admitMessage, localizedText } from "../admission.mjs";
9
- import { d as telegramRuntimeSource, n as conversationLanguage, o as telegramPrincipal, u as runtimeEnvelope } from "../../../_chunks/principal-B6u41vIf.mjs";
10
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
9
+ import { d as telegramRuntimeSource, n as conversationLanguage, o as telegramPrincipal, u as runtimeEnvelope } from "../../../_chunks/principal-Dmm-cXNF.mjs";
10
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
11
11
  import { addressingReason, conversationKey, otherRecipient } from "../group-routing/signals.mjs";
12
12
  import { conversationAddressing, conversationState } from "../group-routing/conversation.mjs";
13
13
  import { questionInvitation } from "../group-routing/engagement.mjs";
@@ -455,7 +455,7 @@ async function handleInboundMessage(input) {
455
455
  input.request.chatId = sent.chat.id;
456
456
  input.request.replyTo ??= sent.messageId;
457
457
  input.request.monitor = (session, marker) => {
458
- input.request?.backgroundUntil?.(typingUntilComplete(session, marker, context.telegram, AbortSignal.timeout(6e5), {
458
+ input.request?.backgroundUntil?.(typingUntilComplete(session, marker, context.telegram, new AbortController().signal, {
459
459
  traceId: input.request?.traceId,
460
460
  intakeId: input.request?.lifecycleKey,
461
461
  chatId: sent.chat.id,
@@ -4,12 +4,12 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { d as telegramRuntimeSource, l as principalRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-B6u41vIf.mjs";
7
+ import { d as telegramRuntimeSource, l as principalRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-Dmm-cXNF.mjs";
8
8
  import { object } from "../confirmation-description.mjs";
9
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
9
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
10
10
  import { needsConfirmation } from "../confirmations.mjs";
11
11
  import { OntologyActionNotPermitted, actionToolName, ontologyTools } from "../ontology-tools.mjs";
12
- import { t as agentBuild } from "../../../_chunks/build-metadata-DfGc35Vd.mjs";
12
+ import { t as agentBuild } from "../../../_chunks/build-metadata-CfQ3J5Jk.mjs";
13
13
  var AttachmentLifecycleNotPermitted = class extends Error {
14
14
  code = "attachment_lifecycle_not_permitted";
15
15
  };
@@ -150,6 +150,7 @@ function startTypingHeartbeat(telegram) {
150
150
  let stopped = false;
151
151
  let timer;
152
152
  const tick = async () => {
153
+ const startedAt = Date.now();
153
154
  try {
154
155
  const response = await telegram.request("sendChatAction", {
155
156
  chat_id: telegram.chatId,
@@ -175,7 +176,7 @@ function startTypingHeartbeat(telegram) {
175
176
  }
176
177
  if (!stopped) timer = setTimeout(() => {
177
178
  tick();
178
- }, 4e3);
179
+ }, Math.max(0, 4e3 - (Date.now() - startedAt)));
179
180
  };
180
181
  tick();
181
182
  return () => {
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { DEFAULT_IMAGE_DESCRIPTION_MODEL } from "../../config.mjs";
8
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
8
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
9
9
  function planMedia(capabilities, descriptionModel = null) {
10
10
  if (typeof descriptionModel === "string") return {
11
11
  images: "describe",
@@ -4,5 +4,5 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { a as rolesOf, i as memberIdOf, n as conversationLanguage, o as telegramPrincipal, r as identityProviderOf, t as TELEGRAM_AUTHENTICATOR } from "../../../_chunks/principal-B6u41vIf.mjs";
7
+ import { a as rolesOf, i as memberIdOf, n as conversationLanguage, o as telegramPrincipal, r as identityProviderOf, t as TELEGRAM_AUTHENTICATOR } from "../../../_chunks/principal-Dmm-cXNF.mjs";
8
8
  export { TELEGRAM_AUTHENTICATOR, conversationLanguage, identityProviderOf, memberIdOf, rolesOf, telegramPrincipal };
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
8
8
  import { createHash } from "node:crypto";
9
9
  function missingDeployment(error) {
10
10
  if (!(error instanceof Error) || error.name !== "RunKeyFetchError" || !("status" in error) || error.status !== 404) return false;
@@ -40,6 +40,7 @@ function telegramSignals(message, bot, settings) {
40
40
  agentMentioned: audience.botTagged,
41
41
  command: settings?.commandsAddress !== false && command !== null && (command.groups?.target === void 0 || command.groups.target.toLowerCase() === bot?.username?.toLowerCase()),
42
42
  mentions: audience.mentions.map((m) => ({
43
+ type: m.type,
43
44
  externalId: m.id,
44
45
  username: m.username,
45
46
  kind: m.kind
@@ -4,11 +4,11 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import "../../../_chunks/principal-B6u41vIf.mjs";
7
+ import "../../../_chunks/principal-Dmm-cXNF.mjs";
8
8
  import { confirmationLocale } from "./confirmation-text.mjs";
9
9
  import { splitTelegramText } from "./format.mjs";
10
10
  import { inTelegramSendQueue } from "./send-queue.mjs";
11
- import { a as TelegramDeliveryError, l as customerMessage, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
11
+ import { a as TelegramDeliveryError, l as customerMessage, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
12
12
  import { agentMessage, observedChatKey } from "../group-routing/observed.mjs";
13
13
  const SILENT_MARKERS = new Set(["[silent]", "no_reply"]);
14
14
  function isSilentReply(text) {
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { STRUCTURED_KINDS } from "./structured-settings.mjs";
8
- import { d as telegramRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-B6u41vIf.mjs";
8
+ import { d as telegramRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { workspaceAction } from "./workspace-action.mjs";
10
10
  const record = (value) => {
11
11
  if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("Invalid structured Telegram object.");
@@ -5,10 +5,11 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { telegramText } from "./texts.mjs";
8
- import { i as memberIdOf } from "../../../_chunks/principal-B6u41vIf.mjs";
8
+ import { i as memberIdOf } from "../../../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { confirmationLocale } from "./confirmation-text.mjs";
10
- import { c as customerCopy, d as failureText, o as currentLocale, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
10
+ import { c as customerCopy, d as failureText, o as currentLocale, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
11
11
  import { recordSessionFailure } from "./conversations.mjs";
12
+ import { isSilentRoutingCancellation } from "../group-routing/cancellation.mjs";
12
13
  function telegramFailureEvents(input) {
13
14
  return {
14
15
  async "authorization.required"(event, channel, context) {
@@ -41,12 +42,22 @@ function telegramFailureEvents(input) {
41
42
  const authorizationTurn = state.authorizationCancellationTurnId;
42
43
  delete state.authorizationCancellationTurnId;
43
44
  if (typeof event.turnId === "string" && authorizationTurn === event.turnId) return;
45
+ try {
46
+ if (await isSilentRoutingCancellation(input.archive, context, event.turnId)) return;
47
+ } catch (error) {
48
+ reportTelegramError("routing_cancellation_lookup_failed", error, {
49
+ sessionId: context.session.id,
50
+ turnId: event.turnId
51
+ });
52
+ return;
53
+ }
44
54
  const errorId = reportTelegramError("turn_cancelled", event, {
45
55
  chatId: channel.state.chatId,
46
56
  sessionId: context.session.id,
47
57
  turnId: event.turnId
48
58
  });
49
- await channel.telegram.post(failureText(errorId, "cancelled", confirmationLocale(context.session.auth.current, currentLocale())));
59
+ const locale = confirmationLocale(context.session.auth.current, currentLocale());
60
+ await channel.telegram.post(failureText(errorId, "cancelled", locale));
50
61
  },
51
62
  async "turn.failed"(event, channel, context) {
52
63
  const errorId = reportTelegramError("turn_failed", event, {
@@ -55,6 +66,15 @@ function telegramFailureEvents(input) {
55
66
  sessionId: context.session.id,
56
67
  turnId: event.turnId
57
68
  });
69
+ try {
70
+ if (await isSilentRoutingCancellation(input.archive, context, event.turnId)) return;
71
+ } catch (error) {
72
+ reportTelegramError("routing_failure_lookup_failed", error, {
73
+ sessionId: context.session.id,
74
+ turnId: event.turnId
75
+ });
76
+ return;
77
+ }
58
78
  await channel.telegram.post(failureText(errorId, "failed", confirmationLocale(context.session.auth.current, currentLocale())));
59
79
  },
60
80
  async "session.failed"(event, channel) {
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-Buuv7b1I.mjs";
8
8
  import "../connection-proxy.mjs";
9
9
  import { gateway, transcribe } from "ai";
10
10
  const LABELS = {
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { isPreview } from "./lib/environment.mjs";
8
- import { a as rolesOf } from "../_chunks/principal-B6u41vIf.mjs";
8
+ import { a as rolesOf } from "../_chunks/principal-Dmm-cXNF.mjs";
9
9
  import { defineDynamic } from "eve";
10
10
  function chooseModel(input) {
11
11
  const { choice } = input;
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
7
+ import { u as runtimeEnvelope } from "../../_chunks/principal-Dmm-cXNF.mjs";
8
8
  import { n as workflowToolResult } from "../../_chunks/workflow-serializable-_g4JRau5.mjs";
9
9
  import segmentstream from "../extension.mjs";
10
10
  import { actionApproval } from "../lib/confirmations.mjs";
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
7
+ import { i as memberIdOf } from "../../_chunks/principal-Dmm-cXNF.mjs";
8
8
  import segmentstream from "../extension.mjs";
9
9
  import { executeDeferredTool } from "../lib/deferred-confirmations.mjs";
10
10
  import { MAXIMUM_ARGUMENTS_FILE_BYTES, ontologyCallArguments } from "../lib/ontology-arguments.mjs";
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
7
+ import { i as memberIdOf } from "../../_chunks/principal-Dmm-cXNF.mjs";
8
8
  import { n as workflowToolResult } from "../../_chunks/workflow-serializable-_g4JRau5.mjs";
9
9
  import { pendingQuestions, questionKey } from "../lib/questions.mjs";
10
10
  import { stringArgument } from "../lib/attachment-tools.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@segmentstream/agent",
3
- "version": "0.17.13",
3
+ "version": "0.17.15",
4
4
  "description": "Mount a SegmentStream workspace's agent on eve: the ontology as tools, acting as the member who writes, and Telegram through the workspace's connection.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "SegmentStream",
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@chat-adapter/telegram": "4.41.0",
69
- "@segmentstream-cloud/ontology": "0.56.0",
69
+ "@segmentstream-cloud/ontology": "0.56.1",
70
70
  "@vercel/oidc": "^3.8.4",
71
71
  "ai": "^7.0.128",
72
72
  "csv-parse": "^7.0.3",