@segmentstream/agent 0.23.16 → 0.24.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.
- package/README.md +11 -10
- package/dist/_chunks/{build-metadata-D471R-eU.mjs → build-metadata-C5051bJL.mjs} +1 -1
- package/dist/_chunks/{inbound-request-gJ5wpsBF.mjs → inbound-request-xmrm-49O.mjs} +0 -1
- package/dist/_chunks/{principal-69qoDdqy.mjs → principal-DMNXj4PX.mjs} +1 -1
- package/dist/extension/hooks/authorization.mjs +1 -1
- package/dist/extension/instructions.md +4 -19
- package/dist/extension/lib/actor.mjs +1 -1
- package/dist/extension/lib/attachment-tools.mjs +1 -1
- package/dist/extension/lib/build-metadata.mjs +1 -1
- package/dist/extension/lib/confirmation-description.d.ts +5 -0
- package/dist/extension/lib/confirmation-description.mjs +11 -3
- package/dist/extension/lib/confirmations.d.ts +1 -1
- package/dist/extension/lib/confirmations.mjs +3 -1
- package/dist/extension/lib/conversation-runtime.mjs +15 -2
- package/dist/extension/lib/group-routing/observed.mjs +1 -1
- package/dist/extension/lib/group-routing/router.d.ts +8 -2
- package/dist/extension/lib/group-routing/router.mjs +4 -2
- package/dist/extension/lib/ontology-connection.mjs +1 -1
- package/dist/extension/lib/ontology-file-call.mjs +1 -1
- package/dist/extension/lib/ontology-tools.d.ts +1 -1
- package/dist/extension/lib/ontology-tools.mjs +1 -1
- package/dist/extension/lib/runtime-envelope.mjs +1 -1
- package/dist/extension/lib/stored-files.d.ts +23 -8
- package/dist/extension/lib/stored-files.mjs +54 -43
- package/dist/extension/lib/telegram/adapter.mjs +11 -50
- package/dist/extension/lib/telegram/attachment-description.mjs +1 -1
- package/dist/extension/lib/telegram/attachments-send.mjs +2 -2
- package/dist/extension/lib/telegram/callbacks.mjs +2 -2
- package/dist/extension/lib/telegram/confirmations.d.ts +1 -2
- package/dist/extension/lib/telegram/confirmations.mjs +3 -11
- package/dist/extension/lib/telegram/conversations.mjs +2 -2
- package/dist/extension/lib/telegram/customer-text.mjs +1 -1
- package/dist/extension/lib/telegram/durable-typing.mjs +1 -1
- package/dist/extension/lib/telegram/files.mjs +2 -2
- package/dist/extension/lib/telegram/health.mjs +1 -1
- package/dist/extension/lib/telegram/held-approvals.d.ts +5 -2
- package/dist/extension/lib/telegram/held-approvals.mjs +1 -2
- package/dist/extension/lib/telegram/images.mjs +1 -1
- package/dist/extension/lib/telegram/inbound-request.d.ts +0 -2
- package/dist/extension/lib/telegram/inbound-request.mjs +1 -1
- package/dist/extension/lib/telegram/inbound.d.ts +0 -2
- package/dist/extension/lib/telegram/inbound.mjs +10 -9
- package/dist/extension/lib/telegram/lifecycle.mjs +3 -3
- package/dist/extension/lib/telegram/media-policy.mjs +1 -1
- package/dist/extension/lib/telegram/principal.mjs +1 -1
- package/dist/extension/lib/telegram/session-recovery.mjs +1 -1
- package/dist/extension/lib/telegram/sessions.d.ts +8 -0
- package/dist/extension/lib/telegram/sessions.mjs +21 -1
- package/dist/extension/lib/telegram/silent.mjs +2 -2
- package/dist/extension/lib/telegram/structured.mjs +1 -1
- package/dist/extension/lib/telegram/turn-errors.mjs +2 -2
- package/dist/extension/lib/telegram/voice.mjs +1 -1
- package/dist/extension/model.mjs +1 -1
- package/dist/extension/tools/attachments_promote.mjs +1 -1
- package/dist/extension/tools/attachments_stage.d.ts +2 -1
- package/dist/extension/tools/attachments_stage.mjs +53 -20
- package/dist/extension/tools/questions_ask.mjs +1 -1
- package/package.json +1 -1
- package/dist/extension/lib/confirmation-outcome.d.ts +0 -27
- package/dist/extension/lib/confirmation-outcome.mjs +0 -34
- package/dist/extension/lib/deferred-confirmations.d.ts +0 -41
- package/dist/extension/lib/deferred-confirmations.mjs +0 -77
- package/dist/extension/lib/telegram/confirmation-expiry.d.ts +0 -5
- package/dist/extension/lib/telegram/confirmation-expiry.mjs +0 -62
- package/dist/extension/lib/telegram/deferred-confirmations.d.ts +0 -26
- package/dist/extension/lib/telegram/deferred-confirmations.mjs +0 -295
- package/dist/extension/schedules/confirmations.d.ts +0 -6
- package/dist/extension/schedules/confirmations.mjs +0 -33
|
@@ -9,7 +9,7 @@ import segmentstream from "../extension.mjs";
|
|
|
9
9
|
import { actorOf } from "../lib/actor.mjs";
|
|
10
10
|
import { sessionSandbox } from "../lib/sandbox-session.mjs";
|
|
11
11
|
import { attachmentOwner, optionalString, stringArgument, toolAttachments } from "../lib/attachment-tools.mjs";
|
|
12
|
-
import {
|
|
12
|
+
import { storedFileGrant } from "../lib/stored-files.mjs";
|
|
13
13
|
import { createHash } from "node:crypto";
|
|
14
14
|
import { posix } from "node:path";
|
|
15
15
|
import { defineDynamic, defineTool } from "eve/tools";
|
|
@@ -21,6 +21,15 @@ function stagedFileName(filename) {
|
|
|
21
21
|
const stem = (dot > 0 ? base.slice(0, dot) : base).normalize("NFKD").replace(/[^\w.-]+/g, "_").replace(/^[._-]+|[._-]+$/g, "").slice(0, 120);
|
|
22
22
|
return `${stem === "" ? "file" : stem}${extension}`;
|
|
23
23
|
}
|
|
24
|
+
async function holds(sandbox, path, sha256) {
|
|
25
|
+
try {
|
|
26
|
+
const hashed = await sandbox.run({ command: `sha256sum -- '${path.replaceAll("'", `'\\''`)}' 2>/dev/null` });
|
|
27
|
+
return hashed.exitCode === 0 && hashed.stdout.slice(0, 64) === sha256;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.warn("A staged file could not be checked; staging it again.", error);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
24
33
|
function stagedFilePath(sha256, filename) {
|
|
25
34
|
return `${STAGED_FILES_DIRECTORY}/${sha256.slice(0, 16)}/${stagedFileName(filename)}`;
|
|
26
35
|
}
|
|
@@ -51,27 +60,51 @@ const tool = defineTool({
|
|
|
51
60
|
const entity = optionalString(input, "entity");
|
|
52
61
|
const property = optionalString(input, "property");
|
|
53
62
|
if (entity === void 0 && property !== void 0) throw new TypeError("property requires entity.");
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
const sandboxOf = () => sessionSandbox(ctx);
|
|
64
|
+
let staged;
|
|
65
|
+
if (entity === void 0) {
|
|
66
|
+
const { attachment, bytes } = await toolAttachments().read(attachmentOwner({
|
|
67
|
+
principal: ctx.session.auth.current,
|
|
68
|
+
sessionId: ctx.session.id
|
|
69
|
+
}), id);
|
|
70
|
+
const sha256 = createHash("sha256").update(bytes).digest("hex");
|
|
71
|
+
if (sha256 !== attachment.sha256) throw new Error("The file's bytes differ from its recorded SHA-256; nothing was staged.");
|
|
72
|
+
const path = stagedFilePath(sha256, attachment.filename);
|
|
73
|
+
await (await sandboxOf()).writeBinaryFile({
|
|
74
|
+
path,
|
|
75
|
+
content: bytes
|
|
76
|
+
});
|
|
77
|
+
staged = {
|
|
78
|
+
path,
|
|
79
|
+
file: {
|
|
80
|
+
...attachment,
|
|
81
|
+
size: bytes.byteLength
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
} else {
|
|
85
|
+
const grant = await storedFileGrant({
|
|
86
|
+
entity,
|
|
87
|
+
id,
|
|
88
|
+
...property === void 0 ? {} : { property }
|
|
89
|
+
}, ctx.session.auth.current);
|
|
90
|
+
const path = stagedFilePath(grant.file.sha256, grant.file.filename);
|
|
91
|
+
const sandbox = await sandboxOf();
|
|
92
|
+
if (!await holds(sandbox, path, grant.file.sha256)) await sandbox.writeBinaryFile({
|
|
93
|
+
path,
|
|
94
|
+
content: await grant.read()
|
|
95
|
+
});
|
|
96
|
+
staged = {
|
|
97
|
+
path,
|
|
98
|
+
file: grant.file
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const { path, file } = staged;
|
|
69
102
|
return workflowToolResult({
|
|
70
103
|
path,
|
|
71
|
-
filename:
|
|
72
|
-
content_type:
|
|
73
|
-
size:
|
|
74
|
-
sha256,
|
|
104
|
+
filename: file.filename,
|
|
105
|
+
content_type: file.contentType,
|
|
106
|
+
size: file.size,
|
|
107
|
+
sha256: file.sha256,
|
|
75
108
|
...entity === void 0 ? { attachment_id: id } : {
|
|
76
109
|
entity,
|
|
77
110
|
record_id: id,
|
|
@@ -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-
|
|
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.
|
|
3
|
+
"version": "0.24.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",
|
|
@@ -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>;
|