@segmentstream/agent 0.18.3 → 0.19.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 +4 -4
- package/dist/_chunks/{build-metadata-DZ9Nb8Q2.mjs → build-metadata-CZ245Pl3.mjs} +1 -1
- package/dist/_chunks/{inbound-request-8xhK7EaW.mjs → inbound-request-Dx1B6Y5r.mjs} +1 -1
- package/dist/_chunks/{principal-qyR3jKAr.mjs → principal-BnJuWJtk.mjs} +1 -1
- package/dist/extension/_manifest.json +3 -15
- package/dist/extension/connections/ontology.d.ts +1 -1
- package/dist/extension/connections/ontology.mjs +2 -2
- package/dist/extension/hooks/authorization.d.ts +1 -1
- package/dist/extension/hooks/authorization.mjs +3 -3
- package/dist/extension/hooks/ontology-files.d.ts +1 -1
- package/dist/extension/hooks/ontology-files.mjs +3 -1
- package/dist/extension/hooks/sandbox.d.ts +2 -2
- package/dist/extension/hooks/sandbox.mjs +2 -2
- package/dist/extension/instructions/conversations.d.ts +1 -1
- package/dist/extension/instructions/conversations.mjs +3 -3
- package/dist/extension/instructions/sandbox.d.ts +1 -1
- package/dist/extension/instructions/sandbox.mjs +2 -2
- package/dist/extension/instructions.md +13 -12
- package/dist/extension/lib/attachment-tools.mjs +1 -1
- package/dist/extension/lib/build-metadata.mjs +1 -1
- package/dist/extension/lib/confirmations.mjs +3 -3
- package/dist/extension/lib/conversation-runtime.d.ts +2 -2
- package/dist/extension/lib/conversation-runtime.mjs +40 -55
- package/dist/extension/lib/conversations.mjs +1 -1
- package/dist/extension/lib/group-routing/conversation-router.d.ts +1 -1
- package/dist/extension/lib/group-routing/conversation-router.mjs +2 -2
- package/dist/extension/lib/group-routing/dequeue.mjs +2 -2
- package/dist/extension/lib/group-routing/record.mjs +1 -1
- package/dist/extension/lib/group-routing/replay.mjs +1 -1
- package/dist/extension/lib/group-routing/router.d.ts +1 -1
- package/dist/extension/lib/group-routing/router.mjs +3 -3
- package/dist/extension/lib/ontology-connection.mjs +2 -2
- package/dist/extension/lib/ontology-file-call.mjs +2 -2
- package/dist/extension/lib/ontology-tools.mjs +1 -1
- package/dist/extension/lib/runtime-envelope.mjs +1 -1
- package/dist/extension/lib/sandbox.d.ts +3 -2
- package/dist/extension/lib/sandbox.mjs +1 -1
- package/dist/extension/lib/stored-files.mjs +1 -1
- package/dist/extension/lib/telegram/adapter.mjs +43 -28
- package/dist/extension/lib/telegram/archive-message.d.ts +4 -0
- package/dist/extension/lib/telegram/archive-message.mjs +85 -0
- 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/confirmation-expiry.mjs +20 -9
- package/dist/extension/lib/telegram/confirmations.d.ts +2 -2
- package/dist/extension/lib/telegram/confirmations.mjs +206 -181
- package/dist/extension/lib/telegram/conversations.mjs +5 -6
- package/dist/extension/lib/telegram/customer-text.mjs +1 -1
- package/dist/extension/lib/telegram/deferred-confirmations.mjs +2 -2
- package/dist/extension/lib/telegram/delivery-diagnostics.mjs +1 -1
- package/dist/extension/lib/telegram/durable-typing.d.ts +11 -0
- package/dist/extension/lib/telegram/durable-typing.mjs +10 -10
- 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 +3 -3
- package/dist/extension/lib/telegram/held-approvals.mjs +23 -19
- package/dist/extension/lib/telegram/images.d.ts +1 -1
- package/dist/extension/lib/telegram/images.mjs +1 -1
- package/dist/extension/lib/telegram/inbound-request.d.ts +2 -2
- package/dist/extension/lib/telegram/inbound-request.mjs +1 -1
- package/dist/extension/lib/telegram/inbound.mjs +5 -6
- package/dist/extension/lib/telegram/lifecycle.d.ts +2 -2
- package/dist/extension/lib/telegram/lifecycle.mjs +23 -27
- package/dist/extension/lib/telegram/media-policy.mjs +1 -1
- package/dist/extension/lib/telegram/principal.mjs +1 -1
- package/dist/extension/lib/telegram/routing-context.mjs +4 -4
- package/dist/extension/lib/telegram/session-recovery.d.ts +1 -1
- package/dist/extension/lib/telegram/session-recovery.mjs +2 -1
- package/dist/extension/lib/telegram/sessions.d.ts +7 -4
- package/dist/extension/lib/telegram/sessions.mjs +6 -3
- package/dist/extension/lib/telegram/silent.d.ts +1 -1
- package/dist/extension/lib/telegram/silent.mjs +11 -8
- package/dist/extension/lib/telegram/structured.mjs +1 -1
- package/dist/extension/lib/telegram/turn-errors.d.ts +1 -1
- package/dist/extension/lib/telegram/turn-errors.mjs +47 -31
- package/dist/extension/lib/telegram/voice.mjs +1 -1
- package/dist/extension/lib/workflow-serializable.mjs +1 -1
- package/dist/extension/model.mjs +7 -4
- package/dist/extension/tools/attachments_discard.mjs +1 -1
- package/dist/extension/tools/attachments_list.mjs +1 -1
- package/dist/extension/tools/attachments_promote.mjs +2 -2
- package/dist/extension/tools/attachments_read.mjs +1 -1
- package/dist/extension/tools/attachments_send.mjs +1 -1
- package/dist/extension/tools/attachments_table.mjs +1 -1
- package/dist/extension/tools/ontology_call_file.d.ts +1 -1
- package/dist/extension/tools/ontology_call_file.mjs +1 -1
- package/dist/extension/tools/questions_ask.mjs +2 -2
- package/dist/extension/tools/sandbox.d.ts +1 -8
- package/dist/extension/tools/sandbox.mjs +1 -1
- package/package.json +5 -5
- /package/dist/_chunks/{content-TRaZitQZ.mjs → content-cDtVnr8Y.mjs} +0 -0
- /package/dist/_chunks/{workflow-serializable-_g4JRau5.mjs → workflow-serializable-DU7WeCIW.mjs} +0 -0
package/README.md
CHANGED
|
@@ -7,13 +7,13 @@ calls go through the workspace's connection, unknown senders pair with a member
|
|
|
7
7
|
messages become text, and group chats are answered only when the agent is addressed or asked for
|
|
8
8
|
something it does.
|
|
9
9
|
|
|
10
|
-
The package is built against one eve version, `0.
|
|
10
|
+
The package is built against one eve version, `0.85.0`, and the workspace's `agent/` pins the same
|
|
11
11
|
one. eve and the package move together.
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
|
-
npm install @segmentstream/agent eve@0.
|
|
16
|
+
npm install @segmentstream/agent eve@0.85.0
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Set up
|
|
@@ -318,7 +318,7 @@ share a group chat's session never share a client.
|
|
|
318
318
|
context. `stt: false` skips transcription. Transcription accepts at most 20 MiB
|
|
319
319
|
and ten minutes of declared duration, with a 60-second inference timeout. A skipped or failed
|
|
320
320
|
transcription reaches the agent as a note. Originals are stored as ontology attachments.
|
|
321
|
-
Eve 0.
|
|
321
|
+
Eve 0.85.0 only hydrates inbound images and PDFs; it does **not** deliver native audio bytes to
|
|
322
322
|
the chat model. Even an audio-capable chat model therefore uses the configured STT fallback,
|
|
323
323
|
with an explicit host limitation note. Native audio requires a compatible Eve host change.
|
|
324
324
|
- **Attachments.** Photos, documents and other Telegram files up to 20 MB stream through the connection proxy (its
|
|
@@ -619,7 +619,7 @@ Eve resolution, so member/topic routing survives a cold start. No second provide
|
|
|
619
619
|
|
|
620
620
|
## Release and migration
|
|
621
621
|
|
|
622
|
-
The
|
|
622
|
+
The original exact-post release used Agent SDK 0.17.13, Eve 0.76.3, Ontology SDK 0.56.0 and App SDK 0.25.2. Current builds require Eve 0.85.0 and a rebuilt Agent SDK extension.
|
|
623
623
|
In the next release, feedback file guidance follows the visible tools.
|
|
624
624
|
The compatible Cloud archive/API must be deployed first; migrations run only through its CI/CD gate.
|
|
625
625
|
Publish the ontology SDK before the agent SDK. Upgrade the workspace ontology before its agent,
|
|
@@ -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.
|
|
7
|
+
var version = "0.19.1";
|
|
8
8
|
function agentBuild(environment = process.env) {
|
|
9
9
|
return {
|
|
10
10
|
agent: version,
|
|
@@ -371,7 +371,7 @@ function withReplacedText(source, request) {
|
|
|
371
371
|
chatId: request.chatId,
|
|
372
372
|
messageId: request.replyTo,
|
|
373
373
|
intakeId: request.lifecycleKey,
|
|
374
|
-
sessionId: result.
|
|
374
|
+
sessionId: result.sessionId
|
|
375
375
|
});
|
|
376
376
|
if (marker !== void 0) request.monitor?.(result, marker);
|
|
377
377
|
return result;
|
|
@@ -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-
|
|
7
|
+
import { n as currentInboundRequest } from "./inbound-request-Dx1B6Y5r.mjs";
|
|
8
8
|
import { randomUUID } from "node:crypto";
|
|
9
9
|
function telegramRuntimeSource(message, files, callbackQueryId) {
|
|
10
10
|
const attachments = [];
|
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"kind": "eve-extension",
|
|
3
|
-
"formatVersion":
|
|
4
|
-
"builtWithEve": "0.
|
|
5
|
-
"
|
|
6
|
-
"extension": 1,
|
|
7
|
-
"tool": 85,
|
|
8
|
-
"dynamicTool": 79,
|
|
9
|
-
"channel": 58,
|
|
10
|
-
"schedule": 31,
|
|
11
|
-
"connection": 46,
|
|
12
|
-
"hook": 44,
|
|
13
|
-
"instructions": 2,
|
|
14
|
-
"dynamicInstructions": 37,
|
|
15
|
-
"config": 1,
|
|
16
|
-
"state": 13
|
|
17
|
-
}
|
|
3
|
+
"formatVersion": 3,
|
|
4
|
+
"builtWithEve": "0.85.0",
|
|
5
|
+
"contractMajor": 0
|
|
18
6
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** Let Eve own tool discovery, schemas and calls, while retaining our member/approval boundary. */
|
|
2
|
-
declare const _default: import("eve").DynamicSentinel<import("eve/connections").DynamicConnectionResult>;
|
|
2
|
+
declare const _default: import("eve").DynamicSentinel<import("eve/connections").DynamicConnectionResult, import("eve").DynamicContext>;
|
|
3
3
|
export default _default;
|
|
@@ -7,7 +7,7 @@ __eveCreateRequire(import.meta.url);
|
|
|
7
7
|
import segmentstream from "../extension.mjs";
|
|
8
8
|
import { ontologyConnection } from "../lib/ontology-connection.mjs";
|
|
9
9
|
import { defineDynamic } from "eve/connections";
|
|
10
|
-
var ontology_default = defineDynamic(
|
|
10
|
+
var ontology_default = defineDynamic(async (context) => {
|
|
11
11
|
if (!segmentstream.config.ontology.connection) return null;
|
|
12
12
|
return ontologyConnection({
|
|
13
13
|
principal: context.session.auth.current,
|
|
@@ -15,5 +15,5 @@ var ontology_default = defineDynamic({ events: { "turn.started": async (_event,
|
|
|
15
15
|
chatPosting: true,
|
|
16
16
|
runtimeSource: true
|
|
17
17
|
});
|
|
18
|
-
}
|
|
18
|
+
});
|
|
19
19
|
export { ontology_default as default };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** Channel delivery reports the reference; the public hook owns cancellation of the running turn. */
|
|
2
|
-
declare const _default: import("eve/hooks").HookDefinition<"
|
|
2
|
+
declare const _default: import("eve/hooks").HookDefinition<"interaction.opened">;
|
|
3
3
|
export default _default;
|
|
@@ -5,12 +5,12 @@ 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-
|
|
8
|
+
import "../../_chunks/principal-BnJuWJtk.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";
|
|
12
|
-
var authorization_default = defineHook({ events: { "
|
|
12
|
+
var authorization_default = defineHook({ events: { "interaction.opened": (event, context) => {
|
|
13
13
|
const principal = context.session.auth.current;
|
|
14
|
-
if (principal?.authenticator === "segmentstream-telegram" && event.data.
|
|
14
|
+
if (principal?.authenticator === "segmentstream-telegram" && event.data.request.kind === "sign-in" && localizedText(segmentstream.config.texts?.authorization?.prompt, confirmationLocale(principal)) === void 0) context.cancel();
|
|
15
15
|
} } });
|
|
16
16
|
export { authorization_default as default };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("eve/hooks").HookDefinition<"context.
|
|
1
|
+
declare const _default: import("eve/hooks").HookDefinition<"context.settled">;
|
|
2
2
|
export default _default;
|
|
@@ -6,5 +6,7 @@ __eveDirname(__filename);
|
|
|
6
6
|
__eveCreateRequire(import.meta.url);
|
|
7
7
|
import { releaseOntologyFilePayloads } from "../lib/ontology-file-call.mjs";
|
|
8
8
|
import { defineHook } from "eve/hooks";
|
|
9
|
-
var ontology_files_default = defineHook({ events: { "context.
|
|
9
|
+
var ontology_files_default = defineHook({ events: { "context.settled": (event) => {
|
|
10
|
+
if (event.data.kind === "clear" && event.data.outcome === "completed") releaseOntologyFilePayloads();
|
|
11
|
+
} } });
|
|
10
12
|
export { ontology_files_default as default };
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* A cleared history, such as the idle reset of `sessions.idleResetHours`, starts the next
|
|
3
3
|
* conversation without the files of the last one: the sandbox is deleted through its handle, so
|
|
4
4
|
* the next access opens a fresh one. Compaction keeps the conversation and fires
|
|
5
|
-
* `
|
|
5
|
+
* `context.settled` with kind `compaction` mid-turn too, so it leaves the sandbox alone; eve's own session-end
|
|
6
6
|
* cleanup deletes whatever remains.
|
|
7
7
|
*/
|
|
8
|
-
declare const _default: import("eve/hooks").HookDefinition<"context.
|
|
8
|
+
declare const _default: import("eve/hooks").HookDefinition<"context.settled">;
|
|
9
9
|
export default _default;
|
|
@@ -6,7 +6,7 @@ __eveDirname(__filename);
|
|
|
6
6
|
__eveCreateRequire(import.meta.url);
|
|
7
7
|
import { releaseSandbox } from "../lib/sandbox-session.mjs";
|
|
8
8
|
import { defineHook } from "eve/hooks";
|
|
9
|
-
var sandbox_default = defineHook({ events: { "context.
|
|
10
|
-
await releaseSandbox(context);
|
|
9
|
+
var sandbox_default = defineHook({ events: { "context.settled": async (event, context) => {
|
|
10
|
+
if (event.data.kind === "clear" && event.data.outcome === "completed") await releaseSandbox(context);
|
|
11
11
|
} } });
|
|
12
12
|
export { sandbox_default as default };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** Refreshes durable chat context on every turn, including bot posts and cold starts. */
|
|
2
|
-
declare const _default: import("eve").DynamicSentinel<import("eve/instructions").DynamicInstructionsResult>;
|
|
2
|
+
declare const _default: import("eve").DynamicSentinel<import("eve/instructions").DynamicInstructionsResult, import("eve").DynamicContext>;
|
|
3
3
|
export default _default;
|
|
@@ -8,13 +8,13 @@ import { conversations, storedConversationContext } from "../lib/conversations.m
|
|
|
8
8
|
import { conversationCoordinates } from "../lib/conversation-runtime.mjs";
|
|
9
9
|
import { defineDynamic, defineInstructions } from "eve/instructions";
|
|
10
10
|
const archive = conversations();
|
|
11
|
-
var conversations_default = defineDynamic(
|
|
11
|
+
var conversations_default = defineDynamic(async (context) => {
|
|
12
12
|
const coordinates = conversationCoordinates(context);
|
|
13
13
|
if (coordinates === void 0) return null;
|
|
14
|
-
const content = await storedConversationContext(archive, coordinates);
|
|
14
|
+
const content = await context.memo([context.turn?.id ?? null, coordinates.participantIds], () => storedConversationContext(archive, coordinates));
|
|
15
15
|
return content === null ? null : defineInstructions({
|
|
16
16
|
role: "user",
|
|
17
17
|
content
|
|
18
18
|
});
|
|
19
|
-
}
|
|
19
|
+
});
|
|
20
20
|
export { conversations_default as default };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("eve").DynamicSentinel<import("eve/instructions").DynamicInstructionsResult>;
|
|
1
|
+
declare const _default: import("eve").DynamicSentinel<import("eve/instructions").DynamicInstructionsResult, import("eve").DynamicContext>;
|
|
2
2
|
export default _default;
|
|
@@ -31,8 +31,8 @@ Downloads and package installs fail. For reading one file or exact totals over o
|
|
|
31
31
|
- The sandbox is temporary. It is discarded when the chat's history resets and replaced after a
|
|
32
32
|
day; keep what matters through the ontology. To keep a file you produced, pass its path inside
|
|
33
33
|
/workspace to \`segmentstream__attachments_promote\` instead of an id.`;
|
|
34
|
-
var sandbox_default = defineDynamic(
|
|
34
|
+
var sandbox_default = defineDynamic(() => segmentstream.config.sandbox ? defineInstructions({
|
|
35
35
|
role: "system",
|
|
36
36
|
content: SANDBOX_INSTRUCTIONS
|
|
37
|
-
}) : null
|
|
37
|
+
}) : null);
|
|
38
38
|
export { sandbox_default as default };
|
|
@@ -18,18 +18,19 @@ Native confirmations pause this turn until the original requester approves or ca
|
|
|
18
18
|
The action has not run while approval is pending. Never claim success, repeat a pending action,
|
|
19
19
|
or treat a text acknowledgement as approval. Report completion only from the resumed tool result.
|
|
20
20
|
|
|
21
|
-
- When the ontology offers `app_feedback_submit`,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
21
|
+
- When the ontology offers `app_feedback_submit`, follow its published feedback reporting policy.
|
|
22
|
+
By default, offer once per problem and submit only after the member agrees to the title and
|
|
23
|
+
summary in their language. When the workspace explicitly preauthorizes technical failure reports,
|
|
24
|
+
record unexpected or persistent failures during requested work without another confirmation.
|
|
25
|
+
Include only the operation, safe technical reason and diagnostic references; never include business
|
|
26
|
+
contents, credentials or files in an automatic report. Feature/change requests and sharing contents
|
|
27
|
+
or files still require the member's agreement. First reuse the member's open `app_feedback` with
|
|
28
|
+
the same subject; claim reporting only after a successful submission or existing-item read.
|
|
29
|
+
If `app_feedback_file_attach` is available, attach only files the member agreed to share.
|
|
30
|
+
When a member starts talking to you, find their `app_feedback` with `responded_at` set and
|
|
31
|
+
`seen_at` empty, tell them the builders' response, then call `app_feedback_acknowledge` with
|
|
32
|
+
its `responded_at`. Older ontologies without `discover` return the legacy full catalog from
|
|
33
|
+
`describe`; use that available contract. New description results carry `kind` and `hash`.
|
|
33
34
|
- When the current member has permission and gives a clear instruction, act, including necessary
|
|
34
35
|
routine intermediate steps. Their authorization continues across turns. When they answer your
|
|
35
36
|
question, use the answer and continue the pending task without asking for permission again.
|
|
@@ -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-
|
|
8
|
+
import { i as memberIdOf } from "../../_chunks/principal-BnJuWJtk.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-
|
|
7
|
+
import { t as agentBuild } from "../../_chunks/build-metadata-CZ245Pl3.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-
|
|
8
|
+
import { i as memberIdOf } from "../../_chunks/principal-BnJuWJtk.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";
|
|
@@ -124,7 +124,7 @@ function actionApproval(options) {
|
|
|
124
124
|
reason
|
|
125
125
|
});
|
|
126
126
|
if (saved === void 0 || saved.status !== "pending") return reject("This confirmation is no longer pending.");
|
|
127
|
-
if (ctx.response.principal.attributes.confirmationRequestId !== ctx.request.
|
|
127
|
+
if (ctx.response.principal.attributes.confirmationRequestId !== ctx.request.interactionId || ctx.response.principal.attributes.confirmationDecision !== (ctx.response.decision === "deny" ? "cancel" : "approve")) return reject("Use the Confirm or Cancel button on the action's message.");
|
|
128
128
|
if (memberIdOf(ctx.response.principal) !== saved.memberId || memberIdOf(ctx.request.principal) !== saved.memberId) return reject("Only the requesting member can confirm or cancel this action.");
|
|
129
129
|
if (saved.action !== ctx.request.toolName || saved.inputHash !== inputHash(ctx.request.toolInput ?? {})) return reject("The action or input changed. Make a new call.");
|
|
130
130
|
if (ctx.response.decision === "approve" && saved.expiresAt <= now()) return reject("This confirmation expired.");
|
|
@@ -133,7 +133,7 @@ function actionApproval(options) {
|
|
|
133
133
|
[ctx.request.callId]: {
|
|
134
134
|
...saved,
|
|
135
135
|
status: ctx.response.decision === "approve" ? "approved" : "cancelled",
|
|
136
|
-
...ctx.response.decision === "
|
|
136
|
+
...ctx.response.decision === "deny" && ["edit", "expired"].includes(String(ctx.response.principal.attributes.confirmationReason)) ? { cancellationReason: ctx.response.principal.attributes.confirmationReason } : {}
|
|
137
137
|
}
|
|
138
138
|
}));
|
|
139
139
|
return { status: "allowed" };
|
|
@@ -16,8 +16,8 @@ export declare function conversationCoordinates(context: {
|
|
|
16
16
|
} | undefined;
|
|
17
17
|
/**
|
|
18
18
|
* eve event hooks run after its durable event write. IDs make platform writes replay-safe.
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* Eve v27 fails the turn if a hook throws. Archive failures propagate so missing audit
|
|
20
|
+
* evidence never silently permits the turn to continue.
|
|
21
21
|
*/
|
|
22
22
|
export declare function conversationRecorder(archive?: Conversations, closing?: (message: string, model: string) => Promise<number>): (event: HookEvent, context: HookContext) => Promise<void>;
|
|
23
23
|
export {};
|
|
@@ -5,12 +5,13 @@ 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-
|
|
9
|
-
import { n as contentText, t as CONTENT_CAPS } from "../../_chunks/content-
|
|
8
|
+
import { i as memberIdOf } from "../../_chunks/principal-BnJuWJtk.mjs";
|
|
9
|
+
import { n as contentText, t as CONTENT_CAPS } from "../../_chunks/content-cDtVnr8Y.mjs";
|
|
10
10
|
import { conversationEvent, conversations, sessionFailureEventId, summarizeArguments } from "./conversations.mjs";
|
|
11
11
|
import { parseAddress } from "./telegram/sessions.mjs";
|
|
12
12
|
import { completionKind } from "./telegram/silent.mjs";
|
|
13
13
|
import { decide } from "eve/ai";
|
|
14
|
+
import { call } from "eve/events";
|
|
14
15
|
function conversationCoordinates(context) {
|
|
15
16
|
const principal = context.session.auth.current;
|
|
16
17
|
const telegram = principal?.authenticator === "segmentstream-telegram" || context.channel.kind?.includes("telegram");
|
|
@@ -43,11 +44,11 @@ function reportUnaddressed(event, context, reported) {
|
|
|
43
44
|
hasContinuationToken: Boolean(context.channel.continuationToken),
|
|
44
45
|
authenticator: context.session.auth.current?.authenticator ?? null
|
|
45
46
|
};
|
|
46
|
-
if (event.type === "turn.
|
|
47
|
+
if ((event.type === "turn.settled" || event.type === "model.settled" || event.type === "session.ended") && event.data.outcome === "failed") {
|
|
47
48
|
console.error("[segmentstream] agent log dropped unaddressed failure", {
|
|
48
49
|
...fields,
|
|
49
|
-
code: event.data.code,
|
|
50
|
-
message: contentText(event.data.message, CONTENT_CAPS.error)
|
|
50
|
+
code: event.data.error?.code,
|
|
51
|
+
message: contentText(event.data.error?.message, CONTENT_CAPS.error)
|
|
51
52
|
});
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
@@ -64,7 +65,7 @@ function conversationRecorder(archive = conversations(), closing = async (messag
|
|
|
64
65
|
type: "boolean",
|
|
65
66
|
instructions: ENDS_CONVERSATION_INSTRUCTIONS
|
|
66
67
|
} },
|
|
67
|
-
|
|
68
|
+
signal: AbortSignal.timeout(5e3),
|
|
68
69
|
maxRetries: 0
|
|
69
70
|
})).answers.ends_conversation.probability;
|
|
70
71
|
}) {
|
|
@@ -78,60 +79,44 @@ function conversationRecorder(archive = conversations(), closing = async (messag
|
|
|
78
79
|
const base = {
|
|
79
80
|
...coordinates,
|
|
80
81
|
sessionId: context.session.id,
|
|
81
|
-
turnId: event.
|
|
82
|
-
at:
|
|
82
|
+
turnId: event.scope?.turnId ?? context.session.turn.id,
|
|
83
|
+
at: context.now.toISOString()
|
|
83
84
|
};
|
|
84
|
-
const eventId = `eve:${context.session.id}:${
|
|
85
|
-
if (event.type === "
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
else if (event.type === "action.result") {
|
|
99
|
-
const result = event.data.result;
|
|
100
|
-
const name = "toolName" in result ? result.toolName : "name" in result ? result.name : result.subagentName;
|
|
85
|
+
const eventId = `eve:${context.session.id}:${context.position.line}:${context.position.index}`;
|
|
86
|
+
if (event.type === "call.requested") await archive.append(conversationEvent({
|
|
87
|
+
...base,
|
|
88
|
+
eventId,
|
|
89
|
+
kind: "tool_call",
|
|
90
|
+
toolCallId: event.data.callId,
|
|
91
|
+
toolName: event.data.capability.name,
|
|
92
|
+
argsSummary: summarizeArguments(event.data.input),
|
|
93
|
+
argsText: contentText(event.data.input, CONTENT_CAPS.args),
|
|
94
|
+
status: "requested"
|
|
95
|
+
}));
|
|
96
|
+
else if (event.type === "call.settled") {
|
|
97
|
+
const requested = call(context.view, event.data.callId);
|
|
101
98
|
await archive.append(conversationEvent({
|
|
102
99
|
...base,
|
|
103
100
|
eventId,
|
|
104
101
|
kind: "tool_result",
|
|
105
|
-
toolCallId:
|
|
106
|
-
toolName: name,
|
|
107
|
-
status: event.data.
|
|
108
|
-
resultText: contentText("output" in result ? result.output : null, CONTENT_CAPS.result),
|
|
109
|
-
errorText: contentText(event.data.error?.message ?? (event.data.status === "failed" ? resultErrorMessage(result.output) : null), CONTENT_CAPS.error)
|
|
110
|
-
}));
|
|
111
|
-
} else if (event.type === "task.started" || event.type === "task.settled") await archive.append(conversationEvent({
|
|
112
|
-
...base,
|
|
113
|
-
eventId,
|
|
114
|
-
kind: event.type === "task.started" ? "tool_call" : "tool_result",
|
|
115
|
-
toolCallId: event.data.callId,
|
|
116
|
-
toolName: event.data.name ?? "task",
|
|
117
|
-
argsSummary: "{}",
|
|
118
|
-
...event.type === "task.settled" ? {
|
|
102
|
+
toolCallId: event.data.callId,
|
|
103
|
+
toolName: requested?.name ?? "unknown",
|
|
104
|
+
status: event.data.outcome === "interrupted" || event.data.outcome === "abandoned" ? "cancelled" : event.data.outcome,
|
|
119
105
|
resultText: contentText(event.data.output, CONTENT_CAPS.result),
|
|
120
|
-
errorText: contentText(event.data.error?.message, CONTENT_CAPS.error)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
}));
|
|
124
|
-
else if (event.type === "turn.failed" || event.type === "step.failed" || event.type === "session.failed") await archive.append(conversationEvent({
|
|
106
|
+
errorText: contentText(event.data.error?.message ?? (event.data.outcome === "failed" ? resultErrorMessage(event.data.output) : null), CONTENT_CAPS.error)
|
|
107
|
+
}));
|
|
108
|
+
} else if ((event.type === "turn.settled" || event.type === "model.settled" || event.type === "session.ended") && event.data.outcome === "failed") await archive.append(conversationEvent({
|
|
125
109
|
...base,
|
|
126
|
-
eventId: event.type === "session.
|
|
110
|
+
eventId: event.type === "session.ended" ? sessionFailureEventId(context.session.id) : eventId,
|
|
127
111
|
kind: "decision",
|
|
128
112
|
decision: "silent",
|
|
129
|
-
reason: event.type,
|
|
113
|
+
reason: event.type === "session.ended" ? "session.failed" : event.type,
|
|
130
114
|
status: "failed",
|
|
131
|
-
errorText: contentText(event.data.message, CONTENT_CAPS.error)
|
|
115
|
+
errorText: contentText(event.data.error?.message, CONTENT_CAPS.error)
|
|
132
116
|
}));
|
|
133
|
-
else if (event.type === "
|
|
134
|
-
const
|
|
117
|
+
else if (event.type === "content.completed" && event.data.kind === "text" && event.data.phase === "reply" && !event.data.interrupted) {
|
|
118
|
+
const message = typeof event.data.value === "string" ? event.data.value : "";
|
|
119
|
+
const kind = completionKind(message);
|
|
135
120
|
const silent = kind !== "reply";
|
|
136
121
|
let routingMessageId;
|
|
137
122
|
if (kind === "silent_marker" && typeof context.session.auth.current?.attributes.groupRouting === "string") try {
|
|
@@ -152,25 +137,25 @@ function conversationRecorder(archive = conversations(), closing = async (messag
|
|
|
152
137
|
argsSummary: JSON.stringify({
|
|
153
138
|
outputKind: kind,
|
|
154
139
|
...routingMessageId === void 0 ? {} : { routing: { conversationEnded: true } },
|
|
155
|
-
outputCharacters:
|
|
156
|
-
|
|
140
|
+
outputCharacters: message.length,
|
|
141
|
+
phase: event.data.phase
|
|
157
142
|
})
|
|
158
143
|
}));
|
|
159
144
|
if (coordinates.provider !== "telegram" && !silent) await archive.append(conversationEvent({
|
|
160
145
|
...base,
|
|
161
146
|
eventId: `${eventId}:outbound`,
|
|
162
147
|
kind: "outbound",
|
|
163
|
-
text:
|
|
148
|
+
text: message,
|
|
164
149
|
senderId: "agent",
|
|
165
150
|
senderIsBot: true,
|
|
166
151
|
status: "completed"
|
|
167
152
|
}));
|
|
168
|
-
} else if (event.type === "
|
|
153
|
+
} else if (event.type === "delivery.consumed" && coordinates.provider !== "telegram") await archive.append(conversationEvent({
|
|
169
154
|
...base,
|
|
170
155
|
eventId,
|
|
171
156
|
kind: "inbound",
|
|
172
|
-
text: event.data.
|
|
173
|
-
attachments: (event.data.parts ?? []).filter((part) => part.
|
|
157
|
+
text: event.data.parts.filter((part) => part.kind === "text").map((part) => part.text).join("\n"),
|
|
158
|
+
attachments: (event.data.parts ?? []).filter((part) => part.kind === "file").map((part, index) => ({
|
|
174
159
|
id: `${eventId}:file:${index}`,
|
|
175
160
|
kind: "file",
|
|
176
161
|
...part.filename ? { filename: part.filename } : {},
|
|
@@ -6,7 +6,7 @@ __eveDirname(__filename);
|
|
|
6
6
|
__eveCreateRequire(import.meta.url);
|
|
7
7
|
import { proxyEnvironment } from "./environment.mjs";
|
|
8
8
|
import { runtimeToken } from "./runtime-token.mjs";
|
|
9
|
-
import { r as workflowValue } from "../../_chunks/workflow-serializable-
|
|
9
|
+
import { r as workflowValue } from "../../_chunks/workflow-serializable-DU7WeCIW.mjs";
|
|
10
10
|
function collapseConversationEvents(events) {
|
|
11
11
|
const latest = new Map();
|
|
12
12
|
for (const event of events) {
|
|
@@ -50,7 +50,7 @@ export type ConversationDecideFunction = (options: {
|
|
|
50
50
|
readonly model: string;
|
|
51
51
|
readonly state: Readonly<Record<string, string | ReadonlyArray<string>>>;
|
|
52
52
|
readonly questions: ReturnType<typeof conversationQuestions>;
|
|
53
|
-
readonly
|
|
53
|
+
readonly signal?: AbortSignal;
|
|
54
54
|
}) => Promise<{
|
|
55
55
|
readonly answers: AddressingAnswers;
|
|
56
56
|
}>;
|
|
@@ -120,12 +120,12 @@ function conversationDecisionRouter(decide) {
|
|
|
120
120
|
const state = conversationModelState(question, analysis);
|
|
121
121
|
const questions = conversationQuestions(policy.smart.instructions);
|
|
122
122
|
const started = performance.now();
|
|
123
|
-
const
|
|
123
|
+
const signal = AbortSignal.timeout(Math.ceil(policy.smart.timeoutSeconds * 1e3));
|
|
124
124
|
const { answers: raw } = await decide({
|
|
125
125
|
model: policy.smart.model,
|
|
126
126
|
state,
|
|
127
127
|
questions,
|
|
128
|
-
|
|
128
|
+
signal
|
|
129
129
|
});
|
|
130
130
|
const normalize = (answer) => {
|
|
131
131
|
const p = answer.probabilities?.true ?? answer.probability ?? NaN;
|
|
@@ -69,7 +69,7 @@ function conversationDequeueGuard(archive = conversations(), classifier = decide
|
|
|
69
69
|
groups: input.policy,
|
|
70
70
|
signals,
|
|
71
71
|
agent: input.agent,
|
|
72
|
-
processingAt:
|
|
72
|
+
processingAt: ctx.now.toISOString(),
|
|
73
73
|
agentIdentity: input.agentIdentity,
|
|
74
74
|
chat: input.chat,
|
|
75
75
|
recent,
|
|
@@ -88,7 +88,7 @@ function conversationDequeueGuard(archive = conversations(), classifier = decide
|
|
|
88
88
|
...coordinates,
|
|
89
89
|
sessionId: ctx.session.id,
|
|
90
90
|
turnId: ctx.session.turn.id,
|
|
91
|
-
at:
|
|
91
|
+
at: ctx.now.toISOString(),
|
|
92
92
|
messageId: input.signals.message.id
|
|
93
93
|
};
|
|
94
94
|
if (route === "reply") {
|
|
@@ -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 { r as redactRouterPayload } from "../../../_chunks/content-
|
|
7
|
+
import { r as redactRouterPayload } from "../../../_chunks/content-cDtVnr8Y.mjs";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
function policyHash(policy) {
|
|
10
10
|
return createHash("sha256").update(JSON.stringify(policy)).digest("hex");
|
|
@@ -86,7 +86,7 @@ async function replayRouterPayload(input) {
|
|
|
86
86
|
model: policy.smart.model,
|
|
87
87
|
state,
|
|
88
88
|
questions,
|
|
89
|
-
|
|
89
|
+
signal: AbortSignal.timeout(Math.ceil(policy.smart.timeoutSeconds * 1e3))
|
|
90
90
|
})).answers.route : answer;
|
|
91
91
|
return {
|
|
92
92
|
route: result.choice,
|
|
@@ -176,7 +176,7 @@ function decisionRouter(input) {
|
|
|
176
176
|
if (question.groups?.smart.engagement.policy === "conversation") return conversationDecisionRouter(input.decide)(question);
|
|
177
177
|
const policy = question.groups?.smart;
|
|
178
178
|
const started = performance.now();
|
|
179
|
-
const
|
|
179
|
+
const signal = AbortSignal.timeout(Math.ceil((policy?.timeoutSeconds ?? 15) * 1e3));
|
|
180
180
|
const state = conversationContext(question);
|
|
181
181
|
const questions = { route: {
|
|
182
182
|
type: "choice",
|
|
@@ -187,9 +187,9 @@ function decisionRouter(input) {
|
|
|
187
187
|
model: policy?.model ?? input.model,
|
|
188
188
|
state,
|
|
189
189
|
questions,
|
|
190
|
-
|
|
190
|
+
signal
|
|
191
191
|
}).catch((error) => {
|
|
192
|
-
if (
|
|
192
|
+
if (signal.aborted) throw new RoutingTimeoutError(error);
|
|
193
193
|
throw error;
|
|
194
194
|
});
|
|
195
195
|
const { choice, probabilities } = result.answers.route;
|
|
@@ -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-
|
|
8
|
+
import { c as compatibleRuntimeEnvelope, i as memberIdOf, r as identityProviderOf, u as runtimeEnvelope } from "../../_chunks/principal-BnJuWJtk.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";
|
|
@@ -72,7 +72,7 @@ function ontologyConnection(input) {
|
|
|
72
72
|
};
|
|
73
73
|
} } } } : {},
|
|
74
74
|
auth: {
|
|
75
|
-
|
|
75
|
+
principalType: "app",
|
|
76
76
|
getToken: async () => {
|
|
77
77
|
const value = await token();
|
|
78
78
|
const expiresAt = tokenExpiry(value);
|