@segmentstream/agent 0.13.0 → 0.14.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.
Files changed (47) hide show
  1. package/README.md +1 -1
  2. package/dist/_chunks/{build-metadata-BLeBanNg.mjs → build-metadata-BB2uSGsI.mjs} +1 -1
  3. package/dist/_chunks/principal-VFQWqe5S.mjs +126 -0
  4. package/dist/extension/config.d.ts +5 -0
  5. package/dist/extension/config.mjs +30 -1
  6. package/dist/extension/hooks/authorization.mjs +2 -2
  7. package/dist/extension/lib/attachment-tools.mjs +1 -1
  8. package/dist/extension/lib/attachments.d.ts +2 -0
  9. package/dist/extension/lib/attachments.mjs +1 -0
  10. package/dist/extension/lib/build-metadata.mjs +1 -1
  11. package/dist/extension/lib/confirmations.mjs +1 -1
  12. package/dist/extension/lib/conversation-runtime.mjs +1 -1
  13. package/dist/extension/lib/deferred-confirmations.d.ts +2 -0
  14. package/dist/extension/lib/deferred-confirmations.mjs +21 -10
  15. package/dist/extension/lib/ontology-connection.d.ts +1 -0
  16. package/dist/extension/lib/ontology-connection.mjs +18 -12
  17. package/dist/extension/lib/ontology-gateway.mjs +9 -2
  18. package/dist/extension/lib/ontology-metadata-read.mjs +1 -1
  19. package/dist/extension/lib/ontology-tools.d.ts +9 -2
  20. package/dist/extension/lib/ontology-tools.mjs +28 -4
  21. package/dist/extension/lib/runtime-envelope.d.ts +28 -0
  22. package/dist/extension/lib/runtime-envelope.mjs +8 -0
  23. package/dist/extension/lib/stored-files.mjs +1 -1
  24. package/dist/extension/lib/telegram/adapter.mjs +21 -6
  25. package/dist/extension/lib/telegram/attachments-send.mjs +2 -2
  26. package/dist/extension/lib/telegram/callbacks.d.ts +18 -0
  27. package/dist/extension/lib/telegram/callbacks.mjs +155 -0
  28. package/dist/extension/lib/telegram/confirmation-expiry.mjs +2 -2
  29. package/dist/extension/lib/telegram/confirmations.mjs +4 -4
  30. package/dist/extension/lib/telegram/conversations.mjs +1 -1
  31. package/dist/extension/lib/telegram/deferred-confirmations.mjs +4 -4
  32. package/dist/extension/lib/telegram/files.mjs +1 -1
  33. package/dist/extension/lib/telegram/health.mjs +1 -1
  34. package/dist/extension/lib/telegram/inbound.mjs +8 -4
  35. package/dist/extension/lib/telegram/lifecycle.mjs +14 -2
  36. package/dist/extension/lib/telegram/principal.d.ts +1 -0
  37. package/dist/extension/lib/telegram/principal.mjs +1 -49
  38. package/dist/extension/lib/telegram/sessions.d.ts +3 -1
  39. package/dist/extension/lib/telegram/silent.mjs +2 -2
  40. package/dist/extension/lib/telegram/turn-errors.mjs +1 -1
  41. package/dist/extension/lib/telegram/workspace-action.d.ts +21 -0
  42. package/dist/extension/lib/telegram/workspace-action.mjs +23 -0
  43. package/dist/extension/model.mjs +1 -1
  44. package/dist/extension/tools/attachments_promote.mjs +6 -0
  45. package/dist/extension/tools/ontology.mjs +1 -1
  46. package/dist/extension/tools/questions_ask.mjs +1 -1
  47. package/package.json +2 -2
@@ -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 { memberIdOf } from "./telegram/principal.mjs";
7
+ import { i as memberIdOf } from "../../_chunks/principal-VFQWqe5S.mjs";
8
8
  import { redactDiagnostic } from "./diagnostics.mjs";
9
9
  import { object } from "./confirmation-description.mjs";
10
10
  import { ontologyTools } from "./ontology-tools.mjs";
@@ -7,19 +7,20 @@ __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 { conversationLanguage, telegramPrincipal } from "./principal.mjs";
10
+ import { n as conversationLanguage, o as telegramPrincipal } from "../../../_chunks/principal-VFQWqe5S.mjs";
11
+ import { confirmationLocale } from "./confirmation-text.mjs";
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-BXhiIph-.mjs";
11
14
  import { chooseModel } from "../../model.mjs";
12
15
  import { groupRoutingHealth } from "../group-routing/health.mjs";
13
16
  import { decisionRouter } from "../group-routing/router.mjs";
14
17
  import { runtimeToken } from "../runtime-token.mjs";
15
18
  import { conversations } from "../conversations.mjs";
16
19
  import { archivedRoutingMessages } from "../group-routing/routing-context.mjs";
17
- import { t as agentBuild } from "../../../_chunks/build-metadata-BLeBanNg.mjs";
18
- import { confirmationLocale } from "./confirmation-text.mjs";
19
- import { telegramSendScope } from "./send-queue.mjs";
20
- 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-BXhiIph-.mjs";
21
- import { attachmentLifecycle } from "./lifecycle.mjs";
22
20
  import { scopedAddress, sessionPolicy } from "./sessions.mjs";
21
+ import { handleWorkspaceCallback, isWorkspaceCallback } from "./callbacks.mjs";
22
+ import { t as agentBuild } from "../../../_chunks/build-metadata-BB2uSGsI.mjs";
23
+ import { attachmentLifecycle } from "./lifecycle.mjs";
23
24
  import { observedMessages } from "./observed.mjs";
24
25
  import { expireDeferredCards, handleDeferredCallback, isDeferredCallback } from "./deferred-confirmations.mjs";
25
26
  import { gatewayImageDescriber } from "./images.mjs";
@@ -307,6 +308,20 @@ function segmentstreamTelegram(options) {
307
308
  const inbound = currentInboundRequest();
308
309
  if (inbound !== void 0) inbound.locale = query.from.languageCode;
309
310
  try {
311
+ if (isWorkspaceCallback(query.data)) {
312
+ await handleWorkspaceCallback({
313
+ context,
314
+ query,
315
+ configuration: settings().callbacks,
316
+ admission: options.admission?.() ?? manifestOf({}),
317
+ scope: options.sessions().scope,
318
+ identities: pairing(),
319
+ environment,
320
+ token,
321
+ ...options.fetch ? { fetch: options.fetch } : {}
322
+ });
323
+ return;
324
+ }
310
325
  if (isDeferredCallback(query.data)) {
311
326
  await handleDeferredCallback({
312
327
  context,
@@ -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 "./principal.mjs";
9
- import { runtimeToken } from "../runtime-token.mjs";
8
+ import "../../../_chunks/principal-VFQWqe5S.mjs";
10
9
  import { redactDiagnostic } from "../diagnostics.mjs";
11
10
  import { confirmationLocale } from "./confirmation-text.mjs";
12
11
  import { inTelegramSendQueue, telegramSendScope } from "./send-queue.mjs";
13
12
  import { d as failureText, f as formattingRefused, l as customerMessage, p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
13
+ import { runtimeToken } from "../runtime-token.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";
@@ -0,0 +1,18 @@
1
+ import type { TelegramCallbackQuery, TelegramContext } from "eve/channels/telegram";
2
+ import type { AdmissionSettings, SessionSettings, TelegramSettings } from "../../config.js";
3
+ import type { AgentIdentities } from "../identities.js";
4
+ import type { Environment } from "../environment.js";
5
+ import type { RuntimeToken } from "../runtime-token.js";
6
+ export declare const isWorkspaceCallback: (data?: string) => boolean;
7
+ /** A single dispatch and acknowledgement. Token policy and business idempotency belong to the workspace. */
8
+ export declare function handleWorkspaceCallback(input: {
9
+ readonly context: TelegramContext;
10
+ readonly query: TelegramCallbackQuery;
11
+ readonly configuration?: TelegramSettings["callbacks"];
12
+ readonly scope: SessionSettings["scope"];
13
+ readonly admission: AdmissionSettings;
14
+ readonly identities: AgentIdentities;
15
+ readonly environment?: Environment;
16
+ readonly token?: RuntimeToken;
17
+ readonly fetch?: typeof fetch;
18
+ }): Promise<void>;
@@ -0,0 +1,155 @@
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 { admitMessage } from "../admission.mjs";
8
+ import { telegramText } from "./texts.mjs";
9
+ import { d as telegramRuntimeSource, i as memberIdOf, o as telegramPrincipal, u as runtimeEnvelope } from "../../../_chunks/principal-VFQWqe5S.mjs";
10
+ import { object } from "../confirmation-description.mjs";
11
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
12
+ import { formatAddress, parseAddress, scopedAddress } from "./sessions.mjs";
13
+ import { workspaceAction } from "./workspace-action.mjs";
14
+ const isWorkspaceCallback = (data) => data?.startsWith("ws:") === true;
15
+ async function handleWorkspaceCallback(input) {
16
+ const { query, context } = input;
17
+ const locale = query.from.languageCode;
18
+ let acknowledgement;
19
+ let showAlert = false;
20
+ let result;
21
+ let principal;
22
+ const controller = new AbortController();
23
+ let timer;
24
+ try {
25
+ const token = query.data?.slice(3) ?? "";
26
+ if (!query.message || query.from.isBot || !token || new TextEncoder().encode(token).byteLength > 60) acknowledgement = telegramText("callback", "unknown", locale);
27
+ else if (input.configuration === void 0) acknowledgement = telegramText("callback", "unsupported", locale);
28
+ else {
29
+ const message = {
30
+ ...query.message,
31
+ from: query.from,
32
+ attachments: [],
33
+ text: "",
34
+ caption: "",
35
+ raw: {}
36
+ };
37
+ const dispatch = async () => {
38
+ const lookup = await input.identities.lookup({
39
+ provider: "telegram",
40
+ externalId: query.from.id
41
+ });
42
+ if (lookup.status !== "paired") {
43
+ acknowledgement = telegramText("callback", "forbidden", locale);
44
+ return;
45
+ }
46
+ controller.signal.throwIfAborted();
47
+ principal = telegramPrincipal({
48
+ message,
49
+ member: lookup.member,
50
+ callbackQueryId: query.id
51
+ });
52
+ return workspaceAction({
53
+ ...input,
54
+ configuration: input.configuration,
55
+ principal,
56
+ memberId: lookup.member.id,
57
+ input: { token },
58
+ signal: controller.signal,
59
+ envelope: runtimeEnvelope({
60
+ source: telegramRuntimeSource(message, void 0, query.id),
61
+ sessionId: `telegram:callback:${query.id}`,
62
+ callId: query.id
63
+ })
64
+ });
65
+ };
66
+ const deadline = new Promise((resolve) => {
67
+ timer = setTimeout(() => {
68
+ controller.abort();
69
+ reportTelegramError("workspace_callback_timeout", new Error("Telegram callback dispatch exceeded 10 seconds."), { callbackQueryId: query.id });
70
+ resolve(void 0);
71
+ }, 1e4);
72
+ });
73
+ result = await Promise.race([dispatch(), deadline]);
74
+ if (result !== void 0) {
75
+ acknowledgement = typeof result.acknowledgement === "string" && result.acknowledgement.length <= 200 ? result.acknowledgement : void 0;
76
+ showAlert = result.show_alert === true;
77
+ }
78
+ }
79
+ } catch (error) {
80
+ reportTelegramError("workspace_callback_failed", error, { callbackQueryId: query.id });
81
+ acknowledgement = controller.signal.aborted ? void 0 : telegramText("callback", "error", locale);
82
+ } finally {
83
+ if (timer !== void 0) clearTimeout(timer);
84
+ try {
85
+ await context.telegram.answerCallbackQuery({
86
+ callbackQueryId: query.id,
87
+ ...acknowledgement === void 0 ? {} : { text: acknowledgement },
88
+ showAlert
89
+ });
90
+ } catch (error) {
91
+ reportTelegramError("workspace_callback_ack_failed", error, { callbackQueryId: query.id });
92
+ }
93
+ }
94
+ if (result === void 0 || query.message === void 0 || principal === void 0) return;
95
+ const edit = object(result.edit);
96
+ try {
97
+ if (typeof edit.text === "string" || edit.reply_markup !== void 0) {
98
+ const payload = {
99
+ chat_id: query.message.chat.id,
100
+ message_id: Number(query.message.messageId),
101
+ ...typeof edit.text === "string" && edit.text.length <= 4096 ? { text: edit.text } : {},
102
+ ...[
103
+ "MarkdownV2",
104
+ "Markdown",
105
+ "HTML"
106
+ ].includes(String(edit.parse_mode)) ? { parse_mode: edit.parse_mode } : {},
107
+ ...Array.isArray(edit.entities) && edit.entities.length <= 100 ? { entities: edit.entities } : {},
108
+ ...edit.reply_markup === void 0 ? {} : { reply_markup: edit.reply_markup }
109
+ };
110
+ const encoded = JSON.stringify(payload);
111
+ if (encoded.length > 32768) throw new Error("The callback edit exceeds the Telegram hook limit.");
112
+ await context.telegram.request(typeof edit.text === "string" ? "editMessageText" : "editMessageReplyMarkup", JSON.parse(encoded));
113
+ }
114
+ } catch (error) {
115
+ reportTelegramError("workspace_callback_edit_failed", error, { callbackQueryId: query.id });
116
+ }
117
+ if (typeof result.context === "string" && result.context.trim() && result.context.length <= 16384) try {
118
+ const admitted = await admitMessage({
119
+ identity: {
120
+ provider: "telegram",
121
+ externalId: query.from.id,
122
+ chat: query.message.chat.type === "private" ? "private" : "group",
123
+ turn: true
124
+ },
125
+ identities: input.identities,
126
+ settings: input.admission,
127
+ languageCode: locale,
128
+ sendNotice: (text) => context.telegram.post(text),
129
+ noticeFailed: (error) => reportTelegramError("workspace_callback_notice_failed", error)
130
+ });
131
+ if (admitted.status !== "existing" && admitted.status !== "created" || admitted.member.id !== memberIdOf(principal)) return;
132
+ const sessions = currentInboundRequest()?.sessions;
133
+ if (sessions === void 0) throw new Error("The callback has no session transport.");
134
+ const address = scopedAddress(formatAddress({
135
+ chatId: query.message.chat.type === "private" ? query.from.id : query.message.chat.id,
136
+ messageThreadId: String(query.message.messageThreadId ?? ""),
137
+ conversationId: query.message.chat.type === "private" ? "" : query.message.messageId
138
+ }), input.scope);
139
+ const session = sessions.from(address);
140
+ if (session.send === void 0) throw new Error("The callback session cannot enqueue turns.");
141
+ await session.send(result.context, {
142
+ auth: principal,
143
+ turnPolicy: "queue",
144
+ state: {
145
+ chatId: query.message.chat.id,
146
+ chatType: query.message.chat.type,
147
+ messageThreadId: query.message.messageThreadId ?? null,
148
+ conversationId: parseAddress(address).conversationId || null
149
+ }
150
+ });
151
+ } catch (error) {
152
+ reportTelegramError("workspace_callback_turn_failed", error, { callbackQueryId: query.id });
153
+ }
154
+ }
155
+ export { handleWorkspaceCallback, isWorkspaceCallback };
@@ -6,10 +6,10 @@ __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { withTelegramTexts } from "./texts.mjs";
8
8
  import { proxyEnvironment } from "../environment.mjs";
9
- import { runtimeToken } from "../runtime-token.mjs";
10
- import { conversations } from "../conversations.mjs";
11
9
  import { telegramSendScope } from "./send-queue.mjs";
12
10
  import { m as safeTelegramFetch, p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
11
+ import { runtimeToken } from "../runtime-token.mjs";
12
+ import { conversations } from "../conversations.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,16 +5,16 @@ 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 { memberIdOf, telegramPrincipal } from "./principal.mjs";
9
- import { agentMessage, observedChatKey, withConfirmationPrompt } from "../group-routing/observed.mjs";
10
- import { conversationEvent } from "../conversations.mjs";
8
+ import { i as memberIdOf, o as telegramPrincipal } from "../../../_chunks/principal-VFQWqe5S.mjs";
11
9
  import { humanText } from "../confirmation-description.mjs";
12
10
  import { renderConfirmation, withConfirmationText } from "./confirmation-text.mjs";
13
11
  import { chatPostCard, chatPostCardStatus, chatPostReceipt, withChatPostCard } from "./chat-post-card.mjs";
14
12
  import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
13
+ import { agentMessage, observedChatKey, withConfirmationPrompt } from "../group-routing/observed.mjs";
14
+ import { conversationEvent } from "../conversations.mjs";
15
+ import { formatAddress, scopedAddress } from "./sessions.mjs";
15
16
  import { chatPostOperationId, isChatPost } from "../chat-post-confirmation.mjs";
16
17
  import { confirmations } from "../confirmations.mjs";
17
- import { formatAddress, scopedAddress } from "./sessions.mjs";
18
18
  import { postDeferredCard } from "./deferred-confirmations.mjs";
19
19
  import { answerMarker, isPendingQuestion, pendingQuestions, questionKey } from "../questions.mjs";
20
20
  import { createHash } from "node:crypto";
@@ -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-BXhiIph-.mjs";
7
8
  import { currentConfirmationPrompt, observedChatKey } from "../group-routing/observed.mjs";
8
9
  import { conversationEvent } from "../conversations.mjs";
9
10
  import { archivedRoutingMessages } from "../group-routing/routing-context.mjs";
10
- import { n as currentInboundRequest, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
11
11
  import { contentShape, messageContent } from "./content.mjs";
12
12
  import { messageMetadata } from "./observed.mjs";
13
13
  import { reportMembership } from "./membership.mjs";
@@ -5,18 +5,18 @@ 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 { telegramPrincipal } from "./principal.mjs";
9
- import { agentMessage, observedChatKey, withConfirmationPrompt } from "../group-routing/observed.mjs";
10
- import { conversationEvent } from "../conversations.mjs";
8
+ import { o as telegramPrincipal } from "../../../_chunks/principal-VFQWqe5S.mjs";
11
9
  import { humanText } from "../confirmation-description.mjs";
12
10
  import { renderConfirmation, withConfirmationText } from "./confirmation-text.mjs";
13
11
  import { chatPostCard, chatPostCardStatus, chatPostReceipt, withChatPostCard } from "./chat-post-card.mjs";
14
12
  import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
13
+ import { agentMessage, observedChatKey, withConfirmationPrompt } from "../group-routing/observed.mjs";
14
+ import { conversationEvent } from "../conversations.mjs";
15
+ import { formatAddress } from "./sessions.mjs";
15
16
  import { CONFIRMATION_TTL_MS, inputHash } from "../confirmations.mjs";
16
17
  import { OntologyToolRejected } from "../ontology-tools.mjs";
17
18
  import { confirmationOutcome } from "../confirmation-outcome.mjs";
18
19
  import { deferredConfirmations, deferredKey, runDeferredAction } from "../deferred-confirmations.mjs";
19
- import { formatAddress } from "./sessions.mjs";
20
20
  import { telegramTextLinks } from "@segmentstream-cloud/ontology/telegram";
21
21
  const PREFIX = "ss-confirm:d:";
22
22
  const isDeferredCallback = (data) => data?.startsWith(PREFIX) === true;
@@ -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 { conversationLanguage } from "./principal.mjs";
7
+ import { n as conversationLanguage } from "../../../_chunks/principal-VFQWqe5S.mjs";
8
8
  import { d as failureText, p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
9
9
  import { describableImage, describeReceivedImage } from "./images.mjs";
10
10
  import { MAXIMUM_ATTACHMENT_BYTES, attachmentUrl } from "../attachments.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 { t as agentBuild } from "../../../_chunks/build-metadata-BLeBanNg.mjs";
7
+ import { t as agentBuild } from "../../../_chunks/build-metadata-BB2uSGsI.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";
@@ -6,16 +6,16 @@ __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 { conversationLanguage, telegramPrincipal } from "./principal.mjs";
9
+ import { d as telegramRuntimeSource, n as conversationLanguage, o as telegramPrincipal, u as runtimeEnvelope } from "../../../_chunks/principal-VFQWqe5S.mjs";
10
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
10
11
  import { addressingReason, conversationKey, otherRecipient } from "../group-routing/signals.mjs";
11
12
  import { conversationAddressing, conversationState } from "../group-routing/conversation.mjs";
12
13
  import { questionInvitation } from "../group-routing/engagement.mjs";
13
14
  import { conversationContext, routeMessage } from "../group-routing/router.mjs";
14
15
  import { observedContext } from "../group-routing/observed.mjs";
15
16
  import { debounceBurst, routingBurst } from "../group-routing/burst.mjs";
16
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
17
- import { AttachmentLifecycleNotPermitted, startTypingHeartbeat, typingUntilComplete } from "./lifecycle.mjs";
18
17
  import { formatAddress, messageAddress, scopedAddress } from "./sessions.mjs";
18
+ import { AttachmentLifecycleNotPermitted, startTypingHeartbeat, typingUntilComplete } from "./lifecycle.mjs";
19
19
  import { contentShape, messageContent } from "./content.mjs";
20
20
  import { messageAudience } from "./audience.mjs";
21
21
  import { attachmentKind, messageMetadata } from "./observed.mjs";
@@ -757,6 +757,7 @@ async function handleInboundMessage(input) {
757
757
  } : mediaPlan },
758
758
  ...dependencies.describeImage === void 0 ? {} : { describeImage: dependencies.describeImage }
759
759
  });
760
+ if (input.request !== void 0) input.request.files = files;
760
761
  if (input.request?.lifecycle !== void 0) {
761
762
  const lifecycle = input.request.lifecycle;
762
763
  const key = input.request.lifecycleKey;
@@ -787,7 +788,10 @@ async function handleInboundMessage(input) {
787
788
  outcome = { result: (await dependencies.attachments.promote({
788
789
  memberId: member.id,
789
790
  conversation: `telegram:${sent.chat.id}`
790
- }, file.attachment.id, stored.retain)).result };
791
+ }, file.attachment.id, {
792
+ ...stored.retain,
793
+ runtime: runtimeEnvelope({ source: telegramRuntimeSource(sent, files) })
794
+ })).result };
791
795
  } catch (error) {
792
796
  outcome = { error: reportTelegramError("attachment_retention_failed", error, { attachmentId: file.attachment.id }) };
793
797
  }
@@ -4,16 +4,21 @@ 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-BLeBanNg.mjs";
7
+ import { d as telegramRuntimeSource, l as principalRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-VFQWqe5S.mjs";
8
8
  import { object } from "../confirmation-description.mjs";
9
9
  import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.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-BB2uSGsI.mjs";
12
13
  var AttachmentLifecycleNotPermitted = class extends Error {
13
14
  code = "attachment_lifecycle_not_permitted";
14
15
  };
15
16
  function attachmentLifecycle(options) {
16
- const tools = ontologyTools(options);
17
+ const source = () => options.message.raw === void 0 ? principalRuntimeSource(options.principal) : telegramRuntimeSource({
18
+ ...options.message,
19
+ attachments: options.message.attachments ?? [],
20
+ raw: options.message.raw
21
+ }, currentInboundRequest()?.files);
17
22
  const action = actionToolName(options.configuration.entity, options.configuration.action);
18
23
  return async (phase, data = {}) => {
19
24
  console.info("[segmentstream] telegram.phase", {
@@ -40,6 +45,13 @@ function attachmentLifecycle(options) {
40
45
  ...options.configuration.contextVersion === 2 && typeof options.message.raw?.date === "number" && Number.isSafeInteger(options.message.raw.date) && options.message.raw.date > 0 ? { source_at: options.message.raw.date * 1e3 } : {}
41
46
  }
42
47
  };
48
+ const tools = ontologyTools({
49
+ ...options,
50
+ envelope: runtimeEnvelope({
51
+ principal: options.principal,
52
+ source: source()
53
+ })
54
+ });
43
55
  const labels = await tools.labels(options.memberId, action, input).catch((error) => {
44
56
  throw error instanceof OntologyActionNotPermitted ? new AttachmentLifecycleNotPermitted("The sender may not run the lifecycle action.", { cause: error }) : error;
45
57
  });
@@ -14,6 +14,7 @@ export declare function telegramPrincipal(input: {
14
14
  };
15
15
  readonly member: PairedMember;
16
16
  readonly conversationLanguage?: string;
17
+ readonly callbackQueryId?: string;
17
18
  }): SessionAuthContext;
18
19
  /** Short answers and attachment-only turns retain the recent chat language when known. */
19
20
  export declare function conversationLanguage(texts: readonly string[]): "ru" | "en" | undefined;
@@ -4,53 +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
- const TELEGRAM_AUTHENTICATOR = "segmentstream-telegram";
8
- function isGroup(message) {
9
- return message.chat.type === "group" || message.chat.type === "supergroup";
10
- }
11
- function telegramPrincipal(input) {
12
- const { message, member } = input;
13
- const sender = message.from.id;
14
- const attributes = {
15
- memberId: member.id,
16
- identityProvider: "telegram",
17
- roles: member.roles,
18
- chatId: message.chat.id,
19
- chatType: message.chat.type
20
- };
21
- if (member.name !== null) attributes.memberName = member.name;
22
- if (message.messageThreadId !== void 0) attributes.messageThreadId = String(message.messageThreadId);
23
- if (message.from.username !== void 0) attributes.username = message.from.username;
24
- const locale = member.locale ?? message.from.languageCode;
25
- if (locale !== void 0) attributes.locale = locale;
26
- const language = input.conversationLanguage ?? conversationLanguage([message.text || message.caption]);
27
- if (language !== void 0) attributes.conversationLanguage = language;
28
- return {
29
- authenticator: TELEGRAM_AUTHENTICATOR,
30
- issuer: "telegram",
31
- principalId: isGroup(message) ? `telegram:${message.chat.id}:${sender}` : `telegram:${sender}`,
32
- principalType: "user",
33
- subject: sender,
34
- attributes
35
- };
36
- }
37
- function conversationLanguage(texts) {
38
- for (const text of texts) {
39
- if (/[\u0430-\u044f\u0451]/iu.test(text)) return "ru";
40
- if ((text.match(/\b[a-z]+\b/gi)?.length ?? 0) >= 3) return "en";
41
- }
42
- }
43
- function memberIdOf(principal) {
44
- const memberId = principal?.attributes.memberId;
45
- return typeof memberId === "string" && memberId !== "" ? memberId : void 0;
46
- }
47
- function rolesOf(principal) {
48
- const roles = principal?.attributes.roles;
49
- if (typeof roles === "string") return [roles];
50
- return roles ?? [];
51
- }
52
- function identityProviderOf(principal) {
53
- const provider = principal?.attributes.identityProvider;
54
- return typeof provider === "string" && provider !== "" ? provider : void 0;
55
- }
7
+ import { a as rolesOf, i as memberIdOf, n as conversationLanguage, o as telegramPrincipal, r as identityProviderOf, t as TELEGRAM_AUTHENTICATOR } from "../../../_chunks/principal-VFQWqe5S.mjs";
56
8
  export { TELEGRAM_AUTHENTICATOR, conversationLanguage, identityProviderOf, memberIdOf, rolesOf, telegramPrincipal };
@@ -1,5 +1,6 @@
1
1
  import type { TelegramMessage } from "eve/channels/telegram";
2
- import type { CancelTurnResult } from "eve/channels";
2
+ import type { CancelTurnResult, ChannelSource } from "eve/channels";
3
+ import type { TelegramChannelState } from "eve/channels/telegram";
3
4
  import type { SessionSettings } from "../../config.js";
4
5
  /**
5
6
  * Session policy for the Telegram channel (`agent-design.md`, section 4, and docs/agent.md,
@@ -62,6 +63,7 @@ export interface SessionOperations {
62
63
  }) => Promise<CancelTurnResult>;
63
64
  } | undefined>;
64
65
  readonly from: (address: string) => {
66
+ readonly send?: ChannelSource<TelegramChannelState>["send"];
65
67
  compact(): Promise<unknown>;
66
68
  clear(): Promise<unknown>;
67
69
  };
@@ -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 "./principal.mjs";
8
- import { agentMessage, observedChatKey } from "../group-routing/observed.mjs";
7
+ import "../../../_chunks/principal-VFQWqe5S.mjs";
9
8
  import { confirmationLocale } from "./confirmation-text.mjs";
10
9
  import { splitTelegramText } from "./format.mjs";
11
10
  import { inTelegramSendQueue } from "./send-queue.mjs";
12
11
  import { a as TelegramDeliveryError, l as customerMessage, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
12
+ import { agentMessage, observedChatKey } from "../group-routing/observed.mjs";
13
13
  const SILENT_MARKERS = new Set(["[silent]", "no_reply"]);
14
14
  function isSilentReply(text) {
15
15
  return SILENT_MARKERS.has(text.trim().toLowerCase());
@@ -5,7 +5,7 @@ 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 { memberIdOf } from "./principal.mjs";
8
+ import { i as memberIdOf } from "../../../_chunks/principal-VFQWqe5S.mjs";
9
9
  import { confirmationLocale } from "./confirmation-text.mjs";
10
10
  import { c as customerCopy, d as failureText, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-BXhiIph-.mjs";
11
11
  const telegramFailureEvents = {
@@ -0,0 +1,21 @@
1
+ import type { SessionAuthContext } from "eve/context";
2
+ import type { RuntimeEnvelope } from "../runtime-envelope.js";
3
+ import type { Environment } from "../environment.js";
4
+ import type { RuntimeToken } from "../runtime-token.js";
5
+ export interface WorkspaceActionHook {
6
+ readonly entity: string;
7
+ readonly action: string;
8
+ readonly contextVersion: 2;
9
+ }
10
+ /** A declared routine action, re-authorized as the verified member on every event. */
11
+ export declare function workspaceAction(input: {
12
+ readonly configuration: WorkspaceActionHook;
13
+ readonly principal: SessionAuthContext;
14
+ readonly memberId: string;
15
+ readonly input: Readonly<Record<string, unknown>>;
16
+ readonly envelope: RuntimeEnvelope;
17
+ readonly environment?: Environment;
18
+ readonly token?: RuntimeToken;
19
+ readonly fetch?: typeof fetch;
20
+ readonly signal?: AbortSignal;
21
+ }): Promise<Record<string, unknown>>;
@@ -0,0 +1,23 @@
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 { object } from "../confirmation-description.mjs";
8
+ import { needsConfirmation } from "../confirmations.mjs";
9
+ import { actionToolName, ontologyTools } from "../ontology-tools.mjs";
10
+ async function workspaceAction(input) {
11
+ const tools = ontologyTools(input);
12
+ const action = actionToolName(input.configuration.entity, input.configuration.action);
13
+ if (needsConfirmation(await tools.labels(input.memberId, action, input.input, input.signal))) throw new Error("A Telegram workspace hook must be a permitted routine action.");
14
+ if (!await tools.supportsRuntimeSource(input.memberId, input.signal)) throw new Error("A Telegram workspace hook requires the runtime-source capability.");
15
+ const raw = await tools.rpc(input.memberId, "tools/call", {
16
+ name: action,
17
+ arguments: input.input
18
+ }, input.signal);
19
+ const envelope = object(raw.structuredContent);
20
+ if (object(envelope.validation).ok === false) throw new Error("The Telegram workspace hook rejected its event.");
21
+ return object(envelope.result ?? envelope);
22
+ }
23
+ export { workspaceAction };
@@ -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 { rolesOf } from "./lib/telegram/principal.mjs";
8
+ import { a as rolesOf } from "../_chunks/principal-VFQWqe5S.mjs";
9
9
  import { defineDynamic } from "eve";
10
10
  function chooseModel(input) {
11
11
  const { choice } = input;
@@ -4,6 +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-VFQWqe5S.mjs";
7
8
  import { n as workflowToolResult } from "../../_chunks/workflow-serializable-DVQBWK8p.mjs";
8
9
  import segmentstream from "../extension.mjs";
9
10
  import { actionApproval } from "../lib/confirmations.mjs";
@@ -73,6 +74,11 @@ var attachments_promote_default = defineTool({
73
74
  const recordId = optionalString(input, "record_id");
74
75
  const actionInput = optionalObject(input, "input");
75
76
  const promoted = await toolAttachments().promote(owner, stringArgument(input, "id"), {
77
+ runtime: runtimeEnvelope({
78
+ principal: ctx.session.auth.current,
79
+ sessionId: ctx.session.id,
80
+ callId: ctx.callId
81
+ }),
76
82
  entity: stringArgument(input, "entity"),
77
83
  action: stringArgument(input, "action"),
78
84
  ...actionInput === void 0 ? {} : { input: actionInput },
@@ -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 { memberIdOf } from "../lib/telegram/principal.mjs";
7
+ import { i as memberIdOf } from "../../_chunks/principal-VFQWqe5S.mjs";
8
8
  import segmentstream from "../extension.mjs";
9
9
  import { executeDeferredTool } from "../lib/deferred-confirmations.mjs";
10
10
  import { ontologyInspect, ontologyMetadata } from "../lib/ontology-gateway.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 { memberIdOf } from "../lib/telegram/principal.mjs";
7
+ import { i as memberIdOf } from "../../_chunks/principal-VFQWqe5S.mjs";
8
8
  import { n as workflowToolResult } from "../../_chunks/workflow-serializable-DVQBWK8p.mjs";
9
9
  import { pendingQuestions, questionKey } from "../lib/questions.mjs";
10
10
  import { stringArgument } from "../lib/attachment-tools.mjs";