@segmentstream/agent 0.25.7 → 0.26.1

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 (46) hide show
  1. package/README.md +9 -29
  2. package/dist/_chunks/{build-metadata-Wt6SOKfE.mjs → build-metadata-D_Gqlb5f.mjs} +1 -1
  3. package/dist/_chunks/{inbound-request-xmrm-49O.mjs → inbound-request-D1r0FkDI.mjs} +0 -4
  4. package/dist/_chunks/{principal-DMNXj4PX.mjs → principal-D99Lleae.mjs} +1 -1
  5. package/dist/extension/extension.d.ts +0 -1
  6. package/dist/extension/extension.mjs +1 -2
  7. package/dist/extension/hooks/authorization.mjs +1 -1
  8. package/dist/extension/lib/actor.mjs +1 -1
  9. package/dist/extension/lib/attachment-tools.mjs +1 -1
  10. package/dist/extension/lib/attachments.mjs +1 -1
  11. package/dist/extension/lib/build-metadata.mjs +1 -1
  12. package/dist/extension/lib/confirmations.mjs +1 -1
  13. package/dist/extension/lib/conversation-runtime.mjs +1 -1
  14. package/dist/extension/lib/ontology-connection.mjs +1 -1
  15. package/dist/extension/lib/ontology-file-call.mjs +1 -1
  16. package/dist/extension/lib/ontology-tools.mjs +1 -1
  17. package/dist/extension/lib/runtime-envelope.mjs +1 -1
  18. package/dist/extension/lib/stored-files.mjs +1 -1
  19. package/dist/extension/lib/telegram/adapter.mjs +12 -7
  20. package/dist/extension/lib/telegram/attachment-description.mjs +1 -1
  21. package/dist/extension/lib/telegram/attachments-send.mjs +3 -3
  22. package/dist/extension/lib/telegram/callbacks.mjs +2 -2
  23. package/dist/extension/lib/telegram/confirmations.mjs +2 -2
  24. package/dist/extension/lib/telegram/conversations.mjs +1 -1
  25. package/dist/extension/lib/telegram/customer-text.mjs +1 -1
  26. package/dist/extension/lib/telegram/files.mjs +2 -2
  27. package/dist/extension/lib/telegram/health.mjs +1 -1
  28. package/dist/extension/lib/telegram/images.mjs +1 -1
  29. package/dist/extension/lib/telegram/inbound-request.d.ts +0 -4
  30. package/dist/extension/lib/telegram/inbound-request.mjs +1 -1
  31. package/dist/extension/lib/telegram/inbound.mjs +4 -16
  32. package/dist/extension/lib/telegram/lifecycle.d.ts +0 -6
  33. package/dist/extension/lib/telegram/lifecycle.mjs +4 -101
  34. package/dist/extension/lib/telegram/media-policy.mjs +1 -1
  35. package/dist/extension/lib/telegram/principal.mjs +1 -1
  36. package/dist/extension/lib/telegram/session-recovery.mjs +1 -1
  37. package/dist/extension/lib/telegram/silent.mjs +2 -2
  38. package/dist/extension/lib/telegram/structured.mjs +1 -1
  39. package/dist/extension/lib/telegram/turn-errors.mjs +2 -2
  40. package/dist/extension/lib/telegram/voice.mjs +1 -1
  41. package/dist/extension/model.mjs +1 -1
  42. package/dist/extension/tools/attachments_promote.mjs +1 -1
  43. package/dist/extension/tools/questions_ask.mjs +1 -1
  44. package/package.json +2 -2
  45. package/dist/extension/lib/telegram/durable-typing.d.ts +0 -52
  46. package/dist/extension/lib/telegram/durable-typing.mjs +0 -182
package/README.md CHANGED
@@ -452,6 +452,10 @@ The SDK adds no text to the prompt.
452
452
  The turn stays in the session. Archive decisions distinguish silence markers, empty text and
453
453
  whitespace, retaining finish reason and character count without logging raw output. Model reply
454
454
  decisions do not prove transport delivery; completed outbound events carry that evidence.
455
+ - **Typing.** The channel keeps Eve's native indicator: one `typing` chat action in the message's
456
+ chat and topic when a message is admitted, when its turn starts and when each tool call is
457
+ requested. Telegram shows each for a few seconds; nothing refreshes it on a timer, and a refused
458
+ action is logged and does not affect the turn.
455
459
 
456
460
  The observed ring and chat-report caches live in process memory. On a cold start, the adapter
457
461
  restores recent conversation context from the platform archive and reports its chats afresh.
@@ -779,13 +783,10 @@ before business completion. Persist bill/result receipts and resume by business
779
783
  identity after later uploads; a collection timer alone is insufficient.
780
784
 
781
785
  The adapter retains the queued-turn policy, checks durable inbox acknowledgement,
782
- and anchors delivery to the immutable source message/topic. Every admitted text or intake webhook
783
- uses its host `waitUntil` lifetime to follow the durable session stream and refresh
784
- Telegram typing every four seconds; completion, human input, cancellation,
785
- failure or abort close the reader and timer. There is no fixed ten-minute cutoff;
786
- monitoring remains bounded by the host request lifetime. This is not a separate durable heartbeat workflow.
787
- Safe phase telemetry distinguishes admission, storage, queue acceptance and the
788
- owning turn without recording file contents or grants.
786
+ and anchors delivery to the immutable source message/topic. Intake admission sends one
787
+ [typing](#telegram) action; the webhook does not follow the turn after queue acceptance.
788
+ Safe phase telemetry distinguishes admission, storage and queue acceptance without recording
789
+ file contents or grants; the turn's model and tool events stay in its durable session stream.
789
790
 
790
791
  Before a final reply, an active lifecycle receives `completed`. Return
791
792
  `{complete, message}` after checking durable results. The adapter uses this
@@ -804,7 +805,7 @@ ordinary routing classifier. Omit the key to retain ordinary routing. Collection
804
805
  honours the returned deadline within a 120-second processing budget; expiry fails
805
806
  closed without queueing an incomplete turn. Authenticated runtime health includes
806
807
  the built SDK version and deployment identity. Phase telemetry records webhook
807
- receipt, lifecycle/queue admission, model/tool events and typing API acceptance.
808
+ receipt and lifecycle/queue admission.
808
809
 
809
810
  A configured hook failure, or a processing failure after it admits a task, returns
810
811
  HTTP 503 with a correlation reference before durable queue admission. Telegram
@@ -864,27 +865,6 @@ mappings. They require the ontology runtime-source capability and dispatch only
864
865
  permitted routine action as the verified member. The workspace owns callback tokens, presentation
865
866
  and business idempotency.
866
867
 
867
- ### Durable typing
868
-
869
- The webhook monitor ends with its host request. For turns that can outlive that
870
- request, an application's authored Workflow can call `telegramTypingBlock` from
871
- `@segmentstream/agent/extension` in a `"use step"` helper. Each activity runs for
872
- at most about thirty seconds, follows a bounded cursor through one session's
873
- durable stream, and sends only `sendChatAction` through the declared connection.
874
- It stops for its source turn's completion, failure, cancellation or input wait,
875
- or when the source session is terminal. Pass an exact `turnId` from a real
876
- `turn.started` hook, or a unique `marker` in a private acceptance message.
877
-
878
- The application owns the Workflow directives: Eve does not permit them in an
879
- SDK extension. Its step reads `getRun(source.sessionId).status` through
880
- `workflow/api` and calls `telegramTypingBlock(source, cursor, status)`. Its
881
- workflow carries the returned cursor between activities and ends when `done` is
882
- true. Start a continuation periodically to bound the workflow history, then
883
- retire the previous monitor. `recordTelegramTypingStart(source, workflowRunId)`
884
- records the monitor reference in the conversation archive. Source arguments
885
- contain transport coordinates and a member ID, never credentials or message
886
- contents. Repeated typing actions are idempotent; the activity never posts text.
887
-
888
868
  ### Replication lifecycle and freshness
889
869
 
890
870
  After verified initial publication, Cloud keeps a replication stream active while
@@ -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.25.7";
7
+ var version = "0.26.1";
8
8
  function agentBuild(environment = process.env) {
9
9
  return {
10
10
  agent: version,
@@ -244,14 +244,12 @@ var InboundRequest = class {
244
244
  triggeringMessageId;
245
245
  chatId;
246
246
  replyTo;
247
- stopTyping;
248
247
  lifecycle;
249
248
  lifecycleKey;
250
249
  lifecycleDispatchToken;
251
250
  releaseLifecycleDispatch;
252
251
  retryReference;
253
252
  lifecycleContext;
254
- monitor;
255
253
  previousText;
256
254
  attachmentsChanged = false;
257
255
  previousContent;
@@ -270,7 +268,6 @@ var InboundRequest = class {
270
268
  files;
271
269
  extraFiles;
272
270
  sessions;
273
- backgroundUntil;
274
271
  waitUntil;
275
272
  address;
276
273
  respond;
@@ -375,7 +372,6 @@ function withReplacedText(source, request) {
375
372
  intakeId: request.lifecycleKey,
376
373
  sessionId: result.sessionId
377
374
  });
378
- if (marker !== void 0) request.monitor?.(result, marker);
379
375
  return result;
380
376
  }
381
377
  };
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import "../extension/lib/agent-task.mjs";
8
- import { n as currentInboundRequest } from "./inbound-request-xmrm-49O.mjs";
8
+ import { n as currentInboundRequest } from "./inbound-request-D1r0FkDI.mjs";
9
9
  import { randomUUID } from "node:crypto";
10
10
  function telegramRuntimeSource(message, files, callbackQueryId) {
11
11
  const attachments = [];
@@ -31,4 +31,3 @@ export { replayRouterPayload } from "./lib/group-routing/replay.js";
31
31
  export { conversationState as groupConversationState, conversationAddressing as groupConversationAddressing, type ConversationAnalysis, type ConversationPath, } from "./lib/group-routing/conversation.js";
32
32
  export { routingBurst, debounceBurst } from "./lib/group-routing/burst.js";
33
33
  export type { TelegramTexts } from "./lib/telegram/texts.js";
34
- export { telegramTypingBlock, recordTelegramTypingStart, type TelegramTypingSource, type TypingCursor, type TypingBlockResult, } from "./lib/telegram/durable-typing.js";
@@ -14,11 +14,10 @@ import { agentMessage, observedMessages } from "./lib/group-routing/observed.mjs
14
14
  import { archivedRoutingMessages } from "./lib/group-routing/routing-context.mjs";
15
15
  import { replayRouterPayload } from "./lib/group-routing/replay.mjs";
16
16
  import { debounceBurst, routingBurst } from "./lib/group-routing/burst.mjs";
17
- import { recordTelegramTypingStart, telegramTypingBlock } from "./lib/telegram/durable-typing.mjs";
18
17
  import { defineExtension } from "eve/extension";
19
18
  const extension = defineExtension({ config: configSchema });
20
19
  const segmentstream = Object.assign(extension, {
21
20
  model: (choice) => model(choice ?? (() => extension.config.models.chat)),
22
21
  manifestOf
23
22
  });
24
- export { DEFAULT_ADMISSION_LIMITS, DEFAULT_DECISION_MODEL, DEFAULT_GROUP_POLICY, DEFAULT_STT_MODEL, SegmentStreamAgentConfigError, archivedRoutingMessages, chooseModel, conversationKey, debounceBurst, segmentstream as default, segmentstream, effectiveGroupPolicy, addressingReason as groupAddressingReason, agentMessage as groupAgentMessage, conversationAddressing as groupConversationAddressing, conversationState as groupConversationState, decisionRouter as groupDecisionRouter, observedMessages as groupObservedMessages, groupPolicy, manifestOf, model, recordTelegramTypingStart, replayRouterPayload, routeMessage as routeGroupMessage, routingBurst, telegramTypingBlock };
23
+ export { DEFAULT_ADMISSION_LIMITS, DEFAULT_DECISION_MODEL, DEFAULT_GROUP_POLICY, DEFAULT_STT_MODEL, SegmentStreamAgentConfigError, archivedRoutingMessages, chooseModel, conversationKey, debounceBurst, segmentstream as default, segmentstream, effectiveGroupPolicy, addressingReason as groupAddressingReason, agentMessage as groupAgentMessage, conversationAddressing as groupConversationAddressing, conversationState as groupConversationState, decisionRouter as groupDecisionRouter, observedMessages as groupObservedMessages, groupPolicy, manifestOf, model, replayRouterPayload, routeMessage as routeGroupMessage, routingBurst };
@@ -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-DMNXj4PX.mjs";
8
+ import "../../_chunks/principal-D99Lleae.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 { AGENT_TASK_HEADER, agentTaskIdOf, taskSecret } from "./agent-task.mjs";
8
- import { i as memberIdOf, r as identityProviderOf } from "../../_chunks/principal-DMNXj4PX.mjs";
8
+ import { i as memberIdOf, r as identityProviderOf } from "../../_chunks/principal-D99Lleae.mjs";
9
9
  import { defineDynamic } from "eve/tools";
10
10
  const ACT_AS_HEADER = "X-SegmentStream-Act-As";
11
11
  function member(memberId) {
@@ -6,7 +6,7 @@ __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
8
  import { runtimeToken } from "./runtime-token.mjs";
9
- import { i as memberIdOf } from "../../_chunks/principal-DMNXj4PX.mjs";
9
+ import { i as memberIdOf } from "../../_chunks/principal-D99Lleae.mjs";
10
10
  import { agentAttachments } from "./attachments.mjs";
11
11
  import { telegramConversation } from "./telegram/files.mjs";
12
12
  import { detectFile, documentText } from "./attachment-formats.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 { MAXIMUM_DOWNLOAD_BYTES } from "./connection-proxy.mjs";
8
7
  import { ACT_AS_HEADER } from "./actor.mjs";
8
+ import { MAXIMUM_DOWNLOAD_BYTES } from "./connection-proxy.mjs";
9
9
  import { createHash } from "node:crypto";
10
10
  const MAXIMUM_ATTACHMENT_BYTES = MAXIMUM_DOWNLOAD_BYTES;
11
11
  const ATTACHMENT_TTL_HOURS = 24;
@@ -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-Wt6SOKfE.mjs";
7
+ import { t as agentBuild } from "../../_chunks/build-metadata-D_Gqlb5f.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-DMNXj4PX.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-D99Lleae.mjs";
9
9
  import { UnsafeConfirmationTarget } from "./confirmation-description.mjs";
10
10
  import { confirmationCopy, confirmationLocale, renderConfirmation } from "./telegram/confirmation-text.mjs";
11
11
  import { chatPostCard } from "./telegram/chat-post-card.mjs";
@@ -6,7 +6,7 @@ __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { agentTaskIdOf } from "./agent-task.mjs";
8
8
  import { ENDS_CONVERSATION_INSTRUCTIONS } from "./group-routing/conversation-prompt.mjs";
9
- import { i as memberIdOf } from "../../_chunks/principal-DMNXj4PX.mjs";
9
+ import { i as memberIdOf } from "../../_chunks/principal-D99Lleae.mjs";
10
10
  import { n as contentText, t as CONTENT_CAPS } from "../../_chunks/content-cDtVnr8Y.mjs";
11
11
  import { conversationEvent, conversations, sessionFailureEventId, summarizeArguments } from "./conversations.mjs";
12
12
  import { parseAddress } from "./telegram/sessions.mjs";
@@ -6,7 +6,7 @@ __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
8
  import { runtimeToken, tokenExpiry } from "./runtime-token.mjs";
9
- import { c as compatibleRuntimeEnvelope, u as runtimeEnvelope } from "../../_chunks/principal-DMNXj4PX.mjs";
9
+ import { c as compatibleRuntimeEnvelope, u as runtimeEnvelope } from "../../_chunks/principal-D99Lleae.mjs";
10
10
  import { ACT_AS_HEADER, ActorRequiredError, actorHeaders, actorKey, actorOf } from "./actor.mjs";
11
11
  import { CHAT_POST_ENVELOPE, CHAT_POST_TOOL, chatPostDigest, chatPostOperationId, isChatPost } from "./chat-post-confirmation.mjs";
12
12
  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 { u as runtimeEnvelope } from "../../_chunks/principal-DMNXj4PX.mjs";
7
+ import { u as runtimeEnvelope } from "../../_chunks/principal-D99Lleae.mjs";
8
8
  import { actorKey, actorOf } from "./actor.mjs";
9
9
  import { isChatPost } from "./chat-post-confirmation.mjs";
10
10
  import { actionApproval, confirmations, inputHash } from "./confirmations.mjs";
@@ -8,7 +8,7 @@ import { redactDiagnostic } from "./diagnostics.mjs";
8
8
  import { appOrigin } from "./environment.mjs";
9
9
  import { runtimeToken } from "./runtime-token.mjs";
10
10
  import "./agent-task.mjs";
11
- import { c as compatibleRuntimeEnvelope, s as RUNTIME_SOURCE_PROTOCOL, u as runtimeEnvelope } from "../../_chunks/principal-DMNXj4PX.mjs";
11
+ import { c as compatibleRuntimeEnvelope, s as RUNTIME_SOURCE_PROTOCOL, u as runtimeEnvelope } from "../../_chunks/principal-D99Lleae.mjs";
12
12
  import { describeConfirmation, object } from "./confirmation-description.mjs";
13
13
  import { actorHeaders, actorKey, actorOf } from "./actor.mjs";
14
14
  import { describeChatPost, isChatPost, supportsChatPost } from "./chat-post-confirmation.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-DMNXj4PX.mjs";
7
+ import { c as compatibleRuntimeEnvelope, d as telegramRuntimeSource, l as principalRuntimeSource, s as RUNTIME_SOURCE_PROTOCOL, u as runtimeEnvelope } from "../../_chunks/principal-D99Lleae.mjs";
8
8
  export { RUNTIME_SOURCE_PROTOCOL, compatibleRuntimeEnvelope, principalRuntimeSource, runtimeEnvelope, telegramRuntimeSource };
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { redactDiagnostic } from "./diagnostics.mjs";
8
- import { i as memberIdOf } from "../../_chunks/principal-DMNXj4PX.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-D99Lleae.mjs";
9
9
  import { object } from "./confirmation-description.mjs";
10
10
  import { member } from "./actor.mjs";
11
11
  import { OntologyFileUnavailable, ontologyTools } from "./ontology-tools.mjs";
@@ -9,25 +9,25 @@ import { runtimeToken } from "../runtime-token.mjs";
9
9
  import { runtimeTokenVerifier } from "../runtime-identity.mjs";
10
10
  import { telegramText, withTelegramTexts } from "./texts.mjs";
11
11
  import { manifestOf } from "../../config.mjs";
12
- import { n as conversationLanguage, o as telegramPrincipal } from "../../../_chunks/principal-DMNXj4PX.mjs";
12
+ import { n as conversationLanguage, o as telegramPrincipal } from "../../../_chunks/principal-D99Lleae.mjs";
13
13
  import { object } from "../confirmation-description.mjs";
14
14
  import { confirmationLocale } from "./confirmation-text.mjs";
15
15
  import { telegramSendScope } from "./send-queue.mjs";
16
16
  import { conversations } from "../conversations.mjs";
17
17
  import { withDeliveryDiagnostics } from "./delivery-diagnostics.mjs";
18
- 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-xmrm-49O.mjs";
18
+ 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-D1r0FkDI.mjs";
19
19
  import { chooseModel } from "../../model.mjs";
20
20
  import { groupRoutingHealth } from "../group-routing/health.mjs";
21
21
  import { decisionRouter } from "../group-routing/router.mjs";
22
22
  import { archivedRoutingMessages } from "../group-routing/routing-context.mjs";
23
- import { MAXIMUM_DOWNLOAD_BYTES, connectionProxy } from "../connection-proxy.mjs";
24
23
  import { dispatchStructuredMessage, structuredMessage } from "./structured.mjs";
25
24
  import { scopedAddress, sessionPolicy } from "./sessions.mjs";
26
25
  import { handleWorkspaceCallback, isWorkspaceCallback } from "./callbacks.mjs";
27
- import { t as agentBuild } from "../../../_chunks/build-metadata-Wt6SOKfE.mjs";
26
+ import { t as agentBuild } from "../../../_chunks/build-metadata-D_Gqlb5f.mjs";
28
27
  import { attachmentLifecycle } from "./lifecycle.mjs";
29
28
  import { gatewayImageDescriber } from "./images.mjs";
30
29
  import { gatewayAttachmentDescriber } from "./attachment-description.mjs";
30
+ import { MAXIMUM_DOWNLOAD_BYTES, connectionProxy } from "../connection-proxy.mjs";
31
31
  import { agentAttachments, parseAttachmentUrl } from "../attachments.mjs";
32
32
  import { agentIdentities } from "../identities.mjs";
33
33
  import { observedMessages } from "./observed.mjs";
@@ -47,6 +47,9 @@ import { telegramWebhookVerifier } from "./webhook.mjs";
47
47
  import { telegramPreviewEnvironment } from "@segmentstream-cloud/ontology/telegram";
48
48
  import { telegramChannel } from "eve/channels/telegram";
49
49
  const LEGACY_DEFERRED_CALLBACK = "ss-confirm:d:";
50
+ async function typing(_event, ctx) {
51
+ await ctx.channel.telegram.startTyping();
52
+ }
50
53
  const eveHistory = async (sessionId) => {
51
54
  const { sessions } = await import("eve/server");
52
55
  const events = [];
@@ -321,8 +324,6 @@ function segmentstreamTelegram(options) {
321
324
  reportTelegramError("inbound_failure_notice_failed", noticeError, { errorId });
322
325
  }
323
326
  return null;
324
- } finally {
325
- inbound?.stopTyping?.();
326
327
  }
327
328
  },
328
329
  onCallbackQuery: async (context, query) => {
@@ -369,6 +370,11 @@ function segmentstreamTelegram(options) {
369
370
  events: {
370
371
  ...failureEvents,
371
372
  ...approvalEvents,
373
+ "call.requested": typing,
374
+ async "turn.started"(event, ctx) {
375
+ await approvalEvents["turn.started"]?.(event, ctx);
376
+ await typing(event, ctx);
377
+ },
372
378
  async "interaction.opened"(event, ctx) {
373
379
  await failureEvents["interaction.opened"]?.(event, ctx);
374
380
  await approvalEvents["interaction.opened"]?.(event, ctx);
@@ -543,7 +549,6 @@ function gatedRoute(input) {
543
549
  args.waitUntil(task);
544
550
  };
545
551
  inbound.waitUntil = waitUntil;
546
- inbound.backgroundUntil = (task) => args.waitUntil(task);
547
552
  return withTelegramTexts(options.admission?.().texts ?? {}, () => runInboundRequest(inbound, () => input.capture(request, async (routedRequest = request) => {
548
553
  const response = await route.handler(routedRequest, {
549
554
  ...args,
@@ -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-xmrm-49O.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.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";
@@ -7,12 +7,12 @@ __eveCreateRequire(import.meta.url);
7
7
  import { redactDiagnostic } from "../diagnostics.mjs";
8
8
  import { appOrigin, channelsEnabled, proxyEnvironment } from "../environment.mjs";
9
9
  import { runtimeToken } from "../runtime-token.mjs";
10
- import "../../../_chunks/principal-DMNXj4PX.mjs";
10
+ import "../../../_chunks/principal-D99Lleae.mjs";
11
11
  import { confirmationLocale } from "./confirmation-text.mjs";
12
12
  import { inTelegramSendQueue, telegramSendScope } from "./send-queue.mjs";
13
- import { d as failureText, f as formattingRefused, l as customerMessage, p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
14
- import { MAXIMUM_PROXY_BODY_BYTES, connectionProxy } from "../connection-proxy.mjs";
13
+ import { d as failureText, f as formattingRefused, l as customerMessage, p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.mjs";
15
14
  import { ACT_AS_HEADER } from "../actor.mjs";
15
+ import { MAXIMUM_PROXY_BODY_BYTES, connectionProxy } from "../connection-proxy.mjs";
16
16
  import { AttachmentError, CONVERSATION_HEADER, SESSION_HEADER } from "../attachments.mjs";
17
17
  import { TELEGRAM_PLACEHOLDER_TOKEN, TELEGRAM_PROXY_ORIGIN, telegramProxyFetch } from "./proxy-fetch.mjs";
18
18
  import { attachmentOwner } from "../attachment-tools.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-DMNXj4PX.mjs";
9
+ import { d as telegramRuntimeSource, i as memberIdOf, o as telegramPrincipal, u as runtimeEnvelope } from "../../../_chunks/principal-D99Lleae.mjs";
10
10
  import { object } from "../confirmation-description.mjs";
11
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
11
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.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;
@@ -5,12 +5,12 @@ 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-DMNXj4PX.mjs";
8
+ import { i as memberIdOf, o as telegramPrincipal } from "../../../_chunks/principal-D99Lleae.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
12
  import { conversationEvent } from "../conversations.mjs";
13
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
13
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.mjs";
14
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";
@@ -6,7 +6,7 @@ __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { n as contentText, t as CONTENT_CAPS } from "../../../_chunks/content-cDtVnr8Y.mjs";
8
8
  import { conversationEvent, sessionFailureEventId } from "../conversations.mjs";
9
- import { n as currentInboundRequest, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
9
+ import { n as currentInboundRequest, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-D1r0FkDI.mjs";
10
10
  import { currentConfirmationPrompt, observedChatKey } from "../group-routing/observed.mjs";
11
11
  import { archivedRoutingMessages } from "../group-routing/routing-context.mjs";
12
12
  import { parseArchivedMessage } from "./archive-message.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-xmrm-49O.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-D1r0FkDI.mjs";
9
9
  export { TelegramDeliveryError, currentLocale, currentThreadId, customerCopy, customerMessage, customerText, failureText, formattingRefused, isTechnicalText, reportTelegramError, safeTelegramFetch, withDeliveryLocale };
@@ -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-DMNXj4PX.mjs";
8
- import { d as failureText, p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
7
+ import { n as conversationLanguage } from "../../../_chunks/principal-D99Lleae.mjs";
8
+ import { d as failureText, p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.mjs";
9
9
  import { describableImage, describeReceivedImage } from "./images.mjs";
10
10
  import { MAXIMUM_ATTACHMENT_BYTES, attachmentUrl } from "../attachments.mjs";
11
11
  function telegramConversation(chatId) {
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { runtimeRequestFailure } from "./runtime-request.mjs";
8
- import { t as agentBuild } from "../../../_chunks/build-metadata-Wt6SOKfE.mjs";
8
+ import { t as agentBuild } from "../../../_chunks/build-metadata-D_Gqlb5f.mjs";
9
9
  import { GET } from "eve/channels";
10
10
  const HEALTH_ROUTE = "/eve/v1/telegram/health";
11
11
  function healthRoute(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 { p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.mjs";
8
8
  import { gateway, generateText } from "ai";
9
9
  const MAXIMUM_IMAGE_DESCRIPTION_BYTES = 5242880;
10
10
  const MAXIMUM_NATIVE_IMAGE_BYTES = 3145728;
@@ -35,7 +35,6 @@ export declare class InboundRequest {
35
35
  triggeringMessageId: string | undefined;
36
36
  chatId: string | undefined;
37
37
  replyTo: string | undefined;
38
- stopTyping: (() => void) | undefined;
39
38
  lifecycle: ReturnType<typeof import("./lifecycle.js").attachmentLifecycle> | undefined;
40
39
  lifecycleKey: string | undefined;
41
40
  lifecycleDispatchToken: string | undefined;
@@ -43,7 +42,6 @@ export declare class InboundRequest {
43
42
  /** A routed task must be redelivered if recovery or intake did not reach durable admission. */
44
43
  retryReference: string | undefined;
45
44
  lifecycleContext: string | undefined;
46
- monitor: ((session: Awaited<ReturnType<ChannelSource<unknown>["send"]>>, marker: string) => void) | undefined;
47
45
  previousText: string | undefined;
48
46
  attachmentsChanged: boolean;
49
47
  /** Evidence may be reused only while the provider attachment identities are unchanged. */
@@ -81,8 +79,6 @@ export declare class InboundRequest {
81
79
  extraFiles: Exclude<MessageContent, string> | undefined;
82
80
  /** The route's session operations, on addresses already mapped to the configured scope. */
83
81
  sessions: SessionOperations | undefined;
84
- /** Host background lifetime; long-running observers must never enter the routing drain. */
85
- backgroundUntil: ((task: Promise<unknown>) => void) | undefined;
86
82
  /** Keeps work the request started, such as a chat report, alive after it answers. */
87
83
  waitUntil: ((task: Promise<unknown>) => void) | undefined;
88
84
  /** Continues the exact pending question's session, including under thread scope. */
@@ -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-xmrm-49O.mjs";
7
+ import { i as withReplacedText, n as currentInboundRequest, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-D1r0FkDI.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-DMNXj4PX.mjs";
10
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
9
+ import { d as telegramRuntimeSource, n as conversationLanguage, o as telegramPrincipal, u as runtimeEnvelope } from "../../../_chunks/principal-D99Lleae.mjs";
10
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.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";
@@ -17,7 +17,7 @@ import { debounceBurst, routingBurst } from "../group-routing/burst.mjs";
17
17
  import { WorkspaceActionAlreadyDispatched } from "./workspace-action.mjs";
18
18
  import { structuredMessage } from "./structured.mjs";
19
19
  import { evidenceSince, formatAddress, messageAddress, scopedAddress } from "./sessions.mjs";
20
- import { AttachmentLifecycleNotPermitted, startTypingHeartbeat, typingUntilComplete } from "./lifecycle.mjs";
20
+ import { AttachmentLifecycleNotPermitted } from "./lifecycle.mjs";
21
21
  import { MAXIMUM_NATIVE_IMAGE_BYTES } from "./images.mjs";
22
22
  import { MAXIMUM_ROUTING_ATTACHMENT_BYTES, describeRoutingAttachment, routingAttachmentDeadline } from "./attachment-description.mjs";
23
23
  import { attachmentUrl } from "../attachments.mjs";
@@ -396,7 +396,7 @@ async function handleInboundMessage(input) {
396
396
  conversationLanguage: conversationLanguage([sent.text || sent.caption, ...dependencies.observed.recent(chat).map((message) => message.text).reverse()])
397
397
  });
398
398
  input.request.lifecycle = dependencies.lifecycle(principal, member.id, sent);
399
- input.request.stopTyping = startTypingHeartbeat(context.telegram);
399
+ await context.telegram.startTyping();
400
400
  try {
401
401
  const admitted = await input.request.lifecycle("admitted", { attachments: sent.attachments.map((file) => ({
402
402
  id: file.fileId,
@@ -438,8 +438,6 @@ async function handleInboundMessage(input) {
438
438
  });
439
439
  return null;
440
440
  }
441
- input.request.stopTyping?.();
442
- input.request.stopTyping = void 0;
443
441
  console.info("[segmentstream] telegram.phase", {
444
442
  phase: "lifecycle_not_permitted",
445
443
  traceId: input.request.traceId,
@@ -454,16 +452,6 @@ async function handleInboundMessage(input) {
454
452
  input.request.triggeringMessageId = sent.messageId;
455
453
  input.request.chatId = sent.chat.id;
456
454
  input.request.replyTo ??= sent.messageId;
457
- input.request.monitor = (session, marker) => {
458
- input.request?.backgroundUntil?.(typingUntilComplete(session, marker, context.telegram, new AbortController().signal, {
459
- traceId: input.request?.traceId,
460
- intakeId: input.request?.lifecycleKey,
461
- chatId: sent.chat.id,
462
- messageId: sent.messageId
463
- }).catch((error) => {
464
- reportTelegramError("typing_monitor_failed", error, { sessionId: session.sessionId });
465
- }));
466
- };
467
455
  }
468
456
  let address = scopedAddress(messageAddress(sent), dependencies.sessions().scope);
469
457
  const operations = input.request?.sessions;
@@ -1,6 +1,4 @@
1
1
  import type { SessionAuthContext } from "eve/context";
2
- import type { TelegramContext } from "eve/channels/telegram";
3
- import type { Delivery } from "eve/sessions";
4
2
  import type { Environment } from "../environment.js";
5
3
  import type { RuntimeToken } from "../runtime-token.js";
6
4
  export interface AttachmentLifecycle {
@@ -50,7 +48,3 @@ export declare function attachmentLifecycle(options: {
50
48
  readonly token?: RuntimeToken;
51
49
  readonly fetch?: typeof fetch;
52
50
  }): (phase: "admitted" | "stored" | "retained" | "ready" | "completed", data?: Record<string, unknown>) => Promise<LifecycleResult>;
53
- /** Kept inside the webhook's waitUntil lifetime; terminal durable stream events close the reader. */
54
- export declare function typingUntilComplete(session: Delivery, marker: string, telegram: TelegramContext["telegram"], signal: AbortSignal, metadata?: Readonly<Record<string, string | undefined>>): Promise<void>;
55
- /** No global timer survives a request or terminal event; failures retain safe method/status telemetry. */
56
- export declare function startTypingHeartbeat(telegram: TelegramContext["telegram"]): () => void;
@@ -4,13 +4,13 @@ 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-DMNXj4PX.mjs";
7
+ import { d as telegramRuntimeSource, l as principalRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-D99Lleae.mjs";
8
8
  import { object } from "../confirmation-description.mjs";
9
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
9
+ import { n as currentInboundRequest } from "../../../_chunks/inbound-request-D1r0FkDI.mjs";
10
10
  import { member } from "../actor.mjs";
11
11
  import { needsConfirmation } from "../confirmations.mjs";
12
12
  import { OntologyActionNotPermitted, actionToolName, ontologyTools } from "../ontology-tools.mjs";
13
- import { t as agentBuild } from "../../../_chunks/build-metadata-Wt6SOKfE.mjs";
13
+ import { t as agentBuild } from "../../../_chunks/build-metadata-D_Gqlb5f.mjs";
14
14
  var AttachmentLifecycleNotPermitted = class extends Error {
15
15
  code = "attachment_lifecycle_not_permitted";
16
16
  };
@@ -84,101 +84,4 @@ function attachmentLifecycle(options) {
84
84
  };
85
85
  };
86
86
  }
87
- async function typingUntilComplete(session, marker, telegram, signal, metadata = {}) {
88
- const iterator = session.stream({ signal })[Symbol.asyncIterator]();
89
- let turn;
90
- let firstResponse = false;
91
- const abort = () => {
92
- iterator.return?.().catch(() => void 0);
93
- };
94
- signal.addEventListener("abort", abort, { once: true });
95
- const stop = startTypingHeartbeat(telegram);
96
- try {
97
- while (!signal.aborted) {
98
- const item = await iterator.next();
99
- if (item.done) break;
100
- const event = item.value;
101
- if (event.type === "delivery.consumed" && event.data.parts.some((part) => part.kind === "text" && part.text.includes(marker))) {
102
- turn = event.data.turnId;
103
- console.info("[segmentstream] telegram.phase", {
104
- ...metadata,
105
- phase: "turn_received",
106
- at: new Date().toISOString(),
107
- sessionId: session.sessionId,
108
- turnId: turn
109
- });
110
- }
111
- if (turn && event.scope?.turnId === turn && [
112
- "model.started",
113
- "call.requested",
114
- "call.settled",
115
- "turn.settled"
116
- ].includes(event.type)) console.info("[segmentstream] telegram.phase", {
117
- ...metadata,
118
- phase: event.type,
119
- at: new Date().toISOString(),
120
- sessionId: session.sessionId,
121
- turnId: turn
122
- });
123
- if (turn && !firstResponse && event.type === "content.delta" && event.scope?.turnId === turn) {
124
- firstResponse = true;
125
- console.info("[segmentstream] telegram.phase", {
126
- ...metadata,
127
- phase: "model_first_response",
128
- at: new Date().toISOString(),
129
- sessionId: session.sessionId,
130
- turnId: turn
131
- });
132
- }
133
- if (event.type === "session.ended") break;
134
- if (turn && event.scope?.turnId === turn && [
135
- "turn.settled",
136
- "turn.paused",
137
- "interaction.opened"
138
- ].includes(event.type)) break;
139
- }
140
- } finally {
141
- stop();
142
- signal.removeEventListener("abort", abort);
143
- await iterator.return?.().catch(() => void 0);
144
- }
145
- }
146
- function startTypingHeartbeat(telegram) {
147
- let stopped = false;
148
- let timer;
149
- const tick = async () => {
150
- const startedAt = Date.now();
151
- try {
152
- const response = await telegram.request("sendChatAction", {
153
- chat_id: telegram.chatId,
154
- action: "typing",
155
- ...telegram.messageThreadId === void 0 ? {} : { message_thread_id: telegram.messageThreadId }
156
- });
157
- console.info("[segmentstream] telegram.method", {
158
- method: "sendChatAction",
159
- at: new Date().toISOString(),
160
- chatId: telegram.chatId,
161
- status: response.status,
162
- accepted: response.ok && object(response.body).ok === true
163
- });
164
- if (!response.ok || object(response.body).ok !== true) throw new Error("Telegram rejected sendChatAction.", { cause: {
165
- status: response.status,
166
- body: response.body
167
- } });
168
- } catch (error) {
169
- reportTelegramError("typing_failed", error, {
170
- method: "sendChatAction",
171
- chatId: telegram.chatId
172
- });
173
- }
174
- if (!stopped) timer = setTimeout(() => {
175
- tick();
176
- }, Math.max(0, 4e3 - (Date.now() - startedAt)));
177
- };
178
- tick();
179
- return () => {
180
- stopped = true;
181
- if (timer !== void 0) clearTimeout(timer);
182
- };
183
- }
184
- export { AttachmentLifecycleNotPermitted, attachmentLifecycle, startTypingHeartbeat, typingUntilComplete };
87
+ export { AttachmentLifecycleNotPermitted, attachmentLifecycle };
@@ -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-xmrm-49O.mjs";
8
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.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-DMNXj4PX.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-D99Lleae.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-xmrm-49O.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.mjs";
8
8
  import { createHash } from "node:crypto";
9
9
  function strandedRun(error) {
10
10
  if (!(error instanceof Error) || error.name !== "RunKeyFetchError" || !("status" in error) || error.status !== 404) return;
@@ -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-DMNXj4PX.mjs";
7
+ import "../../../_chunks/principal-D99Lleae.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-xmrm-49O.mjs";
11
+ import { a as TelegramDeliveryError, l as customerMessage, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.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-DMNXj4PX.mjs";
8
+ import { d as telegramRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-D99Lleae.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,9 +5,9 @@ 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-DMNXj4PX.mjs";
8
+ import { i as memberIdOf } from "../../../_chunks/principal-D99Lleae.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-xmrm-49O.mjs";
10
+ import { c as customerCopy, d as failureText, o as currentLocale, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-D1r0FkDI.mjs";
11
11
  import { recordSessionFailure } from "./conversations.mjs";
12
12
  import { isSilentRoutingCancellation } from "../group-routing/cancellation.mjs";
13
13
  import { modelServiceFailure } from "../model-service-failure.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 { p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-D1r0FkDI.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-DMNXj4PX.mjs";
8
+ import { a as rolesOf } from "../_chunks/principal-D99Lleae.mjs";
9
9
  import { runs } from "eve/events";
10
10
  import { defineDynamic } from "eve";
11
11
  function chooseModel(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-DMNXj4PX.mjs";
7
+ import { u as runtimeEnvelope } from "../../_chunks/principal-D99Lleae.mjs";
8
8
  import { n as workflowToolResult } from "../../_chunks/workflow-serializable-DU7WeCIW.mjs";
9
9
  import segmentstream from "../extension.mjs";
10
10
  import { memberTool } from "../lib/actor.mjs";
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { agentTaskIdOf, agentTaskSessions } from "../lib/agent-task.mjs";
8
- import { i as memberIdOf } from "../../_chunks/principal-DMNXj4PX.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-D99Lleae.mjs";
9
9
  import { n as workflowToolResult } from "../../_chunks/workflow-serializable-DU7WeCIW.mjs";
10
10
  import { pendingQuestions, questionKey } from "../lib/questions.mjs";
11
11
  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.25.7",
3
+ "version": "0.26.1",
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",
@@ -74,7 +74,7 @@
74
74
  },
75
75
  "dependencies": {
76
76
  "@chat-adapter/telegram": "4.41.0",
77
- "@segmentstream-cloud/ontology": "0.80.0",
77
+ "@segmentstream-cloud/ontology": "0.80.1",
78
78
  "@vercel/oidc": "^3.8.4",
79
79
  "ai": "^7.0.137",
80
80
  "csv-parse": "^7.0.3",
@@ -1,52 +0,0 @@
1
- /** Transport coordinates from an admitted turn; never a token or provider credential. */
2
- export interface TelegramTypingSource {
3
- readonly sessionId: string;
4
- readonly marker?: string;
5
- readonly turnId?: string;
6
- readonly connection: string;
7
- readonly chatId: string;
8
- readonly threadId?: number;
9
- readonly memberId: string;
10
- }
11
- export interface TypingCursor {
12
- readonly index: number;
13
- readonly turnId: string | null;
14
- /** When the monitor first ran, in epoch milliseconds; continuations carry it forward. */
15
- readonly startedAt?: number;
16
- }
17
- interface TypingEvent {
18
- readonly type: string;
19
- readonly scope?: {
20
- readonly turnId?: string;
21
- };
22
- readonly meta?: {
23
- readonly position?: {
24
- readonly line: number;
25
- readonly index: number;
26
- };
27
- readonly endOfLine?: boolean;
28
- readonly next?: number;
29
- };
30
- readonly data?: unknown;
31
- }
32
- interface TypingBlockDependencies {
33
- readonly events: (index: number, signal: AbortSignal) => AsyncIterable<TypingEvent>;
34
- readonly status: () => Promise<string>;
35
- readonly send: () => Promise<boolean>;
36
- readonly now: () => number;
37
- readonly pause: (milliseconds: number) => Promise<void>;
38
- }
39
- export interface TypingBlockResult {
40
- readonly cursor: TypingCursor;
41
- readonly done: boolean;
42
- readonly reason: string;
43
- readonly sent: number;
44
- }
45
- /** The longest a turn shows typing; a longer turn keeps working without the indicator. */
46
- export declare const MAX_TYPING_MS: number;
47
- /** One bounded activity. Its durable parent continues independently of the webhook host. */
48
- export declare function runTypingBlock(source: TelegramTypingSource, cursor: TypingCursor, dependencies: TypingBlockDependencies): Promise<TypingBlockResult>;
49
- export declare function telegramTypingBlock(source: TelegramTypingSource, cursor: TypingCursor, sessionStatus: string): Promise<TypingBlockResult>;
50
- /** Link the durable monitor to the source turn without any customer-visible message. */
51
- export declare function recordTelegramTypingStart(source: TelegramTypingSource, workflowRunId: string): Promise<void>;
52
- export {};
@@ -1,182 +0,0 @@
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 { channelsEnabled, proxyEnvironment } from "../environment.mjs";
8
- import { runtimeToken } from "../runtime-token.mjs";
9
- import { redactTelegramDiagnostic } from "./diagnostic-redaction.mjs";
10
- import { conversationEvent, conversations } from "../conversations.mjs";
11
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
12
- import { connectionProxy } from "../connection-proxy.mjs";
13
- import { sessions } from "eve/server";
14
- const object = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
15
- const MAX_TYPING_MS = 18e5;
16
- async function runTypingBlock(source, cursor, dependencies) {
17
- const deadline = dependencies.now() + 3e4;
18
- const startedAt = cursor.startedAt ?? dependencies.now();
19
- let index = cursor.index, turnId = cursor.turnId ?? source.turnId ?? null, sent = 0;
20
- const result = (done, reason) => ({
21
- cursor: {
22
- index,
23
- turnId,
24
- startedAt
25
- },
26
- done,
27
- reason,
28
- sent
29
- });
30
- if (dependencies.now() - startedAt >= 18e5) return result(true, "typing_expired");
31
- if ([
32
- "completed",
33
- "failed",
34
- "cancelled"
35
- ].includes(await dependencies.status())) return result(true, "session_terminal");
36
- while (dependencies.now() < deadline) {
37
- const started = dependencies.now();
38
- const controller = new AbortController();
39
- const iterator = dependencies.events(index, controller.signal)[Symbol.asyncIterator]();
40
- let timer;
41
- const expired = new Promise((resolve) => {
42
- timer = setTimeout(() => {
43
- resolve(null);
44
- controller.abort();
45
- }, Math.min(1500, Math.max(0, deadline - dependencies.now())));
46
- });
47
- try {
48
- while (dependencies.now() < deadline) {
49
- const next = await Promise.race([iterator.next(), expired]);
50
- if (next === null) return result(false, "history_read_timeout");
51
- if (next.done) break;
52
- const event = next.value;
53
- if (event.meta?.position === void 0) index += 1;
54
- else if (event.meta.endOfLine !== false) index = event.meta.next ?? event.meta.position.line + 1;
55
- const data = object(event.data) ? event.data : {};
56
- if (event.type === "delivery.consumed" && Array.isArray(data.parts) && typeof source.marker === "string" && source.marker !== "" && data.parts.some((part) => object(part) && part.kind === "text" && typeof part.text === "string" && part.text.includes(source.marker)) && typeof data.turnId === "string") turnId = data.turnId;
57
- if (event.type === "session.ended") return result(true, event.type);
58
- if (turnId !== null && (event.scope?.turnId ?? data.turnId) === turnId && [
59
- "turn.settled",
60
- "turn.paused",
61
- "interaction.opened"
62
- ].includes(event.type)) return result(true, event.type);
63
- }
64
- } finally {
65
- clearTimeout(timer);
66
- controller.abort();
67
- iterator.return?.().catch(() => {});
68
- }
69
- if (dependencies.now() >= deadline) return result(false, "continue");
70
- if (turnId !== null) {
71
- if (await dependencies.send()) sent += 1;
72
- }
73
- await dependencies.pause(Math.max(0, 2e3 - (dependencies.now() - started)));
74
- }
75
- return result(false, "continue");
76
- }
77
- async function telegramTypingBlock(source, cursor, sessionStatus) {
78
- try {
79
- if (!channelsEnabled()) return {
80
- cursor,
81
- done: true,
82
- reason: "channels_disabled",
83
- sent: 0
84
- };
85
- const proxy = connectionProxy({
86
- environment: proxyEnvironment(),
87
- connection: source.connection,
88
- token: runtimeToken
89
- });
90
- const result = await runTypingBlock(source, cursor, {
91
- status: async () => sessionStatus,
92
- events: (index, signal) => sessions.attach(source.sessionId).stream({
93
- startIndex: index,
94
- follow: false,
95
- signal
96
- }),
97
- now: Date.now,
98
- pause: (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
99
- send: async () => {
100
- try {
101
- const response = await proxy.request({
102
- api: "bot",
103
- method: "POST",
104
- path: "/sendChatAction",
105
- headers: [["content-type", "application/json"]],
106
- body: Buffer.from(JSON.stringify({
107
- chat_id: source.chatId,
108
- action: "typing",
109
- ...source.threadId === void 0 ? {} : { message_thread_id: source.threadId }
110
- }))
111
- }, AbortSignal.timeout(5e3));
112
- const body = JSON.parse(Buffer.from(response.body).toString("utf8"));
113
- const accepted = response.status >= 200 && response.status < 300 && object(body) && body.ok === true;
114
- console.info("[segmentstream] telegram.method", {
115
- method: "sendChatAction",
116
- at: new Date().toISOString(),
117
- chatId: source.chatId,
118
- status: response.status,
119
- accepted,
120
- sessionId: source.sessionId,
121
- durable: true
122
- });
123
- if (!accepted) throw new Error("Telegram rejected sendChatAction.", { cause: {
124
- status: response.status,
125
- body
126
- } });
127
- return true;
128
- } catch (error) {
129
- reportTelegramError("typing_failed", error, {
130
- chatId: source.chatId,
131
- sessionId: source.sessionId,
132
- durable: true
133
- });
134
- return false;
135
- }
136
- }
137
- });
138
- console.info("[segmentstream] telegram.typing_block", {
139
- sessionId: source.sessionId,
140
- turnId: result.cursor.turnId,
141
- cursor: result.cursor.index,
142
- done: result.done,
143
- reason: result.reason,
144
- sent: result.sent
145
- });
146
- return result;
147
- } catch (error) {
148
- reportTelegramError("typing_monitor_failed", error, {
149
- sessionId: source.sessionId,
150
- durable: true
151
- });
152
- throw new Error("Durable typing monitor failed.", { cause: redactTelegramDiagnostic(error) });
153
- }
154
- }
155
- async function recordTelegramTypingStart(source, workflowRunId) {
156
- console.info("[segmentstream] telegram.typing_started", {
157
- sessionId: source.sessionId,
158
- workflowRunId
159
- });
160
- try {
161
- await conversations().append(conversationEvent({
162
- provider: "telegram",
163
- chatId: source.chatId,
164
- chatType: source.chatId.startsWith("-") ? "group" : "private",
165
- threadId: source.threadId === void 0 ? null : String(source.threadId),
166
- eventId: `telegram:typing:${workflowRunId}`,
167
- sessionId: source.sessionId,
168
- turnId: source.turnId ?? null,
169
- participantIds: [source.memberId],
170
- kind: "decision",
171
- decision: "silent",
172
- reason: "typing_monitor_started",
173
- argsSummary: JSON.stringify({ workflowRunId })
174
- }));
175
- } catch (error) {
176
- reportTelegramError("typing_monitor_recording_failed", error, {
177
- sessionId: source.sessionId,
178
- workflowRunId
179
- });
180
- }
181
- }
182
- export { MAX_TYPING_MS, recordTelegramTypingStart, runTypingBlock, telegramTypingBlock };