@segmentstream/agent 0.9.1 → 0.10.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 +8 -0
- package/dist/_chunks/{build-metadata-DMD3azjO.mjs → build-metadata-BD1PqnN9.mjs} +1 -1
- package/dist/_chunks/{inbound-request-B8Eyjz1O.mjs → inbound-request-BrWspFw5.mjs} +2 -1
- package/dist/extension/extension.d.ts +2 -0
- package/dist/extension/extension.mjs +3 -1
- package/dist/extension/hooks/group-routing.d.ts +2 -0
- package/dist/extension/hooks/group-routing.mjs +10 -0
- package/dist/extension/lib/build-metadata.mjs +1 -1
- package/dist/extension/lib/conversation-runtime.d.ts +1 -1
- package/dist/extension/lib/conversation-runtime.mjs +23 -1
- package/dist/extension/lib/group-routing/burst.d.ts +28 -0
- package/dist/extension/lib/group-routing/burst.mjs +64 -0
- package/dist/extension/lib/group-routing/conversation-prompt.d.ts +10 -0
- package/dist/extension/lib/group-routing/conversation-prompt.mjs +16 -0
- package/dist/extension/lib/group-routing/conversation-router.d.ts +58 -0
- package/dist/extension/lib/group-routing/conversation-router.mjs +182 -0
- package/dist/extension/lib/group-routing/conversation.d.ts +46 -0
- package/dist/extension/lib/group-routing/conversation.mjs +262 -0
- package/dist/extension/lib/group-routing/dequeue.d.ts +5 -0
- package/dist/extension/lib/group-routing/dequeue.mjs +141 -0
- package/dist/extension/lib/group-routing/observed.d.ts +2 -0
- package/dist/extension/lib/group-routing/policy.d.ts +19 -1
- package/dist/extension/lib/group-routing/policy.mjs +49 -11
- package/dist/extension/lib/group-routing/replay.d.ts +2 -2
- package/dist/extension/lib/group-routing/replay.mjs +51 -11
- package/dist/extension/lib/group-routing/router.d.ts +8 -1
- package/dist/extension/lib/group-routing/router.mjs +65 -0
- package/dist/extension/lib/group-routing/routing-context.mjs +17 -2
- package/dist/extension/lib/telegram/adapter.mjs +10 -2
- package/dist/extension/lib/telegram/attachment-description.mjs +1 -1
- package/dist/extension/lib/telegram/attachments-send.mjs +1 -1
- package/dist/extension/lib/telegram/confirmation-expiry.mjs +1 -1
- package/dist/extension/lib/telegram/confirmations.mjs +1 -1
- package/dist/extension/lib/telegram/conversations.mjs +1 -1
- package/dist/extension/lib/telegram/customer-text.mjs +1 -1
- package/dist/extension/lib/telegram/deferred-confirmations.mjs +1 -1
- package/dist/extension/lib/telegram/files.mjs +1 -1
- package/dist/extension/lib/telegram/health.mjs +1 -1
- package/dist/extension/lib/telegram/images.mjs +1 -1
- package/dist/extension/lib/telegram/inbound-request.d.ts +2 -0
- package/dist/extension/lib/telegram/inbound-request.mjs +1 -1
- package/dist/extension/lib/telegram/inbound.d.ts +2 -0
- package/dist/extension/lib/telegram/inbound.mjs +122 -11
- package/dist/extension/lib/telegram/lifecycle.mjs +2 -2
- package/dist/extension/lib/telegram/media-policy.mjs +1 -1
- package/dist/extension/lib/telegram/silent.mjs +1 -1
- package/dist/extension/lib/telegram/turn-errors.mjs +1 -1
- package/dist/extension/lib/telegram/voice.mjs +1 -1
- package/package.json +2 -2
|
@@ -7,10 +7,12 @@ __eveCreateRequire(import.meta.url);
|
|
|
7
7
|
import { effectiveGroupPolicy, groupPolicy } from "../group-routing/policy.mjs";
|
|
8
8
|
import { conversationLanguage, telegramPrincipal } from "./principal.mjs";
|
|
9
9
|
import { addressingReason, conversationKey, otherRecipient } from "../group-routing/signals.mjs";
|
|
10
|
+
import { conversationAddressing, conversationState } from "../group-routing/conversation.mjs";
|
|
10
11
|
import { questionInvitation } from "../group-routing/engagement.mjs";
|
|
11
12
|
import { conversationContext, routeMessage } from "../group-routing/router.mjs";
|
|
12
13
|
import { observedContext } from "../group-routing/observed.mjs";
|
|
13
|
-
import {
|
|
14
|
+
import { debounceBurst, routingBurst } from "../group-routing/burst.mjs";
|
|
15
|
+
import { p as reportTelegramError } from "../../../_chunks/inbound-request-BrWspFw5.mjs";
|
|
14
16
|
import { startTypingHeartbeat, typingUntilComplete } from "./lifecycle.mjs";
|
|
15
17
|
import { formatAddress, messageAddress, scopedAddress } from "./sessions.mjs";
|
|
16
18
|
import { contentShape, messageContent } from "./content.mjs";
|
|
@@ -453,6 +455,19 @@ async function handleInboundMessage(input) {
|
|
|
453
455
|
mode: dependencies.policy,
|
|
454
456
|
model: dependencies.decisionModel
|
|
455
457
|
}), conversationKey(policySignals), registryChat?.scope !== void 0 && registryChat.scope !== policySignals.conversation.scope ? void 0 : registryChat?.routing, cloudGroups?.settings);
|
|
458
|
+
const conversationPolicy = group && groups.smart.engagement.policy === "conversation";
|
|
459
|
+
const agentAliases = [...groups.smart.engagement.agentAliases, ...[
|
|
460
|
+
bot?.username,
|
|
461
|
+
bot?.firstName,
|
|
462
|
+
bot?.displayName
|
|
463
|
+
].filter((n) => !!n)];
|
|
464
|
+
const freshConversation = async () => dependencies.recentConversation ? dependencies.recentConversation(sent.chat.id, sent.messageThreadId === void 0 ? void 0 : String(sent.messageThreadId)) : dependencies.observed.recent(chat);
|
|
465
|
+
let conversationRecent = conversationPolicy ? await freshConversation() : dependencies.observed.recent(chat);
|
|
466
|
+
if (conversationPolicy && input.request && input.request.lifecycleKey === void 0) {
|
|
467
|
+
address = topicAddress;
|
|
468
|
+
input.request.address = topicAddress;
|
|
469
|
+
input.request.turnPolicy = "steer";
|
|
470
|
+
}
|
|
456
471
|
const pending = questionFromHistory(questionHistory, questionOwner);
|
|
457
472
|
let answering = pending !== void 0 && (input.request?.lifecycleKey === void 0 || pending.taskId === input.request.lifecycleKey) && pending.memberId === member.id && pending.chatId === sent.chat.id && pending.messageThreadId === String(sent.messageThreadId ?? "");
|
|
458
473
|
const asked = questionHistory.findLast((event) => {
|
|
@@ -463,12 +478,21 @@ async function handleInboundMessage(input) {
|
|
|
463
478
|
});
|
|
464
479
|
const questionAge = Date.parse(sentAt(sent)) - Date.parse(asked?.meta.at ?? "");
|
|
465
480
|
if (answering && addressed === void 0 && !questionInvitation(asked?.meta.at, sentAt(sent), groups.smart.engagement.openQuestionMinutes)) answering = false;
|
|
466
|
-
|
|
467
|
-
|
|
481
|
+
if (conversationPolicy && answering) {
|
|
482
|
+
if (!conversationState({
|
|
483
|
+
signals: policySignals,
|
|
484
|
+
recent: conversationRecent,
|
|
485
|
+
policy: groups,
|
|
486
|
+
agentNames: agentAliases,
|
|
487
|
+
pendingQuestionAt: asked?.meta.at
|
|
488
|
+
}).pending_question_live) answering = false;
|
|
489
|
+
}
|
|
490
|
+
const recipientAnswer = !conversationPolicy && answering && (groups.smart.engagement.policy === "engaged" || questionAge >= 0 && questionAge <= groups.smart.engagement.followUpMinutes * 6e4) && audience.replyTo?.kind === "bot" && isRecipientAnswer(audience);
|
|
491
|
+
if (!conversationPolicy && answering && pending !== void 0 && input.request !== void 0) {
|
|
468
492
|
address = pending.address || (questionSession === void 0 ? topicAddress : memberQuestionAddress);
|
|
469
493
|
input.request.address = address;
|
|
470
494
|
}
|
|
471
|
-
if (input.request?.lifecycleKey === void 0 && group && (addressed === void 0 && !answering && groups.mode === "mention" || elsewhere !== void 0 && (addressed === void 0 || addressed === "reply-to-bot" && !recipientAnswer))) {
|
|
495
|
+
if (input.request?.lifecycleKey === void 0 && group && (addressed === void 0 && !answering && groups.mode === "mention" || !conversationPolicy && elsewhere !== void 0 && (addressed === void 0 || addressed === "reply-to-bot" && !recipientAnswer))) {
|
|
472
496
|
await recordInboundContent({
|
|
473
497
|
text,
|
|
474
498
|
decoded
|
|
@@ -480,7 +504,7 @@ async function handleInboundMessage(input) {
|
|
|
480
504
|
});
|
|
481
505
|
return null;
|
|
482
506
|
}
|
|
483
|
-
if (hasContent && answering && !await admitTurn(true)) {
|
|
507
|
+
if (!conversationPolicy && hasContent && answering && !await admitTurn(true)) {
|
|
484
508
|
await observeRaw();
|
|
485
509
|
return null;
|
|
486
510
|
}
|
|
@@ -529,7 +553,7 @@ async function handleInboundMessage(input) {
|
|
|
529
553
|
address,
|
|
530
554
|
operations,
|
|
531
555
|
read: dependencies.history ?? dependencies.readHistory,
|
|
532
|
-
remembered: dependencies.observed.recent(chat),
|
|
556
|
+
remembered: conversationPolicy ? conversationRecent : dependencies.observed.recent(chat),
|
|
533
557
|
at: sentAt(sent),
|
|
534
558
|
questionHistory,
|
|
535
559
|
questionSessionId: owner?.id
|
|
@@ -539,7 +563,8 @@ async function handleInboundMessage(input) {
|
|
|
539
563
|
name,
|
|
540
564
|
bot?.displayName,
|
|
541
565
|
bot?.firstName,
|
|
542
|
-
bot?.username
|
|
566
|
+
bot?.username,
|
|
567
|
+
...groups.smart.engagement.agentAliases
|
|
543
568
|
].filter((alias) => alias !== void 0 && alias !== ""))].slice(0, 8).map((alias) => alias.slice(0, 128));
|
|
544
569
|
question = {
|
|
545
570
|
groups,
|
|
@@ -558,7 +583,7 @@ async function handleInboundMessage(input) {
|
|
|
558
583
|
aliases
|
|
559
584
|
},
|
|
560
585
|
chat: group ? chatContext(dependencies.chats.chat(sent.chat.id)) : [],
|
|
561
|
-
recent: context.recent,
|
|
586
|
+
recent: conversationPolicy ? conversationRecent : context.recent,
|
|
562
587
|
pendingConfirmations: context.pendingConfirmations,
|
|
563
588
|
pendingQuestions: context.pendingQuestions.filter((question) => question.chatId === sent.chat.id && question.messageThreadId === String(sent.messageThreadId ?? "")),
|
|
564
589
|
message: observedMessage(sent, text, member, media, bot),
|
|
@@ -567,6 +592,48 @@ async function handleInboundMessage(input) {
|
|
|
567
592
|
};
|
|
568
593
|
return question;
|
|
569
594
|
};
|
|
595
|
+
let burstId;
|
|
596
|
+
if (conversationPolicy && input.request?.lifecycleKey === void 0) {
|
|
597
|
+
if (voice !== void 0) await transcribeVoice(true);
|
|
598
|
+
const routingSignals = {
|
|
599
|
+
...policySignals,
|
|
600
|
+
message: {
|
|
601
|
+
...policySignals.message,
|
|
602
|
+
text
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
const evidence = conversationAddressing(routingSignals, conversationRecent, groups, agentAliases);
|
|
606
|
+
if (!evidence.agent_named && !evidence.reply_to_agent && evidence.human_targets.length === 0) {
|
|
607
|
+
await recordInboundContent({
|
|
608
|
+
text,
|
|
609
|
+
decoded
|
|
610
|
+
});
|
|
611
|
+
const refreshed = await debounceBurst({
|
|
612
|
+
signals: routingSignals,
|
|
613
|
+
policy: groups,
|
|
614
|
+
read: freshConversation
|
|
615
|
+
});
|
|
616
|
+
conversationRecent = refreshed.recent;
|
|
617
|
+
question = void 0;
|
|
618
|
+
if (refreshed.burst.superseded) {
|
|
619
|
+
recordGateDecision("burst_superseded");
|
|
620
|
+
return null;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
const burst = routingBurst(routingSignals, conversationRecent, groups);
|
|
624
|
+
burstId = burst.id;
|
|
625
|
+
const q = await conversation();
|
|
626
|
+
question = {
|
|
627
|
+
...q,
|
|
628
|
+
signals: routingSignals,
|
|
629
|
+
message: {
|
|
630
|
+
...q.message,
|
|
631
|
+
text
|
|
632
|
+
},
|
|
633
|
+
burstId: burst.id,
|
|
634
|
+
messagesToClassify: burst.messages
|
|
635
|
+
};
|
|
636
|
+
}
|
|
570
637
|
const route = input.request?.lifecycleKey !== void 0 ? "reply" : await routeMessage({
|
|
571
638
|
chatId: sent.chat.id,
|
|
572
639
|
memberId: member.id,
|
|
@@ -574,6 +641,10 @@ async function handleInboundMessage(input) {
|
|
|
574
641
|
groups,
|
|
575
642
|
signals: {
|
|
576
643
|
...policySignals,
|
|
644
|
+
message: {
|
|
645
|
+
...policySignals.message,
|
|
646
|
+
text
|
|
647
|
+
},
|
|
577
648
|
sender: {
|
|
578
649
|
...policySignals.sender,
|
|
579
650
|
member
|
|
@@ -586,7 +657,7 @@ async function handleInboundMessage(input) {
|
|
|
586
657
|
record: (decision) => {
|
|
587
658
|
if (decision.reason !== "admission_refused") recordRouteDecision(decision.route, addressed, groups.mode, decision);
|
|
588
659
|
},
|
|
589
|
-
beforeDecide: () => admitTurn(false),
|
|
660
|
+
beforeDecide: (direct) => admitTurn(direct ?? false),
|
|
590
661
|
decide: dependencies.decide,
|
|
591
662
|
question: async () => {
|
|
592
663
|
classified = true;
|
|
@@ -631,6 +702,19 @@ async function handleInboundMessage(input) {
|
|
|
631
702
|
decoded,
|
|
632
703
|
...processedMedia === void 0 ? {} : { media: processedMedia }
|
|
633
704
|
});
|
|
705
|
+
if (conversationPolicy) {
|
|
706
|
+
const current = await conversation();
|
|
707
|
+
const message = {
|
|
708
|
+
...current.message,
|
|
709
|
+
text,
|
|
710
|
+
media
|
|
711
|
+
};
|
|
712
|
+
question = {
|
|
713
|
+
...current,
|
|
714
|
+
message,
|
|
715
|
+
messagesToClassify: current.messagesToClassify?.map((m) => m.messageId === message.messageId ? message : m)
|
|
716
|
+
};
|
|
717
|
+
}
|
|
634
718
|
return conversation();
|
|
635
719
|
}
|
|
636
720
|
});
|
|
@@ -810,7 +894,7 @@ async function handleInboundMessage(input) {
|
|
|
810
894
|
}
|
|
811
895
|
if (voice !== void 0 && input.request !== void 0) input.request.text = text;
|
|
812
896
|
else if (voice !== void 0) notes.push(text);
|
|
813
|
-
if (answering && pending !== void 0 && input.request !== void 0) {
|
|
897
|
+
if (!conversationPolicy && answering && pending !== void 0 && input.request !== void 0) {
|
|
814
898
|
input.request.replyTo = pending.replyToMessageId ?? input.request.replyTo;
|
|
815
899
|
input.request.lifecycleKey = pending.taskId ?? input.request.lifecycleKey;
|
|
816
900
|
input.request.text = `${answerMarker(pending.id)}\n${text}`;
|
|
@@ -868,7 +952,7 @@ async function handleInboundMessage(input) {
|
|
|
868
952
|
return null;
|
|
869
953
|
}
|
|
870
954
|
dependencies.observed.remember(chat, observedMessage(sent, text, member, retainedMedia, bot));
|
|
871
|
-
|
|
955
|
+
let principal = telegramPrincipal({
|
|
872
956
|
message: {
|
|
873
957
|
...sent,
|
|
874
958
|
text
|
|
@@ -876,6 +960,32 @@ async function handleInboundMessage(input) {
|
|
|
876
960
|
member,
|
|
877
961
|
conversationLanguage: language
|
|
878
962
|
});
|
|
963
|
+
if (conversationPolicy && input.request?.lifecycleKey === void 0) principal = {
|
|
964
|
+
...principal,
|
|
965
|
+
attributes: {
|
|
966
|
+
...principal.attributes,
|
|
967
|
+
groupRouting: JSON.stringify({
|
|
968
|
+
policy: {
|
|
969
|
+
...groups,
|
|
970
|
+
chats: {}
|
|
971
|
+
},
|
|
972
|
+
signals: {
|
|
973
|
+
...policySignals,
|
|
974
|
+
message: {
|
|
975
|
+
...policySignals.message,
|
|
976
|
+
text
|
|
977
|
+
}
|
|
978
|
+
},
|
|
979
|
+
agent: question?.agent.slice(0, 600) ?? "",
|
|
980
|
+
agentIdentity: question?.agentIdentity,
|
|
981
|
+
chat: question?.chat,
|
|
982
|
+
burst_id: burstId ?? routingBurst(policySignals, conversationRecent, groups).id,
|
|
983
|
+
message: question?.message,
|
|
984
|
+
pendingQuestions: question?.pendingQuestions,
|
|
985
|
+
pendingQuestionAt: asked?.meta.at
|
|
986
|
+
})
|
|
987
|
+
}
|
|
988
|
+
};
|
|
879
989
|
return {
|
|
880
990
|
auth: answering && pending !== void 0 ? {
|
|
881
991
|
...principal,
|
|
@@ -923,6 +1033,7 @@ async function handleInboundMessage(input) {
|
|
|
923
1033
|
group
|
|
924
1034
|
}),
|
|
925
1035
|
...processedMedia === void 0 ? [] : [processedMedia],
|
|
1036
|
+
...conversationPolicy ? ["If this member declines your involvement or closes the conversation, output exactly [SILENT]. Do not acknowledge the rejection or perform actions."] : [],
|
|
926
1037
|
...notes
|
|
927
1038
|
]
|
|
928
1039
|
};
|
|
@@ -4,9 +4,9 @@ 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-BD1PqnN9.mjs";
|
|
8
8
|
import { object } from "../confirmation-description.mjs";
|
|
9
|
-
import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-
|
|
9
|
+
import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-BrWspFw5.mjs";
|
|
10
10
|
import { needsConfirmation } from "../confirmations.mjs";
|
|
11
11
|
import { actionToolName, ontologyTools } from "../ontology-tools.mjs";
|
|
12
12
|
function attachmentLifecycle(options) {
|
|
@@ -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-
|
|
8
|
+
import { p as reportTelegramError } from "../../../_chunks/inbound-request-BrWspFw5.mjs";
|
|
9
9
|
function planMedia(capabilities, descriptionModel = null) {
|
|
10
10
|
if (typeof descriptionModel === "string") return {
|
|
11
11
|
images: "describe",
|
|
@@ -9,7 +9,7 @@ import { agentMessage, observedChatKey } from "../group-routing/observed.mjs";
|
|
|
9
9
|
import { confirmationLocale } from "./confirmation-text.mjs";
|
|
10
10
|
import { splitTelegramText } from "./format.mjs";
|
|
11
11
|
import { inTelegramSendQueue } from "./send-queue.mjs";
|
|
12
|
-
import { a as TelegramDeliveryError, l as customerMessage, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-
|
|
12
|
+
import { a as TelegramDeliveryError, l as customerMessage, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-BrWspFw5.mjs";
|
|
13
13
|
const SILENT_MARKERS = new Set(["[silent]", "no_reply"]);
|
|
14
14
|
function isSilentReply(text) {
|
|
15
15
|
return SILENT_MARKERS.has(text.trim().toLowerCase());
|
|
@@ -6,7 +6,7 @@ __eveDirname(__filename);
|
|
|
6
6
|
__eveCreateRequire(import.meta.url);
|
|
7
7
|
import { memberIdOf } from "./principal.mjs";
|
|
8
8
|
import { confirmationLocale } from "./confirmation-text.mjs";
|
|
9
|
-
import { c as customerCopy, d as failureText, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-
|
|
9
|
+
import { c as customerCopy, d as failureText, o as currentLocale, p as reportTelegramError } from "../../../_chunks/inbound-request-BrWspFw5.mjs";
|
|
10
10
|
const telegramFailureEvents = {
|
|
11
11
|
async "turn.cancelled"(event, channel, context) {
|
|
12
12
|
const errorId = reportTelegramError("turn_cancelled", event, {
|
|
@@ -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-
|
|
7
|
+
import { p as reportTelegramError } from "../../../_chunks/inbound-request-BrWspFw5.mjs";
|
|
8
8
|
import "../connection-proxy.mjs";
|
|
9
9
|
import { gateway, transcribe } from "ai";
|
|
10
10
|
const LABELS = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@segmentstream/agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.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",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@chat-adapter/telegram": "4.41.0",
|
|
65
|
-
"@segmentstream-cloud/ontology": "0.
|
|
65
|
+
"@segmentstream-cloud/ontology": "0.44.1",
|
|
66
66
|
"@vercel/oidc": "^3.8.4",
|
|
67
67
|
"ai": "^7.0.128",
|
|
68
68
|
"csv-parse": "^7.0.3",
|