@segmentstream/agent 0.17.3 → 0.17.7

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 (49) hide show
  1. package/README.md +18 -1
  2. package/dist/_chunks/{build-metadata-Cq47dn8C.mjs → build-metadata-DNcZwjhU.mjs} +1 -1
  3. package/dist/_chunks/{inbound-request-RIRNBxUC.mjs → inbound-request-DxRm5LC8.mjs} +1 -0
  4. package/dist/_chunks/{principal-MEMlG3EG.mjs → principal-B6u41vIf.mjs} +1 -1
  5. package/dist/extension/hooks/authorization.mjs +1 -1
  6. package/dist/extension/lib/attachment-tools.mjs +1 -1
  7. package/dist/extension/lib/build-metadata.mjs +1 -1
  8. package/dist/extension/lib/confirmations.mjs +1 -1
  9. package/dist/extension/lib/conversation-runtime.mjs +1 -1
  10. package/dist/extension/lib/deferred-confirmations.mjs +1 -1
  11. package/dist/extension/lib/file-grant.d.ts +3 -0
  12. package/dist/extension/lib/file-grant.mjs +25 -0
  13. package/dist/extension/lib/ontology-connection.mjs +1 -1
  14. package/dist/extension/lib/ontology-gateway.mjs +1 -1
  15. package/dist/extension/lib/ontology-metadata-read.mjs +1 -1
  16. package/dist/extension/lib/ontology-tools.d.ts +7 -0
  17. package/dist/extension/lib/ontology-tools.mjs +15 -2
  18. package/dist/extension/lib/runtime-envelope.mjs +1 -1
  19. package/dist/extension/lib/stored-files.mjs +15 -6
  20. package/dist/extension/lib/telegram/adapter.mjs +16 -5
  21. package/dist/extension/lib/telegram/attachment-description.mjs +1 -1
  22. package/dist/extension/lib/telegram/attachments-send.d.ts +3 -0
  23. package/dist/extension/lib/telegram/attachments-send.mjs +24 -8
  24. package/dist/extension/lib/telegram/callbacks.mjs +2 -2
  25. package/dist/extension/lib/telegram/confirmation-expiry.mjs +1 -1
  26. package/dist/extension/lib/telegram/confirmations.mjs +2 -2
  27. package/dist/extension/lib/telegram/conversations.mjs +1 -1
  28. package/dist/extension/lib/telegram/customer-text.mjs +1 -1
  29. package/dist/extension/lib/telegram/deferred-confirmations.mjs +2 -2
  30. package/dist/extension/lib/telegram/files.mjs +2 -2
  31. package/dist/extension/lib/telegram/health.mjs +1 -1
  32. package/dist/extension/lib/telegram/images.mjs +1 -1
  33. package/dist/extension/lib/telegram/inbound-request.d.ts +2 -0
  34. package/dist/extension/lib/telegram/inbound-request.mjs +1 -1
  35. package/dist/extension/lib/telegram/inbound.mjs +24 -20
  36. package/dist/extension/lib/telegram/lifecycle.mjs +3 -3
  37. package/dist/extension/lib/telegram/media-policy.mjs +1 -1
  38. package/dist/extension/lib/telegram/principal.mjs +1 -1
  39. package/dist/extension/lib/telegram/session-recovery.d.ts +10 -0
  40. package/dist/extension/lib/telegram/session-recovery.mjs +66 -0
  41. package/dist/extension/lib/telegram/silent.mjs +2 -2
  42. package/dist/extension/lib/telegram/structured.mjs +1 -1
  43. package/dist/extension/lib/telegram/turn-errors.mjs +2 -2
  44. package/dist/extension/lib/telegram/voice.mjs +1 -1
  45. package/dist/extension/model.mjs +1 -1
  46. package/dist/extension/tools/attachments_promote.mjs +1 -1
  47. package/dist/extension/tools/ontology.mjs +1 -1
  48. package/dist/extension/tools/questions_ask.mjs +1 -1
  49. package/package.json +2 -2
package/README.md CHANGED
@@ -615,7 +615,7 @@ Eve resolution, so member/topic routing survives a cold start. No second provide
615
615
 
616
616
  ## Release and migration
617
617
 
618
- The coordinated release uses Agent SDK 0.17.3, Eve 0.76.3, Ontology SDK 0.54.0 and App SDK 0.25.0.
618
+ The coordinated release uses Agent SDK 0.17.6, Eve 0.76.3, Ontology SDK 0.54.2 and App SDK 0.25.0.
619
619
  The compatible Cloud archive/API must be deployed first; migrations run only through its CI/CD gate.
620
620
  Publish the ontology SDK before the agent SDK. Upgrade the workspace ontology before its agent,
621
621
  with the declared Telegram provider mapping and explicit `agent_chat:post_message` grant.
@@ -628,6 +628,23 @@ disables posting while preserving archive claims and deduplication tombstones;
628
628
  it never restores relay or retries uncertain deliveries.
629
629
  See [migration and verification](../../docs/agent-chat-delivery-migration.md).
630
630
 
631
+ ### Deleted session deployments
632
+
633
+ If Eve's session lookup raises `RunKeyFetchError` with HTTP 404 and Vercel's
634
+ `not_found` / `Deployment not found.` response, the Telegram adapter records the
635
+ original diagnostic and uses a fresh continuation scoped to the serving deployment.
636
+ The smart gate still decides whether to reply; observing a message creates no session
637
+ and sends no failure notice. Independent requests and cold starts select the same
638
+ replacement. Healthy sessions continue across deployments as before. Once an address
639
+ needs recovery, later deployments start it fresh; archived conversation context remains
640
+ available, but the inaccessible session's model history and pending inputs cannot migrate.
641
+
642
+ Recovery applies only to session reads. Dispatch failures are never retried because
643
+ the inbox may already have accepted them. Other provider errors propagate to operator
644
+ diagnostics. A group receives a failure notice only after routing selected a reply or
645
+ a workspace hook acknowledged the task. Notice wording comes from workspace `texts.notice`.
646
+ See [the incident and verification procedure](../../docs/telegram-session-recovery.md).
647
+
631
648
  ### Opt-in attachment lifecycle
632
649
 
633
650
  `channels.telegram.attachmentLifecycle: { entity, action }` selects a permitted,
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- var version = "0.17.3";
7
+ var version = "0.17.7";
8
8
  function agentBuild(environment = process.env) {
9
9
  return {
10
10
  agent: version,
@@ -253,6 +253,7 @@ var InboundRequest = class {
253
253
  previousContent;
254
254
  claimRevision;
255
255
  deliveryFailed;
256
+ engaged = false;
256
257
  claimTurn;
257
258
  beginDispatch;
258
259
  finishClaim;
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { n as currentInboundRequest } from "./inbound-request-RIRNBxUC.mjs";
7
+ import { n as currentInboundRequest } from "./inbound-request-DxRm5LC8.mjs";
8
8
  import { randomUUID } from "node:crypto";
9
9
  function telegramRuntimeSource(message, files, callbackQueryId) {
10
10
  const attachments = [];
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { localizedText } from "../lib/admission.mjs";
8
- import "../../_chunks/principal-MEMlG3EG.mjs";
8
+ import "../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { confirmationLocale } from "../lib/telegram/confirmation-text.mjs";
10
10
  import segmentstream from "../extension.mjs";
11
11
  import { defineHook } from "eve/hooks";
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
- import { i as memberIdOf } from "../../_chunks/principal-MEMlG3EG.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { runtimeToken } from "./runtime-token.mjs";
10
10
  import { agentAttachments } from "./attachments.mjs";
11
11
  import { telegramConversation } from "./telegram/files.mjs";
@@ -4,5 +4,5 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { t as agentBuild } from "../../_chunks/build-metadata-Cq47dn8C.mjs";
7
+ import { t as agentBuild } from "../../_chunks/build-metadata-DNcZwjhU.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-MEMlG3EG.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { confirmationCopy, confirmationLocale, renderConfirmation } from "./telegram/confirmation-text.mjs";
10
10
  import { chatPostCard } from "./telegram/chat-post-card.mjs";
11
11
  import { chatPostDigest, isChatPost } from "./chat-post-confirmation.mjs";
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { ENDS_CONVERSATION_INSTRUCTIONS } from "./group-routing/conversation-prompt.mjs";
8
- import { i as memberIdOf } from "../../_chunks/principal-MEMlG3EG.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { n as contentText, t as CONTENT_CAPS } from "../../_chunks/content-CvFsrmSD.mjs";
10
10
  import { conversationEvent, conversations, sessionFailureEventId, summarizeArguments } from "./conversations.mjs";
11
11
  import { parseAddress } from "./telegram/sessions.mjs";
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
- import { i as memberIdOf, l as principalRuntimeSource, u as runtimeEnvelope } from "../../_chunks/principal-MEMlG3EG.mjs";
8
+ import { i as memberIdOf, l as principalRuntimeSource, u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { redactDiagnostic } from "./diagnostics.mjs";
10
10
  import { humanText, object } from "./confirmation-description.mjs";
11
11
  import { runtimeToken } from "./runtime-token.mjs";
@@ -0,0 +1,3 @@
1
+ export declare const transientFileStatus: (status: number) => boolean;
2
+ /** Only for reads that issue a file grant; never wrap a delivery or a mutation. */
3
+ export declare function fetchFileGrant(send: () => Promise<Response>): Promise<Response>;
@@ -0,0 +1,25 @@
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
+ const transientFileStatus = (status) => [
8
+ 429,
9
+ 502,
10
+ 503,
11
+ 504
12
+ ].includes(status);
13
+ async function fetchFileGrant(send) {
14
+ for (let attempt = 0;; attempt++) {
15
+ const response = await send();
16
+ if (!transientFileStatus(response.status) || attempt === 2) return response;
17
+ const retryAfter = response.headers.get("retry-after");
18
+ const seconds = Number(retryAfter);
19
+ const delay = retryAfter === null ? 500 * 2 ** attempt : Number.isFinite(seconds) ? Math.max(0, seconds * 1e3) : Date.parse(retryAfter) - Date.now();
20
+ if (!Number.isFinite(delay) || delay < 0 || delay > 5e3) return response;
21
+ await response.body?.cancel();
22
+ await new Promise((resolve) => setTimeout(resolve, delay));
23
+ }
24
+ }
25
+ export { fetchFileGrant, transientFileStatus };
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
- import { c as compatibleRuntimeEnvelope, i as memberIdOf, r as identityProviderOf, u as runtimeEnvelope } from "../../_chunks/principal-MEMlG3EG.mjs";
8
+ import { c as compatibleRuntimeEnvelope, i as memberIdOf, r as identityProviderOf, u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { runtimeToken, tokenExpiry } from "./runtime-token.mjs";
10
10
  import { CHAT_POST_ENVELOPE, chatPostDigest, chatPostOperationId, isChatPost } from "./chat-post-confirmation.mjs";
11
11
  import { actionApproval, confirmations } from "./confirmations.mjs";
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { i as memberIdOf, u as runtimeEnvelope } from "../../_chunks/principal-MEMlG3EG.mjs";
7
+ import { i as memberIdOf, u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
8
8
  import { object } from "./confirmation-description.mjs";
9
9
  import { readOntologyMetadata } from "./ontology-metadata-read.mjs";
10
10
  async function ontologyMetadata(memberId, operation, input, context, options = {}) {
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
- import { i as memberIdOf } from "../../_chunks/principal-MEMlG3EG.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { redactDiagnostic } from "./diagnostics.mjs";
10
10
  import { object } from "./confirmation-description.mjs";
11
11
  import { OntologyToolRejected, ontologyTools } from "./ontology-tools.mjs";
@@ -11,6 +11,13 @@ export declare class OntologyToolRejected extends Error {
11
11
  export declare class OntologyActionNotPermitted extends Error {
12
12
  readonly code = "ontology_action_not_permitted";
13
13
  }
14
+ /** A known read-only file request can be repeated; action outcomes keep their existing fence. */
15
+ export declare class OntologyFileUnavailable extends Error {
16
+ readonly code: string;
17
+ readonly requestId: string | undefined;
18
+ readonly retryable = true;
19
+ constructor(code: string, requestId: string | undefined, options?: ErrorOptions);
20
+ }
14
21
  /** A fresh, permission-filtered catalog. Listing tools cannot run an action's prepare step. */
15
22
  export declare function ontologyTools(options?: {
16
23
  readonly principal?: SessionAuthContext | null;
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin } from "./environment.mjs";
8
- import { c as compatibleRuntimeEnvelope, i as memberIdOf, r as identityProviderOf, s as RUNTIME_SOURCE_PROTOCOL, u as runtimeEnvelope } from "../../_chunks/principal-MEMlG3EG.mjs";
8
+ import { c as compatibleRuntimeEnvelope, i as memberIdOf, r as identityProviderOf, s as RUNTIME_SOURCE_PROTOCOL, u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { redactDiagnostic } from "./diagnostics.mjs";
10
10
  import { describeConfirmation, object } from "./confirmation-description.mjs";
11
11
  import { runtimeToken } from "./runtime-token.mjs";
@@ -17,6 +17,16 @@ var OntologyToolRejected = class extends Error {
17
17
  var OntologyActionNotPermitted = class extends Error {
18
18
  code = "ontology_action_not_permitted";
19
19
  };
20
+ var OntologyFileUnavailable = class extends Error {
21
+ code;
22
+ requestId;
23
+ retryable = true;
24
+ constructor(code, requestId, options) {
25
+ super(`${code}${requestId === void 0 ? "" : ` (${requestId})`}`, options);
26
+ this.code = code;
27
+ this.requestId = requestId;
28
+ }
29
+ };
20
30
  function ontologyTools(options = {}) {
21
31
  const runtimeSources = options.runtimeSources ?? new Map();
22
32
  async function rpc(memberId, method, params, signal) {
@@ -61,6 +71,8 @@ function ontologyTools(options = {}) {
61
71
  const result = object(body.result);
62
72
  if (method === "tools/list" && Array.isArray(result.tools)) runtimeSources.set(memberId, result.tools.map(object).some((tool) => object(tool._meta)[RUNTIME_SOURCE_PROTOCOL] === 1));
63
73
  if (result.isError === true) {
74
+ const failure = object(result.structuredContent);
75
+ if (method === "tools/call" && params.name === "files_download" && failure.retryable === true && ["ontology_updating", "storage_unavailable"].includes(String(failure.error))) throw new OntologyFileUnavailable(String(failure.error), typeof failure.request_id === "string" ? failure.request_id : void 0, { cause: result });
64
76
  const message = (Array.isArray(result.content) ? result.content : []).map(object).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join("\n");
65
77
  if ([
66
78
  "action_rejected",
@@ -87,6 +99,7 @@ function ontologyTools(options = {}) {
87
99
  reference,
88
100
  error: diagnostic
89
101
  });
102
+ if (error instanceof OntologyFileUnavailable) throw new OntologyFileUnavailable(error.code, error.requestId, { cause: diagnostic });
90
103
  if (error instanceof OntologyToolRejected) throw new OntologyToolRejected(String(object(diagnostic).message), { cause: diagnostic });
91
104
  throw new Error(`The ontology request failed (${reference}).`, { cause: diagnostic });
92
105
  }
@@ -246,4 +259,4 @@ function promotionTarget(input) {
246
259
  }
247
260
  };
248
261
  }
249
- export { OntologyActionNotPermitted, OntologyToolRejected, actionToolName, ontologyToolLabels, ontologyTools, promotionTarget };
262
+ export { OntologyActionNotPermitted, OntologyFileUnavailable, OntologyToolRejected, actionToolName, ontologyToolLabels, ontologyTools, promotionTarget };
@@ -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-MEMlG3EG.mjs";
7
+ import { c as compatibleRuntimeEnvelope, d as telegramRuntimeSource, l as principalRuntimeSource, s as RUNTIME_SOURCE_PROTOCOL, u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
8
8
  export { RUNTIME_SOURCE_PROTOCOL, compatibleRuntimeEnvelope, principalRuntimeSource, runtimeEnvelope, telegramRuntimeSource };
@@ -4,21 +4,30 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { i as memberIdOf } from "../../_chunks/principal-MEMlG3EG.mjs";
7
+ import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
8
8
  import { redactDiagnostic } from "./diagnostics.mjs";
9
9
  import { object } from "./confirmation-description.mjs";
10
- import { ontologyTools } from "./ontology-tools.mjs";
10
+ import { OntologyFileUnavailable, ontologyTools } from "./ontology-tools.mjs";
11
11
  import { createHash } from "node:crypto";
12
12
  async function readStoredFile(input, principal, options = {}) {
13
13
  const memberId = memberIdOf(principal);
14
14
  if (memberId === void 0) throw new Error("A current member is required to read a stored file.");
15
- const raw = await ontologyTools({
15
+ const tools = ontologyTools({
16
16
  ...options,
17
17
  principal
18
- }).rpc(memberId, "tools/call", {
19
- name: "files_download",
20
- arguments: input
21
18
  });
19
+ const readGrant = async () => {
20
+ for (let attempt = 0;; attempt++) try {
21
+ return await tools.rpc(memberId, "tools/call", {
22
+ name: "files_download",
23
+ arguments: input
24
+ });
25
+ } catch (error) {
26
+ if (!(error instanceof OntologyFileUnavailable) || attempt === 2) throw error;
27
+ await new Promise((resolve) => setTimeout(resolve, error.code === "ontology_updating" ? 5e3 : 500 * 2 ** attempt));
28
+ }
29
+ };
30
+ const raw = await readGrant();
22
31
  const result = object(raw.structuredContent), file = object(result.file), grant = object(result.download);
23
32
  const headers = object(grant.headers);
24
33
  const size = file.size;
@@ -7,10 +7,10 @@ __eveCreateRequire(import.meta.url);
7
7
  import { telegramText, withTelegramTexts } from "./texts.mjs";
8
8
  import { manifestOf } from "../../config.mjs";
9
9
  import { appOrigin, channelsEnabled, proxyEnvironment, runtimeIdentityEnvironment, webhookSecret } from "../environment.mjs";
10
- import { n as conversationLanguage, o as telegramPrincipal } from "../../../_chunks/principal-MEMlG3EG.mjs";
10
+ import { n as conversationLanguage, o as telegramPrincipal } from "../../../_chunks/principal-B6u41vIf.mjs";
11
11
  import { confirmationLocale } from "./confirmation-text.mjs";
12
12
  import { telegramSendScope } from "./send-queue.mjs";
13
- import { d as failureText, h as withDeliveryLocale, i as withReplacedText, m as safeTelegramFetch, n as currentInboundRequest, o as currentLocale, p as reportTelegramError, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
13
+ import { d as failureText, h as withDeliveryLocale, i as withReplacedText, m as safeTelegramFetch, n as currentInboundRequest, o as currentLocale, p as reportTelegramError, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
14
14
  import { chooseModel } from "../../model.mjs";
15
15
  import { groupRoutingHealth } from "../group-routing/health.mjs";
16
16
  import { decisionRouter } from "../group-routing/router.mjs";
@@ -20,7 +20,7 @@ import { archivedRoutingMessages } from "../group-routing/routing-context.mjs";
20
20
  import { dispatchStructuredMessage, structuredMessage } from "./structured.mjs";
21
21
  import { scopedAddress, sessionPolicy } from "./sessions.mjs";
22
22
  import { handleWorkspaceCallback, isWorkspaceCallback } from "./callbacks.mjs";
23
- import { t as agentBuild } from "../../../_chunks/build-metadata-Cq47dn8C.mjs";
23
+ import { t as agentBuild } from "../../../_chunks/build-metadata-DNcZwjhU.mjs";
24
24
  import { attachmentLifecycle } from "./lifecycle.mjs";
25
25
  import { observedMessages } from "./observed.mjs";
26
26
  import { expireDeferredCards, handleDeferredCallback, isDeferredCallback } from "./deferred-confirmations.mjs";
@@ -38,6 +38,7 @@ import { gatewayMediaCapabilities, planMedia } from "./media-policy.mjs";
38
38
  import { agentChats } from "./chats.mjs";
39
39
  import { downloadTelegramFile, gatewayTranscriber } from "./voice.mjs";
40
40
  import { handleInboundMessage } from "./inbound.mjs";
41
+ import { recoverableSessions } from "./session-recovery.mjs";
41
42
  import { TELEGRAM_PLACEHOLDER_TOKEN, TELEGRAM_PROXY_ORIGIN, telegramProxyFetch } from "./proxy-fetch.mjs";
42
43
  import { healthRoute } from "./health.mjs";
43
44
  import { telegramFailureEvents } from "./turn-errors.mjs";
@@ -318,7 +319,11 @@ function segmentstreamTelegram(options) {
318
319
  }
319
320
  const errorId = reportTelegramError("inbound_message_failed", error, { chatId: message.chat.id });
320
321
  if (inbound?.retryReference !== void 0 || inbound?.lifecycleKey !== void 0 || inbound?.structuredContext !== void 0) inbound.retryReference = errorId;
321
- else await context.telegram.post(failureText(errorId));
322
+ else if (message.chat.type === "private" || inbound?.engaged === true) try {
323
+ await context.telegram.post(failureText(errorId));
324
+ } catch (noticeError) {
325
+ reportTelegramError("inbound_failure_notice_failed", noticeError, { errorId });
326
+ }
322
327
  return null;
323
328
  } finally {
324
329
  inbound?.stopTyping?.();
@@ -446,6 +451,7 @@ function segmentstreamTelegram(options) {
446
451
  return {
447
452
  ...channel,
448
453
  async receive(input, operations) {
454
+ operations = recoverableSessions(operations, environment.VERCEL_DEPLOYMENT_ID, readHistory);
449
455
  const target = input.target;
450
456
  if (target.confirmationSessionId !== void 0) {
451
457
  const address = target.confirmationAddress;
@@ -480,7 +486,8 @@ function segmentstreamTelegram(options) {
480
486
  route,
481
487
  options,
482
488
  environment,
483
- capture
489
+ capture,
490
+ readHistory
484
491
  })), healthRoute({
485
492
  chats,
486
493
  ...options.groups === void 0 ? {} : { routing: groupRoutingHealth },
@@ -506,6 +513,10 @@ function gatedRoute(input) {
506
513
  handler: async (request, args) => {
507
514
  if (!channelsEnabled(environment)) return new Response("ok");
508
515
  if (options.settings() === null) return new Response("not found", { status: 404 });
516
+ args = {
517
+ ...args,
518
+ ...recoverableSessions(args, environment.VERCEL_DEPLOYMENT_ID, input.readHistory)
519
+ };
509
520
  let description;
510
521
  const describe = () => description ??= args.describe();
511
522
  const inbound = new InboundRequest(async () => (await describe()).description ?? "", async () => (await describe()).name);
@@ -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-RIRNBxUC.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.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";
@@ -20,6 +20,9 @@ export interface SentFile {
20
20
  readonly error?: string;
21
21
  readonly detail?: string;
22
22
  readonly reference?: string;
23
+ readonly status?: number;
24
+ readonly retryable?: boolean;
25
+ readonly requestId?: string;
23
26
  }
24
27
  /** Bare ids are document records; explicit references select other entities and file properties. */
25
28
  export declare function sendAttachmentsInput(value: Record<string, unknown>): SendAttachmentsInput;
@@ -5,17 +5,18 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { appOrigin, channelsEnabled, proxyEnvironment } from "../environment.mjs";
8
- import "../../../_chunks/principal-MEMlG3EG.mjs";
8
+ import "../../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { redactDiagnostic } from "../diagnostics.mjs";
10
10
  import { confirmationLocale } from "./confirmation-text.mjs";
11
11
  import { inTelegramSendQueue, telegramSendScope } from "./send-queue.mjs";
12
- import { d as failureText, f as formattingRefused, l as customerMessage, p as reportTelegramError } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
12
+ import { d as failureText, f as formattingRefused, l as customerMessage, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
13
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";
17
17
  import { TELEGRAM_PLACEHOLDER_TOKEN, TELEGRAM_PROXY_ORIGIN, telegramProxyFetch } from "./proxy-fetch.mjs";
18
18
  import { attachmentOwner } from "../attachment-tools.mjs";
19
+ import { fetchFileGrant, transientFileStatus } from "../file-grant.mjs";
19
20
  const MAXIMUM_PHOTO_BYTES = 10485760;
20
21
  const MAXIMUM_DOCUMENT_BYTES = 52428800;
21
22
  const PHOTOS = new Set([
@@ -133,12 +134,14 @@ async function sendAttachmentsInOrder(options) {
133
134
  const uploads = [];
134
135
  for (const [index, reference] of options.input.documentIds.entries()) {
135
136
  let filename = "";
137
+ let requestId;
136
138
  try {
137
- const response = await fetchImpl(`${origin}/api/ontology/agent/files/${[
139
+ const path = [
138
140
  reference.entity,
139
141
  reference.id,
140
142
  ...reference.property === void 0 ? [] : [reference.property]
141
- ].map(encodeURIComponent).join("/")}`, {
143
+ ].map(encodeURIComponent).join("/");
144
+ const response = await fetchFileGrant(async () => fetchImpl(`${origin}/api/ontology/agent/files/${path}`, {
142
145
  headers: {
143
146
  authorization: `Bearer ${await token()}`,
144
147
  [ACT_AS_HEADER]: owner.memberId,
@@ -147,10 +150,18 @@ async function sendAttachmentsInOrder(options) {
147
150
  },
148
151
  redirect: "error",
149
152
  signal: AbortSignal.timeout(3e4)
150
- });
153
+ }));
151
154
  if (!response.ok) {
152
- const code = response.status === 404 ? "not_found" : response.status === 403 ? "forbidden" : response.status === 422 ? "unsupported" : "unavailable";
153
- throw refused(code, `The ontology refused the file (${code}).`);
155
+ const body = await response.json().catch(() => void 0);
156
+ const upstream = isRecord(body) ? body : {};
157
+ const ref = upstream.request_id ?? upstream.requestId;
158
+ requestId = typeof ref === "string" ? ref : void 0;
159
+ const code = response.status === 404 ? "not_found" : response.status === 403 ? "forbidden" : response.status === 422 ? "unsupported" : response.status === 503 && upstream.error === "ontology_updating" ? "ontology_updating" : transientFileStatus(response.status) ? "retryable" : "unavailable";
160
+ throw new AttachmentError({
161
+ code,
162
+ message: code,
163
+ status: response.status
164
+ });
154
165
  }
155
166
  const answer = await response.json();
156
167
  const file = isRecord(answer) ? answer.file : void 0;
@@ -191,7 +202,12 @@ async function sendAttachmentsInOrder(options) {
191
202
  filename,
192
203
  error: error instanceof AttachmentError ? error.code : "unavailable",
193
204
  detail: failureText(errorId, "attachment", locale),
194
- reference: errorId
205
+ reference: errorId,
206
+ ...error instanceof AttachmentError && error.status !== void 0 ? {
207
+ status: error.status,
208
+ retryable: transientFileStatus(error.status)
209
+ } : {},
210
+ ...requestId === void 0 ? {} : { requestId }
195
211
  };
196
212
  }
197
213
  }
@@ -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-MEMlG3EG.mjs";
9
+ import { d as telegramRuntimeSource, i as memberIdOf, o as telegramPrincipal, u as runtimeEnvelope } from "../../../_chunks/principal-B6u41vIf.mjs";
10
10
  import { object } from "../confirmation-description.mjs";
11
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
11
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
12
12
  import { workspaceAction } from "./workspace-action.mjs";
13
13
  import { formatAddress, parseAddress, scopedAddress } from "./sessions.mjs";
14
14
  const isWorkspaceCallback = (data) => data?.startsWith("ws:") === true;
@@ -7,7 +7,7 @@ __eveCreateRequire(import.meta.url);
7
7
  import { withTelegramTexts } from "./texts.mjs";
8
8
  import { proxyEnvironment } from "../environment.mjs";
9
9
  import { telegramSendScope } from "./send-queue.mjs";
10
- import { m as safeTelegramFetch, p as reportTelegramError } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
10
+ import { m as safeTelegramFetch, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
11
11
  import { runtimeToken } from "../runtime-token.mjs";
12
12
  import { conversations } from "../conversations.mjs";
13
13
  import { deferredConfirmations } from "../deferred-confirmations.mjs";
@@ -5,11 +5,11 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { telegramText } from "./texts.mjs";
8
- import { i as memberIdOf, o as telegramPrincipal } from "../../../_chunks/principal-MEMlG3EG.mjs";
8
+ import { i as memberIdOf, o as telegramPrincipal } from "../../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { humanText } from "../confirmation-description.mjs";
10
10
  import { renderConfirmation, withConfirmationText } from "./confirmation-text.mjs";
11
11
  import { chatPostCard, chatPostCardStatus, chatPostReceipt, withChatPostCard } from "./chat-post-card.mjs";
12
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
12
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
13
13
  import { agentMessage, observedChatKey, withConfirmationPrompt } from "../group-routing/observed.mjs";
14
14
  import { conversationEvent } from "../conversations.mjs";
15
15
  import { chatPostOperationId, isChatPost } from "../chat-post-confirmation.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 { n as currentInboundRequest, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
7
+ import { n as currentInboundRequest, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
8
8
  import { n as contentText, t as CONTENT_CAPS } from "../../../_chunks/content-CvFsrmSD.mjs";
9
9
  import { currentConfirmationPrompt, observedChatKey } from "../group-routing/observed.mjs";
10
10
  import { conversationEvent, sessionFailureEventId } from "../conversations.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-RIRNBxUC.mjs";
8
+ import { a as TelegramDeliveryError, c as customerCopy, d as failureText, f as formattingRefused, h as withDeliveryLocale, l as customerMessage, m as safeTelegramFetch, o as currentLocale, p as reportTelegramError, s as currentThreadId, u as customerText } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
9
9
  export { TelegramDeliveryError, currentLocale, currentThreadId, customerCopy, customerMessage, customerText, failureText, formattingRefused, isTechnicalText, reportTelegramError, safeTelegramFetch, withDeliveryLocale };
@@ -5,11 +5,11 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { telegramText, withTelegramLocale } from "./texts.mjs";
8
- import { o as telegramPrincipal } from "../../../_chunks/principal-MEMlG3EG.mjs";
8
+ import { o as telegramPrincipal } from "../../../_chunks/principal-B6u41vIf.mjs";
9
9
  import { humanText } from "../confirmation-description.mjs";
10
10
  import { renderConfirmation, withConfirmationText } from "./confirmation-text.mjs";
11
11
  import { chatPostCard, chatPostCardStatus, chatPostReceipt, withChatPostCard } from "./chat-post-card.mjs";
12
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
12
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
13
13
  import { agentMessage, observedChatKey, withConfirmationPrompt } from "../group-routing/observed.mjs";
14
14
  import { conversationEvent } from "../conversations.mjs";
15
15
  import { CONFIRMATION_TTL_MS, inputHash } from "../confirmations.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 { n as conversationLanguage } from "../../../_chunks/principal-MEMlG3EG.mjs";
8
- import { d as failureText, p as reportTelegramError } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
7
+ import { n as conversationLanguage } from "../../../_chunks/principal-B6u41vIf.mjs";
8
+ import { d as failureText, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
9
9
  import { describableImage, describeReceivedImage } from "./images.mjs";
10
10
  import { MAXIMUM_ATTACHMENT_BYTES, attachmentUrl } from "../attachments.mjs";
11
11
  function telegramConversation(chatId) {
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { t as agentBuild } from "../../../_chunks/build-metadata-Cq47dn8C.mjs";
7
+ import { t as agentBuild } from "../../../_chunks/build-metadata-DNcZwjhU.mjs";
8
8
  import { runtimeRequestFailure } from "./runtime-request.mjs";
9
9
  import { GET } from "eve/channels";
10
10
  const HEALTH_ROUTE = "/eve/v1/telegram/health";
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
8
8
  import { gateway, generateText } from "ai";
9
9
  const MAXIMUM_IMAGE_DESCRIPTION_BYTES = 5242880;
10
10
  const MAXIMUM_NATIVE_IMAGE_BYTES = 3145728;
@@ -55,6 +55,8 @@ export declare class InboundRequest {
55
55
  /** Claims one edit revision before routing, including revisions the classifier observes. */
56
56
  claimRevision: (() => Promise<boolean>) | undefined;
57
57
  deliveryFailed: ((error: unknown) => Promise<void>) | undefined;
58
+ /** Routing chose a reply, or the workspace already acknowledged this task. */
59
+ engaged: boolean;
58
60
  /** Atomic per-message admission in the platform archive, after authentication and routing. */
59
61
  claimTurn: (() => Promise<boolean>) | undefined;
60
62
  /** Finalize the reservation only after the durable inbox acknowledges delivery. */
@@ -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-RIRNBxUC.mjs";
7
+ import { i as withReplacedText, n as currentInboundRequest, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-DxRm5LC8.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-MEMlG3EG.mjs";
10
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
9
+ import { d as telegramRuntimeSource, n as conversationLanguage, o as telegramPrincipal, u as runtimeEnvelope } from "../../../_chunks/principal-B6u41vIf.mjs";
10
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
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";
@@ -407,24 +407,27 @@ async function handleInboundMessage(input) {
407
407
  input.request.lifecycleKey = admitted.key;
408
408
  input.request.replyTo = admitted.replyTo ?? sent.messageId;
409
409
  if (admitted.key === void 0) input.request.lifecycle = void 0;
410
- if (admitted.acknowledgement) try {
411
- await context.telegram.post({
412
- text: admitted.acknowledgement,
413
- reply_parameters: { message_id: Number(input.request.replyTo) }
414
- });
415
- console.info("[segmentstream] telegram.phase", {
416
- phase: "acknowledged",
417
- at: new Date().toISOString(),
418
- traceId: input.request.traceId,
419
- intakeId: admitted.key,
420
- chatId: sent.chat.id,
421
- messageId: sent.messageId
422
- });
423
- } catch (error) {
424
- reportTelegramError("intake_acknowledgement_failed", error, {
425
- chatId: sent.chat.id,
426
- messageId: sent.messageId
427
- });
410
+ if (admitted.acknowledgement) {
411
+ input.request.engaged = true;
412
+ try {
413
+ await context.telegram.post({
414
+ text: admitted.acknowledgement,
415
+ reply_parameters: { message_id: Number(input.request.replyTo) }
416
+ });
417
+ console.info("[segmentstream] telegram.phase", {
418
+ phase: "acknowledged",
419
+ at: new Date().toISOString(),
420
+ traceId: input.request.traceId,
421
+ intakeId: admitted.key,
422
+ chatId: sent.chat.id,
423
+ messageId: sent.messageId
424
+ });
425
+ } catch (error) {
426
+ reportTelegramError("intake_acknowledgement_failed", error, {
427
+ chatId: sent.chat.id,
428
+ messageId: sent.messageId
429
+ });
430
+ }
428
431
  }
429
432
  } catch (error) {
430
433
  input.request.lifecycle = void 0;
@@ -749,6 +752,7 @@ async function handleInboundMessage(input) {
749
752
  return conversation();
750
753
  }
751
754
  });
755
+ if (route === "reply" && input.request !== void 0) input.request.engaged = true;
752
756
  let structuredDispatched = false;
753
757
  if (structured !== void 0 && dependencies.structured !== void 0) {
754
758
  if (route === "observe" || admissionRefused) {
@@ -4,12 +4,12 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { d as telegramRuntimeSource, l as principalRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-MEMlG3EG.mjs";
7
+ import { d as telegramRuntimeSource, l as principalRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-B6u41vIf.mjs";
8
8
  import { object } from "../confirmation-description.mjs";
9
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-RIRNBxUC.mjs";
9
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.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-Cq47dn8C.mjs";
12
+ import { t as agentBuild } from "../../../_chunks/build-metadata-DNcZwjhU.mjs";
13
13
  var AttachmentLifecycleNotPermitted = class extends Error {
14
14
  code = "attachment_lifecycle_not_permitted";
15
15
  };
@@ -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-RIRNBxUC.mjs";
8
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.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-MEMlG3EG.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-B6u41vIf.mjs";
8
8
  export { TELEGRAM_AUTHENTICATOR, conversationLanguage, identityProviderOf, memberIdOf, rolesOf, telegramPrincipal };
@@ -0,0 +1,10 @@
1
+ import type { ChannelReceiveContext } from "eve/channels";
2
+ import type { HistoryReader } from "./sessions.js";
3
+ /**
4
+ * Eve 0.76.3 cannot resolve/reset an inbox whose metadata key belonged to a deleted deployment.
5
+ * Recover on a read, before dispatch: independent requests on this deployment use the same fresh
6
+ * continuation. Healthy addresses keep their owner across deploys. An already broken address
7
+ * gets a fresh owner on each deployment; the archive remains the source of routing context.
8
+ * No send is retried: a dispatch error can mean the durable inbox already accepted the message.
9
+ */
10
+ export declare function recoverableSessions<State>(operations: ChannelReceiveContext<State>, deploymentId: string | undefined, readHistory?: HistoryReader): ChannelReceiveContext<State>;
@@ -0,0 +1,66 @@
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 { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
8
+ import { createHash } from "node:crypto";
9
+ function missingDeployment(error) {
10
+ if (!(error instanceof Error) || error.name !== "RunKeyFetchError" || !("status" in error) || error.status !== 404) return false;
11
+ const body = /^Failed to fetch run key for wrun_[\w-]+ \(deployment dpl_[\w-]+\): HTTP 404 [^\n]+? — (.+)$/u.exec(error.message)?.[1];
12
+ try {
13
+ const response = JSON.parse(body ?? "");
14
+ return response?.error?.code === "not_found" && response.error.message === "Deployment not found.";
15
+ } catch {
16
+ return false;
17
+ }
18
+ }
19
+ function recoverableSessions(operations, deploymentId, readHistory) {
20
+ const replacements = new Map();
21
+ const readable = new Map();
22
+ const target = (address) => replacements.get(address) ?? address;
23
+ async function lookup(address) {
24
+ const session = await operations.resolveSession(address);
25
+ if (session !== void 0 && readHistory !== void 0) {
26
+ let history = readable.get(session.id);
27
+ if (history === void 0) {
28
+ history = readHistory(session.id);
29
+ readable.set(session.id, history);
30
+ }
31
+ await history;
32
+ }
33
+ return session;
34
+ }
35
+ async function resolveSession(address) {
36
+ try {
37
+ return await lookup(target(address));
38
+ } catch (error) {
39
+ if (!deploymentId || replacements.has(address) || !missingDeployment(error)) throw error;
40
+ const replacement = `${address}:recovery:${createHash("sha256").update(JSON.stringify([address, deploymentId])).digest("hex")}`;
41
+ reportTelegramError("session_resume_recovered", error, {
42
+ address,
43
+ replacement,
44
+ deploymentId
45
+ });
46
+ replacements.set(address, replacement);
47
+ return lookup(replacement);
48
+ }
49
+ }
50
+ async function source(address) {
51
+ await resolveSession(address);
52
+ return operations.from(target(address));
53
+ }
54
+ return {
55
+ resolveSession,
56
+ from: (address) => ({
57
+ send: async (message, options) => (await source(address)).send(message, options),
58
+ respond: async (responses, options) => (await source(address)).respond(responses, options),
59
+ cancel: async (options) => (await source(address)).cancel(options),
60
+ compact: async () => (await source(address)).compact(),
61
+ clear: async () => (await source(address)).clear(),
62
+ reset: async (options) => (await source(address)).reset(options)
63
+ })
64
+ };
65
+ }
66
+ export { recoverableSessions };
@@ -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-MEMlG3EG.mjs";
7
+ import "../../../_chunks/principal-B6u41vIf.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-RIRNBxUC.mjs";
11
+ import { a as TelegramDeliveryError, l as customerMessage, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.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-MEMlG3EG.mjs";
8
+ import { d as telegramRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-B6u41vIf.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-MEMlG3EG.mjs";
8
+ import { i as memberIdOf } from "../../../_chunks/principal-B6u41vIf.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-RIRNBxUC.mjs";
10
+ import { c as customerCopy, d as failureText, o as currentLocale, p as reportTelegramError, s as currentThreadId } from "../../../_chunks/inbound-request-DxRm5LC8.mjs";
11
11
  import { recordSessionFailure } from "./conversations.mjs";
12
12
  function telegramFailureEvents(input) {
13
13
  return {
@@ -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-RIRNBxUC.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-DxRm5LC8.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-MEMlG3EG.mjs";
8
+ import { a as rolesOf } from "../_chunks/principal-B6u41vIf.mjs";
9
9
  import { defineDynamic } from "eve";
10
10
  function chooseModel(input) {
11
11
  const { choice } = input;
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { u as runtimeEnvelope } from "../../_chunks/principal-MEMlG3EG.mjs";
7
+ import { u as runtimeEnvelope } from "../../_chunks/principal-B6u41vIf.mjs";
8
8
  import { n as workflowToolResult } from "../../_chunks/workflow-serializable-DVQBWK8p.mjs";
9
9
  import segmentstream from "../extension.mjs";
10
10
  import { actionApproval } from "../lib/confirmations.mjs";
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { i as memberIdOf } from "../../_chunks/principal-MEMlG3EG.mjs";
7
+ import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.mjs";
8
8
  import segmentstream from "../extension.mjs";
9
9
  import { executeDeferredTool } from "../lib/deferred-confirmations.mjs";
10
10
  import { MAXIMUM_ARGUMENTS_FILE_BYTES, ontologyCallArguments } from "../lib/ontology-arguments.mjs";
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { i as memberIdOf } from "../../_chunks/principal-MEMlG3EG.mjs";
7
+ import { i as memberIdOf } from "../../_chunks/principal-B6u41vIf.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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@segmentstream/agent",
3
- "version": "0.17.3",
3
+ "version": "0.17.7",
4
4
  "description": "Mount a SegmentStream workspace's agent on eve: the ontology as tools, acting as the member who writes, and Telegram through the workspace's connection.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "SegmentStream",
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@chat-adapter/telegram": "4.41.0",
69
- "@segmentstream-cloud/ontology": "0.54.0",
69
+ "@segmentstream-cloud/ontology": "0.54.3",
70
70
  "@vercel/oidc": "^3.8.4",
71
71
  "ai": "^7.0.128",
72
72
  "csv-parse": "^7.0.3",