@segmentstream/agent 0.23.16 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +8 -8
  2. package/dist/_chunks/{build-metadata-D471R-eU.mjs → build-metadata-DDV7Rc51.mjs} +1 -1
  3. package/dist/_chunks/{inbound-request-gJ5wpsBF.mjs → inbound-request-xmrm-49O.mjs} +0 -1
  4. package/dist/_chunks/{principal-69qoDdqy.mjs → principal-DMNXj4PX.mjs} +1 -1
  5. package/dist/extension/hooks/authorization.mjs +1 -1
  6. package/dist/extension/instructions.md +4 -19
  7. package/dist/extension/lib/actor.mjs +1 -1
  8. package/dist/extension/lib/attachment-tools.mjs +1 -1
  9. package/dist/extension/lib/build-metadata.mjs +1 -1
  10. package/dist/extension/lib/confirmations.mjs +1 -1
  11. package/dist/extension/lib/conversation-runtime.mjs +1 -1
  12. package/dist/extension/lib/group-routing/observed.mjs +1 -1
  13. package/dist/extension/lib/group-routing/router.d.ts +8 -2
  14. package/dist/extension/lib/group-routing/router.mjs +4 -2
  15. package/dist/extension/lib/ontology-connection.mjs +1 -1
  16. package/dist/extension/lib/ontology-file-call.mjs +1 -1
  17. package/dist/extension/lib/ontology-tools.d.ts +1 -1
  18. package/dist/extension/lib/ontology-tools.mjs +1 -1
  19. package/dist/extension/lib/runtime-envelope.mjs +1 -1
  20. package/dist/extension/lib/stored-files.mjs +1 -1
  21. package/dist/extension/lib/telegram/adapter.mjs +11 -50
  22. package/dist/extension/lib/telegram/attachment-description.mjs +1 -1
  23. package/dist/extension/lib/telegram/attachments-send.mjs +2 -2
  24. package/dist/extension/lib/telegram/callbacks.mjs +2 -2
  25. package/dist/extension/lib/telegram/confirmations.d.ts +1 -2
  26. package/dist/extension/lib/telegram/confirmations.mjs +3 -11
  27. package/dist/extension/lib/telegram/conversations.mjs +2 -2
  28. package/dist/extension/lib/telegram/customer-text.mjs +1 -1
  29. package/dist/extension/lib/telegram/durable-typing.mjs +1 -1
  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/held-approvals.d.ts +5 -2
  33. package/dist/extension/lib/telegram/held-approvals.mjs +1 -2
  34. package/dist/extension/lib/telegram/images.mjs +1 -1
  35. package/dist/extension/lib/telegram/inbound-request.d.ts +0 -2
  36. package/dist/extension/lib/telegram/inbound-request.mjs +1 -1
  37. package/dist/extension/lib/telegram/inbound.d.ts +0 -2
  38. package/dist/extension/lib/telegram/inbound.mjs +10 -9
  39. package/dist/extension/lib/telegram/lifecycle.mjs +3 -3
  40. package/dist/extension/lib/telegram/media-policy.mjs +1 -1
  41. package/dist/extension/lib/telegram/principal.mjs +1 -1
  42. package/dist/extension/lib/telegram/session-recovery.mjs +1 -1
  43. package/dist/extension/lib/telegram/sessions.d.ts +8 -0
  44. package/dist/extension/lib/telegram/sessions.mjs +21 -1
  45. package/dist/extension/lib/telegram/silent.mjs +2 -2
  46. package/dist/extension/lib/telegram/structured.mjs +1 -1
  47. package/dist/extension/lib/telegram/turn-errors.mjs +2 -2
  48. package/dist/extension/lib/telegram/voice.mjs +1 -1
  49. package/dist/extension/model.mjs +1 -1
  50. package/dist/extension/tools/attachments_promote.mjs +1 -1
  51. package/dist/extension/tools/questions_ask.mjs +1 -1
  52. package/package.json +1 -1
  53. package/dist/extension/lib/confirmation-outcome.d.ts +0 -27
  54. package/dist/extension/lib/confirmation-outcome.mjs +0 -34
  55. package/dist/extension/lib/deferred-confirmations.d.ts +0 -41
  56. package/dist/extension/lib/deferred-confirmations.mjs +0 -77
  57. package/dist/extension/lib/telegram/confirmation-expiry.d.ts +0 -5
  58. package/dist/extension/lib/telegram/confirmation-expiry.mjs +0 -62
  59. package/dist/extension/lib/telegram/deferred-confirmations.d.ts +0 -26
  60. package/dist/extension/lib/telegram/deferred-confirmations.mjs +0 -295
  61. package/dist/extension/schedules/confirmations.d.ts +0 -6
  62. package/dist/extension/schedules/confirmations.mjs +0 -33
@@ -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-gJ5wpsBF.mjs";
7
+ import { i as withReplacedText, n as currentInboundRequest, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
8
8
  export { InboundRequest, currentInboundRequest, runInboundRequest, withReplacedText };
@@ -51,8 +51,6 @@ export interface InboundDependencies {
51
51
  readonly groups?: GroupPolicy;
52
52
  readonly recentConversation?: (chatId: string, threadId?: string) => Promise<ReadonlyArray<RecentMessage>>;
53
53
  readonly signalSettings?: TelegramSettings["groups"];
54
- /** Recover old held sessions only when the workspace has chosen non-blocking confirmations. */
55
- readonly recoverHeldApprovals?: boolean;
56
54
  readonly lifecycle?: (principal: import("eve/context").SessionAuthContext, memberId: string, message: TelegramMessage) => ReturnType<typeof attachmentLifecycle>;
57
55
  readonly admission: () => AdmissionSettings;
58
56
  readonly sessions: () => SessionSettings;
@@ -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-69qoDdqy.mjs";
10
- import { p as reportTelegramError } from "../../../_chunks/inbound-request-gJ5wpsBF.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";
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";
@@ -16,14 +16,14 @@ import { observedContext } from "../group-routing/observed.mjs";
16
16
  import { debounceBurst, routingBurst } from "../group-routing/burst.mjs";
17
17
  import { WorkspaceActionAlreadyDispatched } from "./workspace-action.mjs";
18
18
  import { structuredMessage } from "./structured.mjs";
19
- import { formatAddress, messageAddress, scopedAddress } from "./sessions.mjs";
19
+ import { evidenceSince, formatAddress, messageAddress, scopedAddress } from "./sessions.mjs";
20
20
  import { AttachmentLifecycleNotPermitted, startTypingHeartbeat, typingUntilComplete } from "./lifecycle.mjs";
21
- import { contentShape, messageContent } from "./content.mjs";
22
- import { messageAudience } from "./audience.mjs";
23
- import { attachmentKind, messageMetadata } from "./observed.mjs";
24
21
  import { MAXIMUM_NATIVE_IMAGE_BYTES } from "./images.mjs";
25
22
  import { MAXIMUM_ROUTING_ATTACHMENT_BYTES, describeRoutingAttachment, routingAttachmentDeadline } from "./attachment-description.mjs";
26
23
  import { attachmentUrl } from "../attachments.mjs";
24
+ import { contentShape, messageContent } from "./content.mjs";
25
+ import { messageAudience } from "./audience.mjs";
26
+ import { attachmentKind, messageMetadata } from "./observed.mjs";
27
27
  import { telegramSignals } from "./signals.mjs";
28
28
  import { answerMarker } from "../questions.mjs";
29
29
  import { questionAddress, questionFromHistory } from "./confirmations.mjs";
@@ -966,16 +966,17 @@ async function handleInboundMessage(input) {
966
966
  recordGateDecision("message_already_handled");
967
967
  return null;
968
968
  }
969
- if (dependencies.recoverHeldApprovals === true && operations !== void 0 && dependencies.history !== void 0) {
969
+ let receivingHistory;
970
+ if (operations !== void 0 && dependencies.history !== void 0) {
970
971
  let recoverySessionId;
971
972
  try {
972
973
  const session = await operations.resolveSession(address);
973
974
  if (session !== void 0) {
974
975
  recoverySessionId = session.id;
975
976
  const previous = session.id === owner?.id ? questionHistory : await dependencies.history(session.id);
977
+ receivingHistory = previous;
976
978
  const recovery = heldApprovals(previous).length === 0 ? void 0 : await releaseHeldApproval({
977
979
  events: await dependencies.history(session.id),
978
- addressed: addressed !== void 0,
979
980
  now: Date.now(),
980
981
  cancel: (options) => {
981
982
  if (session.cancel === void 0) throw new Error("The parked session does not support turn cancellation.");
@@ -1052,7 +1053,7 @@ async function handleInboundMessage(input) {
1052
1053
  }));
1053
1054
  }
1054
1055
  const language = conversationLanguage([text, ...dependencies.observed.recent(chat).map((message) => message.text).reverse()]);
1055
- const sharedContext = group ? conversationContext(await conversation()) : void 0;
1056
+ const sharedContext = group ? conversationContext(await conversation(), { since: receivingHistory === void 0 ? void 0 : evidenceSince(receivingHistory) }) : void 0;
1056
1057
  const beginTurnDispatch = structuredDispatched ? input.request?.beginStructuredContinuation : input.request?.beginDispatch;
1057
1058
  if (beginTurnDispatch !== void 0 && !await beginTurnDispatch()) {
1058
1059
  recordGateDecision("message_already_handled");
@@ -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-69qoDdqy.mjs";
7
+ import { d as telegramRuntimeSource, l as principalRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-DMNXj4PX.mjs";
8
8
  import { object } from "../confirmation-description.mjs";
9
- import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-gJ5wpsBF.mjs";
9
+ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.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-D471R-eU.mjs";
13
+ import { t as agentBuild } from "../../../_chunks/build-metadata-DDV7Rc51.mjs";
14
14
  var AttachmentLifecycleNotPermitted = class extends Error {
15
15
  code = "attachment_lifecycle_not_permitted";
16
16
  };
@@ -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-gJ5wpsBF.mjs";
8
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.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-69qoDdqy.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-DMNXj4PX.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-gJ5wpsBF.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.mjs";
8
8
  import { createHash } from "node:crypto";
9
9
  function missingDeployment(error) {
10
10
  if (!(error instanceof Error) || error.name !== "RunKeyFetchError" || !("status" in error) || error.status !== 404) return false;
@@ -57,6 +57,14 @@ export type HistoryReader = (sessionId: string) => Promise<ReadonlyArray<Recorde
57
57
  export declare const HISTORY_TAIL = 400;
58
58
  /** Folds a tail into a history; with no reset marker in it, `resetAt` is its earliest event. */
59
59
  export declare function historyOf(events: ReadonlyArray<RecordedEvent>): SessionHistory;
60
+ /**
61
+ * The earliest message time a group turn's conversation evidence still needs: each member
62
+ * message the session took in carried the chat's evidence up to then, and its history keeps it
63
+ * until a compaction or clear. Undefined when the session has none since its last reset, so the
64
+ * turn carries the whole window. Schedule sends and button answers carry no evidence and are
65
+ * skipped; a workspace callback turn is indistinguishable and may hide earlier unseen chatter.
66
+ */
67
+ export declare function evidenceSince(events: ReadonlyArray<RecordedEvent>): number | undefined;
60
68
  /** The route's operations on a continuation address, as eve gives them to the handler. */
61
69
  export interface SessionOperations {
62
70
  readonly resolveSession: (address: string) => Promise<{
@@ -108,6 +108,26 @@ function historyOf(events) {
108
108
  turnsSinceReset
109
109
  };
110
110
  }
111
+ const EVIDENCE_OVERLAP_MS = 6e4;
112
+ function evidenceSince(events) {
113
+ const members = new Set();
114
+ let since;
115
+ for (const event of events) {
116
+ const data = typeof event.data === "object" && event.data !== null ? event.data : {};
117
+ if (event.type === "session.started" || event.type === "context.settled" && data.outcome === "completed") {
118
+ members.clear();
119
+ since = void 0;
120
+ }
121
+ if (event.type === "delivery.admitted" && typeof data.deliveryId === "string") {
122
+ const principal = data.principal;
123
+ const source = data.source;
124
+ if (typeof principal?.id === "string" && principal.id.startsWith("telegram:") && source?.scheduleId === void 0) members.add(data.deliveryId);
125
+ }
126
+ const at = Date.parse(event.meta.at);
127
+ if (event.type === "delivery.consumed" && members.has(String(data.deliveryId)) && Array.isArray(data.parts) && data.parts.length > 0 && !Number.isNaN(at)) since = at - EVIDENCE_OVERLAP_MS;
128
+ }
129
+ return since;
130
+ }
111
131
  const MAXIMUM_REMEMBERED = 500;
112
132
  function sessionPolicy(input) {
113
133
  const remembered = new Map();
@@ -200,4 +220,4 @@ function sessionPolicy(input) {
200
220
  }
201
221
  };
202
222
  }
203
- export { HISTORY_TAIL, compactBoundary, formatAddress, historyOf, messageAddress, parseAddress, scopedAddress, sessionPolicy };
223
+ export { HISTORY_TAIL, compactBoundary, evidenceSince, formatAddress, historyOf, messageAddress, parseAddress, scopedAddress, sessionPolicy };
@@ -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-69qoDdqy.mjs";
7
+ import "../../../_chunks/principal-DMNXj4PX.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-gJ5wpsBF.mjs";
11
+ import { a as TelegramDeliveryError, l as customerMessage, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.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-69qoDdqy.mjs";
8
+ import { d as telegramRuntimeSource, u as runtimeEnvelope } from "../../../_chunks/principal-DMNXj4PX.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-69qoDdqy.mjs";
8
+ import { i as memberIdOf } from "../../../_chunks/principal-DMNXj4PX.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-gJ5wpsBF.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";
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-gJ5wpsBF.mjs";
7
+ import { p as reportTelegramError } from "../../../_chunks/inbound-request-xmrm-49O.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-69qoDdqy.mjs";
8
+ import { a as rolesOf } from "../_chunks/principal-DMNXj4PX.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-69qoDdqy.mjs";
7
+ import { u as runtimeEnvelope } from "../../_chunks/principal-DMNXj4PX.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-69qoDdqy.mjs";
8
+ import { i as memberIdOf } from "../../_chunks/principal-DMNXj4PX.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.23.16",
3
+ "version": "0.24.0",
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",
@@ -1,27 +0,0 @@
1
- import type { DeferredConfirmation } from "./deferred-confirmations.js";
2
- /** Model-only correlation plus bounded display context; never forward business input or results. */
3
- export declare function confirmationOutcome(record: DeferredConfirmation, status: Exclude<DeferredConfirmation["status"], "pending">, detail?: {
4
- readonly execution?: "not_started" | "uncertain";
5
- readonly editRequested?: boolean;
6
- readonly error?: {
7
- readonly code: string;
8
- readonly message: string;
9
- };
10
- }): {
11
- execution?: "not_started" | "uncertain";
12
- editRequested?: boolean;
13
- error?: {
14
- readonly code: string;
15
- readonly message: string;
16
- };
17
- context?: {
18
- targets?: {
19
- label: string;
20
- value: string;
21
- }[] | undefined;
22
- request?: string | undefined;
23
- } | undefined;
24
- confirmation: string;
25
- status: "failed" | "expired" | "done" | "cancelled" | "approved";
26
- summary: string;
27
- };
@@ -1,34 +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 { humanText } from "./confirmation-description.mjs";
8
- import { confirmationCopy } from "./telegram/confirmation-text.mjs";
9
- function confirmationOutcome(record, status, detail = {}) {
10
- const description = record.data.confirmation.description;
11
- const request = confirmationCopy(record.data.confirmation.copy)?.question;
12
- const targets = [...description?.targets ?? [], ...description?.chatPost ? [{
13
- label: "→",
14
- value: description.chatPost.title
15
- }] : []].flatMap((target) => {
16
- const label = humanText(target.label);
17
- const value = humanText(target.value, 3584);
18
- return label === void 0 || value === void 0 ? [] : [{
19
- label,
20
- value
21
- }];
22
- });
23
- return {
24
- confirmation: record.id,
25
- status,
26
- summary: humanText(description?.action) ?? "❓",
27
- ...request === void 0 && targets.length === 0 ? {} : { context: {
28
- ...request === void 0 ? {} : { request },
29
- ...targets.length === 0 ? {} : { targets }
30
- } },
31
- ...detail
32
- };
33
- }
34
- export { confirmationOutcome };
@@ -1,41 +0,0 @@
1
- import type { RuntimeEnvelope } from "./runtime-envelope.js";
2
- import { type Confirmation } from "./confirmations.js";
3
- import { type Environment } from "./environment.js";
4
- import { type RuntimeToken } from "./runtime-token.js";
5
- import type { TelegramTexts } from "./telegram/texts.js";
6
- export interface DeferredConfirmation {
7
- readonly id: string;
8
- readonly key: string;
9
- readonly memberId: string;
10
- readonly inputHash: string;
11
- readonly expiresAt: number;
12
- readonly status: "pending" | "approved" | "cancelled" | "expired" | "done" | "failed";
13
- readonly data: {
14
- readonly runtimeSource?: RuntimeEnvelope["source"];
15
- readonly action: string;
16
- readonly input: Readonly<Record<string, unknown>>;
17
- readonly confirmation: Confirmation;
18
- readonly sessionId: string;
19
- readonly callId: string;
20
- readonly chatId: string;
21
- readonly threadId: string;
22
- readonly requester: string;
23
- readonly locale?: string;
24
- readonly requesterName?: string;
25
- readonly messageId?: string;
26
- readonly address?: string;
27
- };
28
- }
29
- export type DeferredOptions = {
30
- readonly texts?: () => TelegramTexts;
31
- readonly environment?: Environment;
32
- readonly token?: RuntimeToken;
33
- readonly fetch?: typeof fetch;
34
- };
35
- export declare const deferredKey: (id: string) => string;
36
- /** Private deployment-authenticated ledger; the model never gets this transport. */
37
- export declare function deferredConfirmations(options?: DeferredOptions): {
38
- command<T>(command: unknown): Promise<T>;
39
- };
40
- /** Re-authorize before prepare; the ontology also authenticates the member on tools/call. */
41
- export declare function runDeferredAction(record: DeferredConfirmation, options: DeferredOptions): Promise<Record<string, unknown>>;
@@ -1,77 +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 { redactDiagnostic } from "./diagnostics.mjs";
8
- import { appOrigin } from "./environment.mjs";
9
- import { runtimeToken } from "./runtime-token.mjs";
10
- import { member } from "./actor.mjs";
11
- import { chatPostDigest, isChatPost } from "./chat-post-confirmation.mjs";
12
- import { inputHash } from "./confirmations.mjs";
13
- import { ontologyTools } from "./ontology-tools.mjs";
14
- import { createHash } from "node:crypto";
15
- const deferredKey = (id) => createHash("sha256").update(id).digest("hex").slice(0, 20);
16
- function deferredConfirmations(options = {}) {
17
- return { async command(command) {
18
- const credential = await (options.token ?? runtimeToken)();
19
- try {
20
- const response = await (options.fetch ?? fetch)(`${appOrigin(options.environment ?? process.env)}/api/ontology/agent/confirmations`, {
21
- method: "POST",
22
- redirect: "error",
23
- signal: AbortSignal.timeout(15e3),
24
- headers: {
25
- authorization: `Bearer ${credential}`,
26
- "content-type": "application/json"
27
- },
28
- body: JSON.stringify(command)
29
- });
30
- if (!response.ok) throw new Error(`Confirmation ledger unavailable (HTTP ${response.status}).`, { cause: await response.text() });
31
- return (await response.json()).result;
32
- } catch (error) {
33
- throw new Error("Confirmation ledger request failed.", { cause: redactDiagnostic(error, new Set([credential])) });
34
- }
35
- } };
36
- }
37
- async function runDeferredAction(record, options) {
38
- if (record.inputHash !== inputHash(record.data.input)) throw new Error("The confirmed input changed.");
39
- const tools = ontologyTools(options);
40
- await tools.labels(member(record.memberId), record.data.action, record.data.input);
41
- const preview = record.data.confirmation.description?.chatPost;
42
- if (isChatPost(record.data.action)) {
43
- const input = Object.fromEntries(Object.entries(record.data.input).filter(([key]) => key !== "_confirmation"));
44
- const current = (await tools.describe(member(record.memberId), record.data.action, input)).chatPost;
45
- if (!preview || !current || chatPostDigest(preview) !== chatPostDigest(current)) throw new Error("The confirmed chat destination or attribution changed.");
46
- }
47
- const envelope = {
48
- version: 1,
49
- session_id: record.data.sessionId,
50
- call_id: record.data.callId,
51
- operation_id: record.id,
52
- ...record.data.runtimeSource === void 0 ? {} : { source: record.data.runtimeSource },
53
- ...preview ? {
54
- source: {
55
- provider: "telegram",
56
- chat_id: record.data.chatId,
57
- thread_id: record.data.threadId,
58
- ...record.data.runtimeSource
59
- },
60
- expected: {
61
- chat_id: preview.chatId,
62
- digest: chatPostDigest(preview)
63
- }
64
- } : {}
65
- };
66
- const result = await ontologyTools({
67
- ...options,
68
- envelope
69
- }).rpc(member(record.memberId), "tools/call", {
70
- name: record.data.action.split("__").at(-1),
71
- arguments: record.data.input
72
- });
73
- const output = result.structuredContent;
74
- if (result.isError === true || (output?.validation)?.ok === false || preview !== void 0 && output?.status !== "sent") throw new Error("The confirmed action did not complete; its outcome may be uncertain.", { cause: result });
75
- return result;
76
- }
77
- export { deferredConfirmations, deferredKey, runDeferredAction };
@@ -1,5 +0,0 @@
1
- import type { TelegramSettings } from "../../config.js";
2
- import { type DeferredConfirmation, type DeferredOptions } from "../deferred-confirmations.js";
3
- import { type TelegramTexts } from "./texts.js";
4
- /** A bounded sweep; concurrent webhooks/schedules compete for the same atomic expiry claim. */
5
- export declare function expireScheduledConfirmations(connection: string, notify: (record: DeferredConfirmation, result: Readonly<Record<string, unknown>>) => Promise<unknown>, options?: DeferredOptions, settings?: TelegramSettings, texts?: TelegramTexts): Promise<void>;
@@ -1,62 +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 { proxyEnvironment } from "../environment.mjs";
8
- import { runtimeToken } from "../runtime-token.mjs";
9
- import { withTelegramTexts } from "./texts.mjs";
10
- import { telegramSendScope } from "./send-queue.mjs";
11
- import { conversations } from "../conversations.mjs";
12
- import { m as safeTelegramFetch, p as reportTelegramError } from "../../../_chunks/inbound-request-gJ5wpsBF.mjs";
13
- import { connectionProxy } from "../connection-proxy.mjs";
14
- import { deferredConfirmations } from "../deferred-confirmations.mjs";
15
- import { expireDeferredRecord } from "./deferred-confirmations.mjs";
16
- import { TELEGRAM_PLACEHOLDER_TOKEN, TELEGRAM_PROXY_ORIGIN, telegramProxyFetch } from "./proxy-fetch.mjs";
17
- import { telegramPreviewEnvironment } from "@segmentstream-cloud/ontology/telegram";
18
- async function expireScheduledConfirmations(connection, notify, options = {}, settings, texts = {}) {
19
- const environment = options.environment ?? process.env;
20
- const token = options.token ?? runtimeToken;
21
- const archive = conversations({
22
- environment,
23
- token,
24
- fetch: options.fetch
25
- });
26
- const scope = telegramSendScope(environment, connection);
27
- const proxy = connectionProxy({
28
- environment: proxyEnvironment(environment),
29
- connection,
30
- token,
31
- fetch: options.fetch
32
- });
33
- const transport = safeTelegramFetch(telegramProxyFetch(proxy, scope), scope, {
34
- settings,
35
- ownOrigins: telegramPreviewEnvironment(environment).appOrigins
36
- });
37
- const records = await deferredConfirmations(options).command({ operation: "expired" });
38
- for (const record of records) try {
39
- await withTelegramTexts(texts, () => expireDeferredRecord(record, { telegram: { editMessageText: async (input) => {
40
- const response = await transport(`${TELEGRAM_PROXY_ORIGIN}/bot${TELEGRAM_PLACEHOLDER_TOKEN}/editMessageText`, {
41
- method: "POST",
42
- headers: { "content-type": "application/json" },
43
- body: JSON.stringify({
44
- chat_id: record.data.chatId,
45
- message_id: input.messageId,
46
- text: input.text,
47
- reply_markup: input.replyMarkup
48
- })
49
- });
50
- const result = await response.json();
51
- if (!response.ok || result.ok !== true) throw new Error(`Telegram confirmation expiry failed: ${result.description ?? response.status}`);
52
- return {
53
- ok: true,
54
- status: response.status,
55
- body: result
56
- };
57
- } } }, options, archive, notify), () => record.data.locale ?? "en");
58
- } catch (error) {
59
- reportTelegramError("deferred_expiry_failed", error);
60
- }
61
- }
62
- export { expireScheduledConfirmations };
@@ -1,26 +0,0 @@
1
- import type { TelegramCallbackQuery, TelegramContext, TelegramHandle, TelegramEventContext } from "eve/channels/telegram";
2
- import type { SessionContext } from "eve/context";
3
- import { type DeferredConfirmation, type DeferredOptions } from "../deferred-confirmations.js";
4
- import { type Conversations } from "../conversations.js";
5
- import type { AgentIdentities } from "../identities.js";
6
- import { type ObservedMessages } from "./observed.js";
7
- export declare const isDeferredCallback: (data?: string) => boolean;
8
- export declare const deferredCallback: (record: DeferredConfirmation, choice: "y" | "n" | "e") => string;
9
- export declare function archiveDeferred(record: DeferredConfirmation, phase: string, archive: Conversations, errorText?: string): Promise<void>;
10
- /** Called at the durable tool-result boundary. Pending cards never become eve input requests. */
11
- export declare function postDeferredCard(id: string, channel: TelegramEventContext, ctx: SessionContext, options: DeferredOptions, archive: Conversations, observed?: ObservedMessages): Promise<void>;
12
- /** Every callback re-resolves the live identity. The database arbitrates concurrent presses. */
13
- export declare function handleDeferredCallback(input: {
14
- readonly context: TelegramContext;
15
- readonly query: TelegramCallbackQuery;
16
- readonly identities: AgentIdentities;
17
- readonly archive: Conversations;
18
- readonly options: DeferredOptions;
19
- readonly observed?: ObservedMessages;
20
- }): Promise<void>;
21
- /** A database-clock expiry claim is shared by webhooks and the minute schedule. */
22
- export declare function expireDeferredRecord(record: DeferredConfirmation, context: {
23
- readonly telegram: Pick<TelegramHandle, "editMessageText">;
24
- }, options: DeferredOptions, archive: Conversations, notify: NonNullable<import("./inbound-request.js").InboundRequest["confirmationEvent"]>, observed?: ObservedMessages): Promise<void>;
25
- /** Webhooks also reconcile expiry if the host's minute scheduler is delayed. */
26
- export declare function expireDeferredCards(context: TelegramContext, options: DeferredOptions, archive: Conversations, observed?: ObservedMessages): Promise<void>;