@finalai/final-agent-provider 0.2.2 → 0.3.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/dist/modules/channel-factories.d.mts +3 -1
- package/dist/modules/channel-factories.mjs +32 -18
- package/dist/modules/channel-factories.mjs.map +2 -2
- package/dist/modules/channels/address-context.mjs +16 -53
- package/dist/modules/channels/address-context.mjs.map +3 -3
- package/dist/modules/channels/agent-events.d.mts +3 -29
- package/dist/modules/channels/agent-events.mjs +67 -146
- package/dist/modules/channels/agent-events.mjs.map +3 -3
- package/dist/modules/channels/agent-schedules.d.mts +1 -0
- package/dist/modules/channels/agent-schedules.mjs +18 -19
- package/dist/modules/channels/agent-schedules.mjs.map +2 -2
- package/dist/modules/channels/delivery.d.mts +1 -1
- package/dist/modules/channels/delivery.mjs +5 -23
- package/dist/modules/channels/delivery.mjs.map +2 -2
- package/dist/modules/channels/fake-platform.d.mts +6 -1
- package/dist/modules/channels/fake-platform.mjs +31 -12
- package/dist/modules/channels/fake-platform.mjs.map +2 -2
- package/dist/modules/channels/index.d.mts +1 -0
- package/dist/modules/channels/index.mjs +1 -0
- package/dist/modules/channels/index.mjs.map +2 -2
- package/dist/modules/channels/prompt.d.mts +19 -2
- package/dist/modules/channels/prompt.mjs +44 -17
- package/dist/modules/channels/prompt.mjs.map +2 -2
- package/dist/modules/channels/routing.mjs +1 -15
- package/dist/modules/channels/routing.mjs.map +2 -2
- package/dist/modules/channels/service-input.d.mts +22 -0
- package/dist/modules/channels/service-input.mjs +32 -0
- package/dist/modules/channels/service-input.mjs.map +7 -0
- package/package.json +5 -5
|
@@ -3,17 +3,15 @@ import {
|
|
|
3
3
|
Delivery,
|
|
4
4
|
jsonObjectSchema,
|
|
5
5
|
jsonValueSchema,
|
|
6
|
-
MessageKind,
|
|
7
6
|
ParticipantKind,
|
|
8
7
|
SandboxEventKind,
|
|
9
|
-
SystemParticipantKind,
|
|
10
8
|
TurnPolicy
|
|
11
9
|
} from "@finalai/agent-provider";
|
|
12
10
|
import * as z from "zod";
|
|
13
11
|
import { contentBlocksOf } from "./content.mjs";
|
|
14
|
-
import { deliverMessage } from "./delivery.mjs";
|
|
15
12
|
import { textBlock } from "./prompt.mjs";
|
|
16
13
|
import { routeMessage } from "./routing.mjs";
|
|
14
|
+
import { sendServiceInput } from "./service-input.mjs";
|
|
17
15
|
const AGENT_EVENTS_SPECIFIER = "@finalai/final-agent-provider/channels/agent-events";
|
|
18
16
|
const AGENT_EVENTS_TURN_POLICY = TurnPolicy.Steer;
|
|
19
17
|
const WEBHOOK_SECRET_NAME = "webhook";
|
|
@@ -21,16 +19,9 @@ const WEBHOOK_BODY_MAX_CHARS = 8e3;
|
|
|
21
19
|
var AgentEventKind = /* @__PURE__ */ ((AgentEventKind2) => {
|
|
22
20
|
AgentEventKind2["Webhook"] = "webhook";
|
|
23
21
|
AgentEventKind2["LinkedConversation"] = "linked-conversation";
|
|
24
|
-
AgentEventKind2["Tool"] = "tool";
|
|
25
22
|
AgentEventKind2["Sandbox"] = "sandbox";
|
|
26
23
|
return AgentEventKind2;
|
|
27
24
|
})(AgentEventKind || {});
|
|
28
|
-
var ToolEventStatus = /* @__PURE__ */ ((ToolEventStatus2) => {
|
|
29
|
-
ToolEventStatus2["Completed"] = "completed";
|
|
30
|
-
ToolEventStatus2["Failed"] = "failed";
|
|
31
|
-
ToolEventStatus2["Cancelled"] = "cancelled";
|
|
32
|
-
return ToolEventStatus2;
|
|
33
|
-
})(ToolEventStatus || {});
|
|
34
25
|
import { SandboxEventKind as SandboxEventKind2 } from "@finalai/agent-provider";
|
|
35
26
|
const SYSTEM_EVENT_TEXT_MAX_CHARS = 4e3;
|
|
36
27
|
var LinkedConversationEvent = /* @__PURE__ */ ((LinkedConversationEvent2) => {
|
|
@@ -50,8 +41,10 @@ const webhookEventSchema = z.object({
|
|
|
50
41
|
});
|
|
51
42
|
const linkedConversationEventSchema = z.object({
|
|
52
43
|
kind: z.literal("linked-conversation" /* LinkedConversation */),
|
|
53
|
-
// The conversation that linked the other: where
|
|
44
|
+
// The conversation that linked the other: where its agent is prompted.
|
|
54
45
|
conversationId: z.string().min(1),
|
|
46
|
+
// The agent that handed the work off; the Default agent when absent.
|
|
47
|
+
participantId: z.string().min(1).nullish(),
|
|
55
48
|
linkId: z.string().min(1),
|
|
56
49
|
linkedConversationId: z.string().min(1),
|
|
57
50
|
linkedTitle: z.string().nullish(),
|
|
@@ -62,19 +55,6 @@ const linkedConversationEventSchema = z.object({
|
|
|
62
55
|
eventId: z.string().min(1),
|
|
63
56
|
originTurnId: z.string().nullish()
|
|
64
57
|
});
|
|
65
|
-
const toolEventSchema = z.object({
|
|
66
|
-
kind: z.literal("tool" /* Tool */),
|
|
67
|
-
conversationId: z.string().min(1),
|
|
68
|
-
// The agent participant whose session called the tool: the only one told.
|
|
69
|
-
participantId: z.string().min(1).nullish(),
|
|
70
|
-
toolName: z.string().min(1),
|
|
71
|
-
title: z.string().nullish(),
|
|
72
|
-
status: z.nativeEnum(ToolEventStatus),
|
|
73
|
-
// The result, or what went wrong.
|
|
74
|
-
text: z.string().nullish(),
|
|
75
|
-
// Makes a redelivered event post once (per tool).
|
|
76
|
-
eventId: z.string().min(1)
|
|
77
|
-
});
|
|
78
58
|
const sandboxEventSchema = z.object({
|
|
79
59
|
kind: z.literal("sandbox" /* Sandbox */),
|
|
80
60
|
conversationId: z.string().min(1),
|
|
@@ -96,7 +76,6 @@ const sandboxEventSchema = z.object({
|
|
|
96
76
|
const agentEventInboundSchema = z.discriminatedUnion("kind", [
|
|
97
77
|
webhookEventSchema,
|
|
98
78
|
linkedConversationEventSchema,
|
|
99
|
-
toolEventSchema,
|
|
100
79
|
sandboxEventSchema
|
|
101
80
|
]);
|
|
102
81
|
var ReceiveTargetKind = /* @__PURE__ */ ((ReceiveTargetKind2) => {
|
|
@@ -107,7 +86,7 @@ var ReceiveTargetKind = /* @__PURE__ */ ((ReceiveTargetKind2) => {
|
|
|
107
86
|
const targetedInboundSchema = z.object({
|
|
108
87
|
target: z.object({ kind: z.nativeEnum(ReceiveTargetKind) }),
|
|
109
88
|
content: z.array(jsonObjectSchema).min(1),
|
|
110
|
-
// Makes a redelivered input
|
|
89
|
+
// Makes a redelivered input count once.
|
|
111
90
|
deliveryId: z.string().min(1).nullish()
|
|
112
91
|
});
|
|
113
92
|
const configSchema = z.looseObject({
|
|
@@ -151,34 +130,43 @@ const targetConversation = async (target, ctx) => {
|
|
|
151
130
|
}
|
|
152
131
|
return bound;
|
|
153
132
|
};
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
133
|
+
const bindingAgent = async (conversation, ctx) => {
|
|
134
|
+
const agent = (await ctx.platform.conversations.participants(conversation.conversationId)).find(
|
|
135
|
+
(participant) => participant.kind === ParticipantKind.Agent && !participant.left && participant.definitionId === ctx.definitionId
|
|
136
|
+
);
|
|
137
|
+
if (agent == null) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`channel binding ${ctx.bindingId ?? "(none)"} has no agent in conversation ${conversation.conversationId}`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
return agent.id;
|
|
143
|
+
};
|
|
144
|
+
const sendBindingInput = async (args) => {
|
|
145
|
+
const binding = args.ctx.bindingId ?? "none";
|
|
146
|
+
const name = configSchema.parse(args.ctx.config).displayName ?? "Webhook";
|
|
147
|
+
await sendServiceInput(args.ctx.platform, {
|
|
148
|
+
room: args.conversation.conversationId,
|
|
149
|
+
participantId: await bindingAgent(args.conversation, args.ctx),
|
|
150
|
+
content: args.content,
|
|
151
|
+
principal: { principalId: `binding:${binding}`, authenticator: "final" },
|
|
152
|
+
displayName: name,
|
|
153
|
+
idempotencyKey: `webhook:${binding}:${args.deliveryKey ?? crypto.randomUUID()}`,
|
|
154
|
+
label: `From ${name}`,
|
|
155
|
+
turnPolicy: args.turnPolicy
|
|
156
|
+
});
|
|
157
|
+
return { conversationId: args.conversation.conversationId };
|
|
158
|
+
};
|
|
159
|
+
const createTargetedInputReceive = (turnPolicy = TurnPolicy.Steer) => async (input, ctx) => {
|
|
161
160
|
const targeted = targetedInboundSchema.parse(input);
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
conversationId: conversation.conversationId,
|
|
166
|
-
authorParticipantId: author.id,
|
|
167
|
-
kind: MessageKind.Message,
|
|
161
|
+
return sendBindingInput({
|
|
162
|
+
ctx,
|
|
163
|
+
conversation: await targetConversation(targeted.target.kind, ctx),
|
|
168
164
|
content: contentBlocksOf(targeted.content),
|
|
169
|
-
|
|
165
|
+
deliveryKey: targeted.deliveryId ?? null,
|
|
166
|
+
turnPolicy
|
|
170
167
|
});
|
|
171
|
-
await deliverMessage({ platform: ctx.platform, route, conversation, message, turnPolicy });
|
|
172
|
-
return { conversationId: conversation.conversationId };
|
|
173
168
|
};
|
|
174
|
-
const
|
|
175
|
-
const deliverEventMessage = (ctx, conversation, message) => deliverMessage({
|
|
176
|
-
platform: ctx.platform,
|
|
177
|
-
route: routeMessage,
|
|
178
|
-
conversation,
|
|
179
|
-
message,
|
|
180
|
-
turnPolicy: AGENT_EVENTS_TURN_POLICY
|
|
181
|
-
});
|
|
169
|
+
const receiveTargetedInput = createTargetedInputReceive(AGENT_EVENTS_TURN_POLICY);
|
|
182
170
|
const clip = (text) => text.length <= LINKED_CONVERSATION_TEXT_MAX_CHARS ? text : `${text.slice(0, LINKED_CONVERSATION_TEXT_MAX_CHARS)}
|
|
183
171
|
\u2026 (truncated)`;
|
|
184
172
|
const renderLinkedConversationEvent = (event) => {
|
|
@@ -199,44 +187,21 @@ ${clip(text)}`;
|
|
|
199
187
|
}
|
|
200
188
|
};
|
|
201
189
|
const receiveLinkedConversationEvent = async (event, ctx) => {
|
|
202
|
-
const conversation = await ctx.platform.conversations.get(event.conversationId);
|
|
203
|
-
if (conversation == null) {
|
|
204
|
-
throw new Error(`conversation ${event.conversationId} not found`);
|
|
205
|
-
}
|
|
206
190
|
const title = event.linkedTitle?.trim() ?? "";
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
displayName: title.length === 0 ? "Linked conversation" : title,
|
|
211
|
-
sourceRef: `link:${event.linkId}`
|
|
212
|
-
});
|
|
213
|
-
const message = await ctx.platform.conversations.postMessage({
|
|
214
|
-
conversationId: conversation.conversationId,
|
|
215
|
-
authorParticipantId: author.id,
|
|
216
|
-
kind: MessageKind.Message,
|
|
191
|
+
await sendServiceInput(ctx.platform, {
|
|
192
|
+
room: event.conversationId,
|
|
193
|
+
participantId: event.participantId ?? void 0,
|
|
217
194
|
content: [textBlock(renderLinkedConversationEvent(event))],
|
|
218
|
-
|
|
219
|
-
|
|
195
|
+
principal: { principalId: `link:${event.linkId}`, authenticator: "final" },
|
|
196
|
+
displayName: title.length === 0 ? "Linked conversation" : title,
|
|
197
|
+
originTurnId: event.originTurnId ?? void 0,
|
|
198
|
+
idempotencyKey: `link:${event.linkId}:${event.eventId}`,
|
|
199
|
+
label: title.length === 0 ? "From a linked conversation" : `From \u201C${title}\u201D`
|
|
220
200
|
});
|
|
221
|
-
|
|
222
|
-
return { conversationId: conversation.conversationId };
|
|
201
|
+
return { conversationId: event.conversationId };
|
|
223
202
|
};
|
|
224
203
|
const clipEnd = (text) => text.length <= SYSTEM_EVENT_TEXT_MAX_CHARS ? text : `\u2026 (truncated)
|
|
225
204
|
${text.slice(text.length - SYSTEM_EVENT_TEXT_MAX_CHARS)}`;
|
|
226
|
-
const toolStatusText = {
|
|
227
|
-
["completed" /* Completed */]: "finished",
|
|
228
|
-
["failed" /* Failed */]: "failed",
|
|
229
|
-
["cancelled" /* Cancelled */]: "was cancelled"
|
|
230
|
-
};
|
|
231
|
-
const renderToolEvent = (event) => {
|
|
232
|
-
const title = event.title?.trim() ?? "";
|
|
233
|
-
const name = title.length === 0 ? event.toolName : `${event.toolName} "${title}"`;
|
|
234
|
-
const text = event.text?.trim() ?? "";
|
|
235
|
-
const heading = `${name} ${toolStatusText[event.status]}.`;
|
|
236
|
-
return text.length === 0 ? heading : `${heading}
|
|
237
|
-
|
|
238
|
-
${clip(text)}`;
|
|
239
|
-
};
|
|
240
205
|
const outputSection = (label, output) => {
|
|
241
206
|
const text = output?.trimEnd() ?? "";
|
|
242
207
|
return text.length === 0 ? [] : [`${label}:
|
|
@@ -255,84 +220,42 @@ const renderSandboxEvent = (event) => {
|
|
|
255
220
|
const routeToOwner = (participantId) => (args) => args.participants.some(
|
|
256
221
|
(participant) => participant.id === participantId && participant.kind === ParticipantKind.Agent && !participant.left
|
|
257
222
|
) ? [{ participantId, delivery: Delivery.Prompt }] : [];
|
|
258
|
-
const postToolSourcedEvent = async (post, ctx) => {
|
|
259
|
-
const conversation = await ctx.platform.conversations.get(post.conversationId);
|
|
260
|
-
if (conversation == null) {
|
|
261
|
-
throw new Error(`conversation ${post.conversationId} not found`);
|
|
262
|
-
}
|
|
263
|
-
const author = await ctx.platform.conversations.systemParticipant({
|
|
264
|
-
conversationId: conversation.conversationId,
|
|
265
|
-
systemKind: SystemParticipantKind.Tool,
|
|
266
|
-
displayName: post.displayName,
|
|
267
|
-
sourceRef: post.sourceRef
|
|
268
|
-
});
|
|
269
|
-
const message = await ctx.platform.conversations.postMessage({
|
|
270
|
-
conversationId: conversation.conversationId,
|
|
271
|
-
authorParticipantId: author.id,
|
|
272
|
-
kind: MessageKind.Message,
|
|
273
|
-
content: [textBlock(post.text)],
|
|
274
|
-
clientMessageId: post.clientMessageId
|
|
275
|
-
});
|
|
276
|
-
if (ctx.platform.conversations.dispatchMessage == null)
|
|
277
|
-
throw new Error("channel dispatch is unavailable");
|
|
278
|
-
await ctx.platform.conversations.dispatchMessage({
|
|
279
|
-
conversationId: conversation.conversationId,
|
|
280
|
-
messageId: message.messageId,
|
|
281
|
-
participantId: post.participantId ?? void 0,
|
|
282
|
-
requestedDelivery: post.participantId == null ? void 0 : Delivery.Prompt
|
|
283
|
-
});
|
|
284
|
-
return { conversationId: conversation.conversationId };
|
|
285
|
-
};
|
|
286
|
-
const receiveToolEvent = (event, ctx) => postToolSourcedEvent(
|
|
287
|
-
{
|
|
288
|
-
conversationId: event.conversationId,
|
|
289
|
-
participantId: event.participantId ?? null,
|
|
290
|
-
displayName: event.toolName,
|
|
291
|
-
sourceRef: `tool:${event.toolName}`,
|
|
292
|
-
text: renderToolEvent(event),
|
|
293
|
-
clientMessageId: `tool:${event.toolName}:${event.eventId}`
|
|
294
|
-
},
|
|
295
|
-
ctx
|
|
296
|
-
);
|
|
297
223
|
const nonEmptyOr = (value, fallback) => {
|
|
298
224
|
const trimmed = value?.trim() ?? "";
|
|
299
225
|
return trimmed.length === 0 ? fallback : trimmed;
|
|
300
226
|
};
|
|
301
|
-
const receiveSandboxEvent = (event, ctx) =>
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
227
|
+
const receiveSandboxEvent = async (event, ctx) => {
|
|
228
|
+
const name = nonEmptyOr(event.sandboxName, "Sandbox");
|
|
229
|
+
const args = {
|
|
230
|
+
room: event.conversationId,
|
|
231
|
+
participantId: event.participantId ?? void 0,
|
|
232
|
+
content: [textBlock(renderSandboxEvent(event))],
|
|
233
|
+
principal: { principalId: `sandbox:${event.bindingId}`, authenticator: "final" },
|
|
234
|
+
displayName: name,
|
|
235
|
+
idempotencyKey: `sandbox:${event.bindingId}:${event.eventId}`,
|
|
236
|
+
label: `After a process in ${name} finished`
|
|
237
|
+
};
|
|
238
|
+
await sendServiceInput(ctx.platform, args);
|
|
239
|
+
return { conversationId: event.conversationId };
|
|
240
|
+
};
|
|
312
241
|
const receiveAgentEvent = async (input, ctx) => {
|
|
313
|
-
if (targetedInboundSchema.safeParse(input).success) return
|
|
242
|
+
if (targetedInboundSchema.safeParse(input).success) return receiveTargetedInput(input, ctx);
|
|
314
243
|
const event = agentEventInboundSchema.parse(input);
|
|
315
244
|
if (event.kind === "webhook" /* Webhook */) {
|
|
316
|
-
const conversation = await webhookConversation(ctx);
|
|
317
245
|
const name = configSchema.parse(ctx.config).displayName ?? "Webhook";
|
|
318
|
-
const author = await bindingAuthor(conversation, ctx);
|
|
319
246
|
const heading = event.event == null ? `${name} event` : `${name} event: ${event.event}`;
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
kind: MessageKind.Message,
|
|
247
|
+
return sendBindingInput({
|
|
248
|
+
ctx,
|
|
249
|
+
conversation: await webhookConversation(ctx),
|
|
324
250
|
content: [textBlock(`${heading}
|
|
325
251
|
|
|
326
252
|
${renderBody(event.body, event.contentType ?? null)}`)],
|
|
327
|
-
|
|
253
|
+
deliveryKey: event.deliveryId ?? null
|
|
328
254
|
});
|
|
329
|
-
await deliverEventMessage(ctx, conversation, message);
|
|
330
|
-
return { conversationId: conversation.conversationId };
|
|
331
255
|
}
|
|
332
256
|
if (event.kind === "linked-conversation" /* LinkedConversation */) {
|
|
333
257
|
return receiveLinkedConversationEvent(event, ctx);
|
|
334
258
|
}
|
|
335
|
-
if (event.kind === "tool" /* Tool */) return receiveToolEvent(event, ctx);
|
|
336
259
|
return receiveSandboxEvent(event, ctx);
|
|
337
260
|
};
|
|
338
261
|
const hex = (bytes) => [...new Uint8Array(bytes)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
@@ -402,17 +325,15 @@ export {
|
|
|
402
325
|
ReceiveTargetKind,
|
|
403
326
|
SYSTEM_EVENT_TEXT_MAX_CHARS,
|
|
404
327
|
SandboxEventKind2 as SandboxEventKind,
|
|
405
|
-
ToolEventStatus,
|
|
406
328
|
WEBHOOK_BODY_MAX_CHARS,
|
|
407
329
|
WEBHOOK_SECRET_NAME,
|
|
408
330
|
agentEventInboundSchema,
|
|
409
331
|
createAgentEventsChannel,
|
|
410
|
-
|
|
332
|
+
createTargetedInputReceive,
|
|
411
333
|
hmacSha256Hex,
|
|
412
334
|
receiveAgentEvent,
|
|
413
335
|
renderLinkedConversationEvent,
|
|
414
336
|
renderSandboxEvent,
|
|
415
|
-
renderToolEvent,
|
|
416
337
|
routeToOwner,
|
|
417
338
|
targetedInboundSchema,
|
|
418
339
|
verifyWebhookSignature
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/channels/agent-events.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n defineChannel,\n Delivery,\n jsonObjectSchema,\n jsonValueSchema,\n MessageKind,\n ParticipantKind,\n SandboxEventKind,\n SystemParticipantKind,\n TurnPolicy,\n type ChannelDefinitionIface,\n type ChannelReceiveContextIface,\n type ConversationIface,\n type ConversationMessageIface,\n type ConversationRefIface,\n type JsonValue,\n type RouteArgsIface,\n type RouteDecisionIface,\n type RouteDefinitionIface,\n} from '@finalai/agent-provider';\nimport * as z from 'zod';\nimport { contentBlocksOf } from \"./content.mjs\";\nimport { deliverMessage, type DeliverMessageArgsIface } from \"./delivery.mjs\";\nimport { textBlock } from \"./prompt.mjs\";\nimport { routeMessage } from \"./routing.mjs\";\n\nexport const AGENT_EVENTS_SPECIFIER = '@finalai/final-agent-provider/channels/agent-events';\nexport const AGENT_EVENTS_TURN_POLICY = TurnPolicy.Steer;\n\n// The binding secret the webhook route verifies with (the binding's\n// `webhook_secret_ref`, resolved by the session service's secrets seam).\nexport const WEBHOOK_SECRET_NAME = 'webhook';\nexport const WEBHOOK_BODY_MAX_CHARS = 8_000;\n\nexport enum AgentEventKind {\n Webhook = 'webhook',\n LinkedConversation = 'linked-conversation',\n // A tool execution's result that arrives after the turn that started it.\n Tool = 'tool',\n // A sandbox's result that arrives after the turn that started the work.\n Sandbox = 'sandbox',\n}\n\nexport enum ToolEventStatus {\n Completed = 'completed',\n Failed = 'failed',\n Cancelled = 'cancelled',\n}\n\nexport { SandboxEventKind } from '@finalai/agent-provider';\n\nexport const SYSTEM_EVENT_TEXT_MAX_CHARS = 4_000;\n\n// What happened in a linked conversation (one a conversation handed work to).\nexport enum LinkedConversationEvent {\n // Its agent ended a turn with a reply.\n Replied = 'replied',\n // Its agent asked for a permission or an answer.\n WaitingForPerson = 'waiting_for_person',\n // Its agent's turn ended without a reply because it failed.\n Failed = 'failed',\n}\n\nexport const LINKED_CONVERSATION_TEXT_MAX_CHARS = 4_000;\n\nconst webhookEventSchema = z.object({\n kind: z.literal(AgentEventKind.Webhook),\n body: z.string(),\n contentType: z.string().nullish(),\n // A provider event name when the sender gives one (`x-github-event`).\n event: z.string().nullish(),\n deliveryId: z.string().nullish(),\n});\n\n// Posted to the conversation that linked another, as a system message from\n// the link, so the agents there hear about work they handed off.\nconst linkedConversationEventSchema = z.object({\n kind: z.literal(AgentEventKind.LinkedConversation),\n // The conversation that linked the other: where the message is posted.\n conversationId: z.string().min(1),\n linkId: z.string().min(1),\n linkedConversationId: z.string().min(1),\n linkedTitle: z.string().nullish(),\n event: z.nativeEnum(LinkedConversationEvent),\n // The reply (Replied) or what the agent asks for (WaitingForPerson).\n text: z.string().nullish(),\n // Makes a redelivered event post once (the turn or pending request).\n eventId: z.string().min(1),\n originTurnId: z.string().nullish(),\n});\n\n// Authored by the tool's own system participant in the conversation\n// whose session called it.\nconst toolEventSchema = z.object({\n kind: z.literal(AgentEventKind.Tool),\n conversationId: z.string().min(1),\n // The agent participant whose session called the tool: the only one told.\n participantId: z.string().min(1).nullish(),\n toolName: z.string().min(1),\n title: z.string().nullish(),\n status: z.nativeEnum(ToolEventStatus),\n // The result, or what went wrong.\n text: z.string().nullish(),\n // Makes a redelivered event post once (per tool).\n eventId: z.string().min(1),\n});\n\n// Authored by the sandbox binding's Tool participant in its session's conversation.\nconst sandboxEventSchema = z.object({\n kind: z.literal(AgentEventKind.Sandbox),\n conversationId: z.string().min(1),\n // The agent participant whose session started the process: the only one told.\n participantId: z.string().min(1).nullish(),\n bindingId: z.string().min(1),\n sandboxName: z.string().nullish(),\n event: z.nativeEnum(SandboxEventKind),\n processId: z.string().min(1),\n command: z.string(),\n // Null when the sandbox could not report one (the process was lost).\n exitCode: z.number().int().nullable(),\n // The end of the process's output.\n stdout: z.string().nullish(),\n stderr: z.string().nullish(),\n // Makes a redelivered event post once (per binding).\n eventId: z.string().min(1),\n});\n\nexport const agentEventInboundSchema = z.discriminatedUnion('kind', [\n webhookEventSchema,\n linkedConversationEventSchema,\n toolEventSchema,\n sandboxEventSchema,\n]);\n\nexport type ToolEventInboundIface = z.infer<typeof toolEventSchema>;\nexport type SandboxEventInboundIface = z.infer<typeof sandboxEventSchema>;\n\nexport type AgentEventInboundIface = z.infer<typeof agentEventInboundSchema>;\n\nexport enum ReceiveTargetKind {\n // The conversation the channel binding is attached to.\n BoundConversation = 'bound-conversation',\n // The agent owner's direct conversation with the agent.\n OwnerDirect = 'owner-direct',\n}\n\n// What a channel route hands to `receive`: content for a\n// target conversation, authored by the binding's system participant.\nexport const targetedInboundSchema = z.object({\n target: z.object({ kind: z.nativeEnum(ReceiveTargetKind) }),\n content: z.array(jsonObjectSchema).min(1),\n // Makes a redelivered input post once.\n deliveryId: z.string().min(1).nullish(),\n});\n\nexport type TargetedInboundIface = z.infer<typeof targetedInboundSchema>;\n\nconst configSchema = z.looseObject({\n displayName: z.string().min(1).nullish(),\n // Owner direct conversation when the binding is attached to none; null for\n // organization-owned agents, whose webhooks need a bound conversation.\n ownerUserId: z.string().min(1).nullish(),\n});\n\nconst renderBody = (body: string, contentType: string | null): string => {\n let rendered = body;\n if (contentType?.includes('json') === true) {\n try {\n rendered = JSON.stringify(jsonValueSchema.parse(JSON.parse(body)), null, 2);\n } catch {\n rendered = body;\n }\n }\n return rendered.length <= WEBHOOK_BODY_MAX_CHARS\n ? rendered\n : `${rendered.slice(0, WEBHOOK_BODY_MAX_CHARS)}\\n\u2026 (truncated)`;\n};\n\nconst boundConversation = async (\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationIface | null> =>\n ctx.bindingId == null ? null : ctx.platform.conversations.boundTo(ctx.bindingId);\n\nconst ownerDirectConversation = async (\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationIface> => {\n const config = configSchema.parse(ctx.config);\n if (config.ownerUserId == null || ctx.definitionId == null) {\n throw new Error(\n `channel binding ${ctx.bindingId ?? '(none)'} is attached to no conversation and its agent has no owner to post to`,\n );\n }\n return ctx.platform.conversations.findOrCreateDirect({\n organizationId: ctx.organizationId,\n userId: config.ownerUserId,\n definitionId: ctx.definitionId,\n });\n};\n\nconst webhookConversation = async (ctx: ChannelReceiveContextIface): Promise<ConversationIface> =>\n (await boundConversation(ctx)) ?? ownerDirectConversation(ctx);\n\nconst targetConversation = async (\n target: ReceiveTargetKind,\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationIface> => {\n if (target === ReceiveTargetKind.OwnerDirect) return ownerDirectConversation(ctx);\n const bound = await boundConversation(ctx);\n if (bound == null) {\n throw new Error(`channel binding ${ctx.bindingId ?? '(none)'} is attached to no conversation`);\n }\n return bound;\n};\n\nconst bindingAuthor = (conversation: ConversationIface, ctx: ChannelReceiveContextIface) =>\n ctx.platform.conversations.systemParticipant({\n conversationId: conversation.conversationId,\n systemKind: SystemParticipantKind.Webhook,\n displayName: configSchema.parse(ctx.config).displayName ?? 'Webhook',\n sourceRef: `binding:${ctx.bindingId ?? 'none'}`,\n });\n\nexport type ChannelReceiveIface = (\n input: JsonValue,\n ctx: ChannelReceiveContextIface,\n) => Promise<ConversationRefIface>;\n\n// The receive of a custom channel that authors none: targeted content\n// (`{target, content}`) only, delivered with the channel's route and turnPolicy.\nexport const createTargetedReceive =\n (\n route: DeliverMessageArgsIface['route'] = routeMessage,\n turnPolicy: TurnPolicy = TurnPolicy.Steer,\n ): ChannelReceiveIface =>\n async (input, ctx) => {\n const targeted = targetedInboundSchema.parse(input);\n const conversation = await targetConversation(targeted.target.kind, ctx);\n const author = await bindingAuthor(conversation, ctx);\n const message = await ctx.platform.conversations.postMessage({\n conversationId: conversation.conversationId,\n authorParticipantId: author.id,\n kind: MessageKind.Message,\n content: contentBlocksOf(targeted.content),\n clientMessageId:\n targeted.deliveryId == null\n ? null\n : `channel:${ctx.bindingId ?? 'none'}:${targeted.deliveryId}`,\n });\n await deliverMessage({ platform: ctx.platform, route, conversation, message, turnPolicy });\n return { conversationId: conversation.conversationId };\n };\n\nconst receiveTargeted = createTargetedReceive(routeMessage, AGENT_EVENTS_TURN_POLICY);\n\nconst deliverEventMessage = (\n ctx: ChannelReceiveContextIface,\n conversation: ConversationIface,\n message: ConversationMessageIface,\n) =>\n deliverMessage({\n platform: ctx.platform,\n route: routeMessage,\n conversation,\n message,\n turnPolicy: AGENT_EVENTS_TURN_POLICY,\n });\n\nconst clip = (text: string): string =>\n text.length <= LINKED_CONVERSATION_TEXT_MAX_CHARS\n ? text\n : `${text.slice(0, LINKED_CONVERSATION_TEXT_MAX_CHARS)}\\n\u2026 (truncated)`;\n\nexport const renderLinkedConversationEvent = (\n event: Pick<z.infer<typeof linkedConversationEventSchema>, 'linkedTitle' | 'event' | 'text'>,\n): string => {\n const title = event.linkedTitle?.trim() ?? '';\n const name = title.length === 0 ? 'A linked conversation' : `\"${title}\"`;\n const text = event.text?.trim() ?? '';\n switch (event.event) {\n case LinkedConversationEvent.Replied:\n return text.length === 0 ? `${name} replied.` : `${name} replied:\\n\\n${clip(text)}`;\n case LinkedConversationEvent.WaitingForPerson:\n return text.length === 0\n ? `${name} is waiting for a person.`\n : `${name} is waiting for a person: ${clip(text)}`;\n case LinkedConversationEvent.Failed:\n return text.length === 0\n ? `${name} stopped with an error.`\n : `${name} stopped with an error.\\n\\n${clip(text)}`;\n }\n};\n\n// Authored by the link's own system participant (a tool-like source: the\n// result of work handed off), routed like any system message.\nconst receiveLinkedConversationEvent = async (\n event: z.infer<typeof linkedConversationEventSchema>,\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationRefIface> => {\n const conversation = await ctx.platform.conversations.get(event.conversationId);\n if (conversation == null) {\n throw new Error(`conversation ${event.conversationId} not found`);\n }\n const title = event.linkedTitle?.trim() ?? '';\n const author = await ctx.platform.conversations.systemParticipant({\n conversationId: conversation.conversationId,\n systemKind: SystemParticipantKind.Tool,\n displayName: title.length === 0 ? 'Linked conversation' : title,\n sourceRef: `link:${event.linkId}`,\n });\n const message = await ctx.platform.conversations.postMessage({\n conversationId: conversation.conversationId,\n authorParticipantId: author.id,\n kind: MessageKind.Message,\n content: [textBlock(renderLinkedConversationEvent(event))],\n clientMessageId: `link:${event.linkId}:${event.eventId}`,\n originTurnId: event.originTurnId ?? null,\n });\n await deliverEventMessage(ctx, conversation, message);\n return { conversationId: conversation.conversationId };\n};\n\nconst clipEnd = (text: string): string =>\n text.length <= SYSTEM_EVENT_TEXT_MAX_CHARS\n ? text\n : `\u2026 (truncated)\\n${text.slice(text.length - SYSTEM_EVENT_TEXT_MAX_CHARS)}`;\n\nconst toolStatusText = {\n [ToolEventStatus.Completed]: 'finished',\n [ToolEventStatus.Failed]: 'failed',\n [ToolEventStatus.Cancelled]: 'was cancelled',\n} satisfies Record<ToolEventStatus, string>;\n\nexport const renderToolEvent = (\n event: Pick<ToolEventInboundIface, 'toolName' | 'title' | 'status' | 'text'>,\n): string => {\n const title = event.title?.trim() ?? '';\n const name = title.length === 0 ? event.toolName : `${event.toolName} \"${title}\"`;\n const text = event.text?.trim() ?? '';\n const heading = `${name} ${toolStatusText[event.status]}.`;\n return text.length === 0 ? heading : `${heading}\\n\\n${clip(text)}`;\n};\n\nconst outputSection = (label: string, output: string | null | undefined): string[] => {\n const text = output?.trimEnd() ?? '';\n return text.length === 0 ? [] : [`${label}:\\n\\`\\`\\`\\n${clipEnd(text)}\\n\\`\\`\\``];\n};\n\nexport const renderSandboxEvent = (\n event: Pick<SandboxEventInboundIface, 'processId' | 'command' | 'exitCode' | 'stdout' | 'stderr'>,\n): string => {\n const outcome =\n event.exitCode == null ? 'stopped without an exit code' : `exited with code ${event.exitCode}`;\n return [\n `Background process ${event.processId} (\\`${event.command}\\`) ${outcome}.`,\n ...outputSection('stdout', event.stdout),\n ...outputSection('stderr', event.stderr),\n ].join('\\n\\n');\n};\n\ninterface SystemEventPostIface {\n conversationId: string;\n // The agent participant whose session produced the result, when known.\n participantId: string | null;\n displayName: string;\n sourceRef: string;\n text: string;\n clientMessageId: string;\n}\n\n// A result belongs to the session that produced it: that agent is prompted and\n// nobody observes it, so one agent's tool or process output never reaches\n// another agent's history (a group's Default or All agents included).\nexport const routeToOwner =\n (participantId: string) =>\n (args: RouteArgsIface): RouteDecisionIface[] =>\n args.participants.some(\n (participant) =>\n participant.id === participantId &&\n participant.kind === ParticipantKind.Agent &&\n !participant.left,\n )\n ? [{ participantId, delivery: Delivery.Prompt }]\n : [];\n\n// A Tool-participant message for the agent whose session\n// produced it; without one (an older producer), routed like any system\n// message: to the Default agent.\nconst postToolSourcedEvent = async (\n post: SystemEventPostIface,\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationRefIface> => {\n const conversation = await ctx.platform.conversations.get(post.conversationId);\n if (conversation == null) {\n throw new Error(`conversation ${post.conversationId} not found`);\n }\n const author = await ctx.platform.conversations.systemParticipant({\n conversationId: conversation.conversationId,\n systemKind: SystemParticipantKind.Tool,\n displayName: post.displayName,\n sourceRef: post.sourceRef,\n });\n const message = await ctx.platform.conversations.postMessage({\n conversationId: conversation.conversationId,\n authorParticipantId: author.id,\n kind: MessageKind.Message,\n content: [textBlock(post.text)],\n clientMessageId: post.clientMessageId,\n });\n if (ctx.platform.conversations.dispatchMessage == null)\n throw new Error('channel dispatch is unavailable');\n await ctx.platform.conversations.dispatchMessage({\n conversationId: conversation.conversationId,\n messageId: message.messageId,\n participantId: post.participantId ?? undefined,\n requestedDelivery: post.participantId == null ? undefined : Delivery.Prompt,\n });\n return { conversationId: conversation.conversationId };\n};\n\nconst receiveToolEvent = (event: ToolEventInboundIface, ctx: ChannelReceiveContextIface) =>\n postToolSourcedEvent(\n {\n conversationId: event.conversationId,\n participantId: event.participantId ?? null,\n displayName: event.toolName,\n sourceRef: `tool:${event.toolName}`,\n text: renderToolEvent(event),\n clientMessageId: `tool:${event.toolName}:${event.eventId}`,\n },\n ctx,\n );\n\nconst nonEmptyOr = (value: string | null | undefined, fallback: string): string => {\n const trimmed = value?.trim() ?? '';\n return trimmed.length === 0 ? fallback : trimmed;\n};\n\nconst receiveSandboxEvent = (event: SandboxEventInboundIface, ctx: ChannelReceiveContextIface) =>\n postToolSourcedEvent(\n {\n conversationId: event.conversationId,\n participantId: event.participantId ?? null,\n displayName: nonEmptyOr(event.sandboxName, 'Sandbox'),\n sourceRef: `sandbox:${event.bindingId}`,\n text: renderSandboxEvent(event),\n clientMessageId: `sandbox:${event.bindingId}:${event.eventId}`,\n },\n ctx,\n );\n\n// agent-events' receive: a webhook, a linked conversation's event, a tool or\n// sandbox result, or targeted content. Outside systems (Final's Goals among\n// them) post conversation events through the public API instead.\nexport const receiveAgentEvent: ChannelReceiveIface = async (input, ctx) => {\n if (targetedInboundSchema.safeParse(input).success) return receiveTargeted(input, ctx);\n const event = agentEventInboundSchema.parse(input);\n if (event.kind === AgentEventKind.Webhook) {\n const conversation = await webhookConversation(ctx);\n const name = configSchema.parse(ctx.config).displayName ?? 'Webhook';\n const author = await bindingAuthor(conversation, ctx);\n const heading = event.event == null ? `${name} event` : `${name} event: ${event.event}`;\n const message = await ctx.platform.conversations.postMessage({\n conversationId: conversation.conversationId,\n authorParticipantId: author.id,\n kind: MessageKind.Message,\n content: [textBlock(`${heading}\\n\\n${renderBody(event.body, event.contentType ?? null)}`)],\n clientMessageId:\n event.deliveryId == null ? null : `webhook:${ctx.bindingId ?? 'none'}:${event.deliveryId}`,\n });\n await deliverEventMessage(ctx, conversation, message);\n return { conversationId: conversation.conversationId };\n }\n if (event.kind === AgentEventKind.LinkedConversation) {\n return receiveLinkedConversationEvent(event, ctx);\n }\n if (event.kind === AgentEventKind.Tool) return receiveToolEvent(event, ctx);\n return receiveSandboxEvent(event, ctx);\n};\n\nconst hex = (bytes: ArrayBuffer): string =>\n [...new Uint8Array(bytes)].map((byte) => byte.toString(16).padStart(2, '0')).join('');\n\nconst constantTimeEqual = (left: string, right: string): boolean => {\n if (left.length !== right.length) return false;\n let difference = 0;\n for (let index = 0; index < left.length; index += 1) {\n difference |= left.charCodeAt(index) ^ right.charCodeAt(index);\n }\n return difference === 0;\n};\n\nexport const hmacSha256Hex = async (secret: string, body: string): Promise<string> => {\n const encoder = new TextEncoder();\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n return hex(await crypto.subtle.sign('HMAC', key, encoder.encode(body)));\n};\n\n// `sha256=<hex>` in `x-final-signature` or GitHub's `x-hub-signature-256`.\nexport const verifyWebhookSignature = async (args: {\n secret: string;\n body: string;\n headers: Headers;\n}): Promise<boolean> => {\n const header = args.headers.get('x-final-signature') ?? args.headers.get('x-hub-signature-256');\n if (header == null) return false;\n const provided = header.startsWith('sha256=') ? header.slice('sha256='.length) : header;\n return constantTimeEqual(provided.toLowerCase(), await hmacSha256Hex(args.secret, args.body));\n};\n\nconst webhookRoute: RouteDefinitionIface = {\n method: 'POST',\n path: '/',\n handler: async ({ request, secrets, receive }) => {\n const secret = await secrets.get(WEBHOOK_SECRET_NAME);\n if (secret == null) {\n return Response.json({ error: 'webhook secret is not configured' }, { status: 503 });\n }\n const body = await request.text();\n if (!(await verifyWebhookSignature({ secret, body, headers: request.headers }))) {\n return Response.json({ error: 'invalid signature' }, { status: 401 });\n }\n const ref = await receive({\n kind: AgentEventKind.Webhook,\n body,\n contentType: request.headers.get('content-type'),\n event: request.headers.get('x-github-event') ?? request.headers.get('x-final-event'),\n deliveryId:\n request.headers.get('x-github-delivery') ?? request.headers.get('x-final-delivery'),\n });\n if (ref == null || !('conversationId' in ref))\n throw new Error('agent event channel returned no conversation');\n return Response.json({ ok: true, conversationId: ref.conversationId }, { status: 202 });\n },\n};\n\n// Webhook messages land in conversations whose own channel (direct or\n// group messaging) projects the replies, so this channel projects nothing.\nexport const createAgentEventsChannel = (): ChannelDefinitionIface<JsonValue, JsonValue> =>\n defineChannel<JsonValue, JsonValue>({\n routes: [webhookRoute],\n receive: receiveAgentEvent,\n route: routeMessage,\n turnPolicy: AGENT_EVENTS_TURN_POLICY,\n project: async () => {},\n });\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["AgentEventKind", "
|
|
4
|
+
"sourcesContent": ["import type { ContentBlock } from '@agentclientprotocol/sdk/experimental/v2';\nimport {\n defineChannel,\n Delivery,\n jsonObjectSchema,\n jsonValueSchema,\n ParticipantKind,\n SandboxEventKind,\n TurnPolicy,\n type ChannelDefinitionIface,\n type ChannelReceiveContextIface,\n type ConversationIface,\n type ConversationRefIface,\n type JsonValue,\n type RouteArgsIface,\n type RouteDecisionIface,\n type RouteDefinitionIface,\n} from '@finalai/agent-provider';\nimport * as z from 'zod';\nimport { contentBlocksOf } from \"./content.mjs\";\nimport { textBlock } from \"./prompt.mjs\";\nimport { routeMessage } from \"./routing.mjs\";\nimport { sendServiceInput, type ServiceInputArgsIface } from \"./service-input.mjs\";\n\nexport const AGENT_EVENTS_SPECIFIER = '@finalai/final-agent-provider/channels/agent-events';\nexport const AGENT_EVENTS_TURN_POLICY = TurnPolicy.Steer;\n\n// The binding secret the webhook route verifies with (the binding's\n// `webhook_secret_ref`, resolved by the session service's secrets seam).\nexport const WEBHOOK_SECRET_NAME = 'webhook';\nexport const WEBHOOK_BODY_MAX_CHARS = 8_000;\n\nexport enum AgentEventKind {\n Webhook = 'webhook',\n LinkedConversation = 'linked-conversation',\n // A sandbox's result that arrives after the turn that started the work.\n Sandbox = 'sandbox',\n}\n\nexport { SandboxEventKind } from '@finalai/agent-provider';\n\nexport const SYSTEM_EVENT_TEXT_MAX_CHARS = 4_000;\n\n// What happened in a linked conversation (one a conversation handed work to).\nexport enum LinkedConversationEvent {\n // Its agent ended a turn with a reply.\n Replied = 'replied',\n // Its agent asked for a permission or an answer.\n WaitingForPerson = 'waiting_for_person',\n // Its agent's turn ended without a reply because it failed.\n Failed = 'failed',\n}\n\nexport const LINKED_CONVERSATION_TEXT_MAX_CHARS = 4_000;\n\nconst webhookEventSchema = z.object({\n kind: z.literal(AgentEventKind.Webhook),\n body: z.string(),\n contentType: z.string().nullish(),\n // A provider event name when the sender gives one (`x-github-event`).\n event: z.string().nullish(),\n deliveryId: z.string().nullish(),\n});\n\n// Input to the conversation that linked another, from the link, so the agent\n// there hears about work it handed off.\nconst linkedConversationEventSchema = z.object({\n kind: z.literal(AgentEventKind.LinkedConversation),\n // The conversation that linked the other: where its agent is prompted.\n conversationId: z.string().min(1),\n // The agent that handed the work off; the Default agent when absent.\n participantId: z.string().min(1).nullish(),\n linkId: z.string().min(1),\n linkedConversationId: z.string().min(1),\n linkedTitle: z.string().nullish(),\n event: z.nativeEnum(LinkedConversationEvent),\n // The reply (Replied) or what the agent asks for (WaitingForPerson).\n text: z.string().nullish(),\n // Makes a redelivered event post once (the turn or pending request).\n eventId: z.string().min(1),\n originTurnId: z.string().nullish(),\n});\n\n// Input from the sandbox binding to the agent whose session started the process.\nconst sandboxEventSchema = z.object({\n kind: z.literal(AgentEventKind.Sandbox),\n conversationId: z.string().min(1),\n // The agent participant whose session started the process: the only one told.\n participantId: z.string().min(1).nullish(),\n bindingId: z.string().min(1),\n sandboxName: z.string().nullish(),\n event: z.nativeEnum(SandboxEventKind),\n processId: z.string().min(1),\n command: z.string(),\n // Null when the sandbox could not report one (the process was lost).\n exitCode: z.number().int().nullable(),\n // The end of the process's output.\n stdout: z.string().nullish(),\n stderr: z.string().nullish(),\n // Makes a redelivered event post once (per binding).\n eventId: z.string().min(1),\n});\n\nexport const agentEventInboundSchema = z.discriminatedUnion('kind', [\n webhookEventSchema,\n linkedConversationEventSchema,\n sandboxEventSchema,\n]);\n\nexport type SandboxEventInboundIface = z.infer<typeof sandboxEventSchema>;\n\nexport type AgentEventInboundIface = z.infer<typeof agentEventInboundSchema>;\n\nexport enum ReceiveTargetKind {\n // The conversation the channel binding is attached to.\n BoundConversation = 'bound-conversation',\n // The agent owner's direct conversation with the agent.\n OwnerDirect = 'owner-direct',\n}\n\n// What a channel route hands to the default `receive`: content for the\n// binding's agent in a target conversation, as input from the binding.\nexport const targetedInboundSchema = z.object({\n target: z.object({ kind: z.nativeEnum(ReceiveTargetKind) }),\n content: z.array(jsonObjectSchema).min(1),\n // Makes a redelivered input count once.\n deliveryId: z.string().min(1).nullish(),\n});\n\nexport type TargetedInboundIface = z.infer<typeof targetedInboundSchema>;\n\nconst configSchema = z.looseObject({\n displayName: z.string().min(1).nullish(),\n // Owner direct conversation when the binding is attached to none; null for\n // organization-owned agents, whose webhooks need a bound conversation.\n ownerUserId: z.string().min(1).nullish(),\n});\n\nconst renderBody = (body: string, contentType: string | null): string => {\n let rendered = body;\n if (contentType?.includes('json') === true) {\n try {\n rendered = JSON.stringify(jsonValueSchema.parse(JSON.parse(body)), null, 2);\n } catch {\n rendered = body;\n }\n }\n return rendered.length <= WEBHOOK_BODY_MAX_CHARS\n ? rendered\n : `${rendered.slice(0, WEBHOOK_BODY_MAX_CHARS)}\\n\u2026 (truncated)`;\n};\n\nconst boundConversation = async (\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationIface | null> =>\n ctx.bindingId == null ? null : ctx.platform.conversations.boundTo(ctx.bindingId);\n\nconst ownerDirectConversation = async (\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationIface> => {\n const config = configSchema.parse(ctx.config);\n if (config.ownerUserId == null || ctx.definitionId == null) {\n throw new Error(\n `channel binding ${ctx.bindingId ?? '(none)'} is attached to no conversation and its agent has no owner to post to`,\n );\n }\n return ctx.platform.conversations.findOrCreateDirect({\n organizationId: ctx.organizationId,\n userId: config.ownerUserId,\n definitionId: ctx.definitionId,\n });\n};\n\nconst webhookConversation = async (ctx: ChannelReceiveContextIface): Promise<ConversationIface> =>\n (await boundConversation(ctx)) ?? ownerDirectConversation(ctx);\n\nconst targetConversation = async (\n target: ReceiveTargetKind,\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationIface> => {\n if (target === ReceiveTargetKind.OwnerDirect) return ownerDirectConversation(ctx);\n const bound = await boundConversation(ctx);\n if (bound == null) {\n throw new Error(`channel binding ${ctx.bindingId ?? '(none)'} is attached to no conversation`);\n }\n return bound;\n};\n\n// The binding's own agent in the conversation its input goes to.\nconst bindingAgent = async (\n conversation: ConversationIface,\n ctx: ChannelReceiveContextIface,\n): Promise<string> => {\n const agent = (await ctx.platform.conversations.participants(conversation.conversationId)).find(\n (participant) =>\n participant.kind === ParticipantKind.Agent &&\n !participant.left &&\n participant.definitionId === ctx.definitionId,\n );\n if (agent == null) {\n throw new Error(\n `channel binding ${ctx.bindingId ?? '(none)'} has no agent in conversation ${conversation.conversationId}`,\n );\n }\n return agent.id;\n};\n\n// Input from the binding (a webhook or an authored route) to its agent.\nconst sendBindingInput = async (args: {\n ctx: ChannelReceiveContextIface;\n conversation: ConversationIface;\n content: ContentBlock[];\n deliveryKey: string | null;\n turnPolicy?: TurnPolicy;\n}): Promise<ConversationRefIface> => {\n const binding = args.ctx.bindingId ?? 'none';\n const name = configSchema.parse(args.ctx.config).displayName ?? 'Webhook';\n await sendServiceInput(args.ctx.platform, {\n room: args.conversation.conversationId,\n participantId: await bindingAgent(args.conversation, args.ctx),\n content: args.content,\n principal: { principalId: `binding:${binding}`, authenticator: 'final' },\n displayName: name,\n idempotencyKey: `webhook:${binding}:${args.deliveryKey ?? crypto.randomUUID()}`,\n label: `From ${name}`,\n turnPolicy: args.turnPolicy,\n });\n return { conversationId: args.conversation.conversationId };\n};\n\nexport type ChannelReceiveIface = (\n input: JsonValue,\n ctx: ChannelReceiveContextIface,\n) => Promise<ConversationRefIface>;\n\n// The receive of a custom channel that authors none: targeted content\n// (`{target, content}`), input to the binding's agent there under the\n// channel's turnPolicy.\nexport const createTargetedInputReceive =\n (turnPolicy: TurnPolicy = TurnPolicy.Steer): ChannelReceiveIface =>\n async (input, ctx) => {\n const targeted = targetedInboundSchema.parse(input);\n return sendBindingInput({\n ctx,\n conversation: await targetConversation(targeted.target.kind, ctx),\n content: contentBlocksOf(targeted.content),\n deliveryKey: targeted.deliveryId ?? null,\n turnPolicy,\n });\n };\n\nconst receiveTargetedInput = createTargetedInputReceive(AGENT_EVENTS_TURN_POLICY);\n\nconst clip = (text: string): string =>\n text.length <= LINKED_CONVERSATION_TEXT_MAX_CHARS\n ? text\n : `${text.slice(0, LINKED_CONVERSATION_TEXT_MAX_CHARS)}\\n\u2026 (truncated)`;\n\nexport const renderLinkedConversationEvent = (\n event: Pick<z.infer<typeof linkedConversationEventSchema>, 'linkedTitle' | 'event' | 'text'>,\n): string => {\n const title = event.linkedTitle?.trim() ?? '';\n const name = title.length === 0 ? 'A linked conversation' : `\"${title}\"`;\n const text = event.text?.trim() ?? '';\n switch (event.event) {\n case LinkedConversationEvent.Replied:\n return text.length === 0 ? `${name} replied.` : `${name} replied:\\n\\n${clip(text)}`;\n case LinkedConversationEvent.WaitingForPerson:\n return text.length === 0\n ? `${name} is waiting for a person.`\n : `${name} is waiting for a person: ${clip(text)}`;\n case LinkedConversationEvent.Failed:\n return text.length === 0\n ? `${name} stopped with an error.`\n : `${name} stopped with an error.\\n\\n${clip(text)}`;\n }\n};\n\n// Input from the link (the result of work handed off) to the agent that handed it off.\nconst receiveLinkedConversationEvent = async (\n event: z.infer<typeof linkedConversationEventSchema>,\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationRefIface> => {\n const title = event.linkedTitle?.trim() ?? '';\n await sendServiceInput(ctx.platform, {\n room: event.conversationId,\n participantId: event.participantId ?? undefined,\n content: [textBlock(renderLinkedConversationEvent(event))],\n principal: { principalId: `link:${event.linkId}`, authenticator: 'final' },\n displayName: title.length === 0 ? 'Linked conversation' : title,\n originTurnId: event.originTurnId ?? undefined,\n idempotencyKey: `link:${event.linkId}:${event.eventId}`,\n label: title.length === 0 ? 'From a linked conversation' : `From \u201C${title}\u201D`,\n });\n return { conversationId: event.conversationId };\n};\n\nconst clipEnd = (text: string): string =>\n text.length <= SYSTEM_EVENT_TEXT_MAX_CHARS\n ? text\n : `\u2026 (truncated)\\n${text.slice(text.length - SYSTEM_EVENT_TEXT_MAX_CHARS)}`;\n\nconst outputSection = (label: string, output: string | null | undefined): string[] => {\n const text = output?.trimEnd() ?? '';\n return text.length === 0 ? [] : [`${label}:\\n\\`\\`\\`\\n${clipEnd(text)}\\n\\`\\`\\``];\n};\n\nexport const renderSandboxEvent = (\n event: Pick<SandboxEventInboundIface, 'processId' | 'command' | 'exitCode' | 'stdout' | 'stderr'>,\n): string => {\n const outcome =\n event.exitCode == null ? 'stopped without an exit code' : `exited with code ${event.exitCode}`;\n return [\n `Background process ${event.processId} (\\`${event.command}\\`) ${outcome}.`,\n ...outputSection('stdout', event.stdout),\n ...outputSection('stderr', event.stderr),\n ].join('\\n\\n');\n};\n\n// A result belongs to the session that produced it: that agent is prompted and\n// nobody observes it, so one agent's process output never reaches another\n// agent's history (a group's Default or All agents included).\nexport const routeToOwner =\n (participantId: string) =>\n (args: RouteArgsIface): RouteDecisionIface[] =>\n args.participants.some(\n (participant) =>\n participant.id === participantId &&\n participant.kind === ParticipantKind.Agent &&\n !participant.left,\n )\n ? [{ participantId, delivery: Delivery.Prompt }]\n : [];\n\nconst nonEmptyOr = (value: string | null | undefined, fallback: string): string => {\n const trimmed = value?.trim() ?? '';\n return trimmed.length === 0 ? fallback : trimmed;\n};\n\nconst receiveSandboxEvent = async (\n event: SandboxEventInboundIface,\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationRefIface> => {\n const name = nonEmptyOr(event.sandboxName, 'Sandbox');\n const args: ServiceInputArgsIface = {\n room: event.conversationId,\n participantId: event.participantId ?? undefined,\n content: [textBlock(renderSandboxEvent(event))],\n principal: { principalId: `sandbox:${event.bindingId}`, authenticator: 'final' },\n displayName: name,\n idempotencyKey: `sandbox:${event.bindingId}:${event.eventId}`,\n label: `After a process in ${name} finished`,\n };\n await sendServiceInput(ctx.platform, args);\n return { conversationId: event.conversationId };\n};\n\n// agent-events' receive: a webhook, a linked conversation's event, a sandbox\n// result, or targeted content, each input to one agent. Outside systems\n// (Final's Goals among them) post conversation events through the public API instead.\nexport const receiveAgentEvent: ChannelReceiveIface = async (input, ctx) => {\n if (targetedInboundSchema.safeParse(input).success) return receiveTargetedInput(input, ctx);\n const event = agentEventInboundSchema.parse(input);\n if (event.kind === AgentEventKind.Webhook) {\n const name = configSchema.parse(ctx.config).displayName ?? 'Webhook';\n const heading = event.event == null ? `${name} event` : `${name} event: ${event.event}`;\n return sendBindingInput({\n ctx,\n conversation: await webhookConversation(ctx),\n content: [textBlock(`${heading}\\n\\n${renderBody(event.body, event.contentType ?? null)}`)],\n deliveryKey: event.deliveryId ?? null,\n });\n }\n if (event.kind === AgentEventKind.LinkedConversation) {\n return receiveLinkedConversationEvent(event, ctx);\n }\n return receiveSandboxEvent(event, ctx);\n};\n\nconst hex = (bytes: ArrayBuffer): string =>\n [...new Uint8Array(bytes)].map((byte) => byte.toString(16).padStart(2, '0')).join('');\n\nconst constantTimeEqual = (left: string, right: string): boolean => {\n if (left.length !== right.length) return false;\n let difference = 0;\n for (let index = 0; index < left.length; index += 1) {\n difference |= left.charCodeAt(index) ^ right.charCodeAt(index);\n }\n return difference === 0;\n};\n\nexport const hmacSha256Hex = async (secret: string, body: string): Promise<string> => {\n const encoder = new TextEncoder();\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n return hex(await crypto.subtle.sign('HMAC', key, encoder.encode(body)));\n};\n\n// `sha256=<hex>` in `x-final-signature` or GitHub's `x-hub-signature-256`.\nexport const verifyWebhookSignature = async (args: {\n secret: string;\n body: string;\n headers: Headers;\n}): Promise<boolean> => {\n const header = args.headers.get('x-final-signature') ?? args.headers.get('x-hub-signature-256');\n if (header == null) return false;\n const provided = header.startsWith('sha256=') ? header.slice('sha256='.length) : header;\n return constantTimeEqual(provided.toLowerCase(), await hmacSha256Hex(args.secret, args.body));\n};\n\nconst webhookRoute: RouteDefinitionIface = {\n method: 'POST',\n path: '/',\n handler: async ({ request, secrets, receive }) => {\n const secret = await secrets.get(WEBHOOK_SECRET_NAME);\n if (secret == null) {\n return Response.json({ error: 'webhook secret is not configured' }, { status: 503 });\n }\n const body = await request.text();\n if (!(await verifyWebhookSignature({ secret, body, headers: request.headers }))) {\n return Response.json({ error: 'invalid signature' }, { status: 401 });\n }\n const ref = await receive({\n kind: AgentEventKind.Webhook,\n body,\n contentType: request.headers.get('content-type'),\n event: request.headers.get('x-github-event') ?? request.headers.get('x-final-event'),\n deliveryId:\n request.headers.get('x-github-delivery') ?? request.headers.get('x-final-delivery'),\n });\n if (ref == null || !('conversationId' in ref))\n throw new Error('agent event channel returned no conversation');\n return Response.json({ ok: true, conversationId: ref.conversationId }, { status: 202 });\n },\n};\n\n// Its inputs go to agents in conversations whose own channel (direct or\n// group messaging) projects the replies, so this channel projects nothing.\nexport const createAgentEventsChannel = (): ChannelDefinitionIface<JsonValue, JsonValue> =>\n defineChannel<JsonValue, JsonValue>({\n routes: [webhookRoute],\n receive: receiveAgentEvent,\n route: routeMessage,\n turnPolicy: AGENT_EVENTS_TURN_POLICY,\n project: async () => {},\n });\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["AgentEventKind", "SandboxEventKind", "LinkedConversationEvent", "ReceiveTargetKind"]
|
|
7
7
|
}
|
|
@@ -14,6 +14,7 @@ export declare const scheduleFiringInboundSchema: z.ZodObject<{
|
|
|
14
14
|
prompt: z.ZodString;
|
|
15
15
|
scheduledFor: z.ZodString;
|
|
16
16
|
displayName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
17
|
+
label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
17
18
|
clientMessageId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
18
19
|
delivery: z.ZodOptional<z.ZodNullable<z.ZodEnum<typeof ScheduleDelivery>>>;
|
|
19
20
|
}, z.core.$strip>;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { FinalContentRole, withFinalMeta } from "@finalai/acp-session";
|
|
2
2
|
import {
|
|
3
3
|
defineChannel,
|
|
4
|
-
|
|
4
|
+
ParticipantKind,
|
|
5
5
|
ScheduleDelivery,
|
|
6
6
|
ScheduleTarget,
|
|
7
|
-
SystemParticipantKind,
|
|
8
7
|
TurnPolicy
|
|
9
8
|
} from "@finalai/agent-provider";
|
|
10
9
|
import * as z from "zod";
|
|
11
10
|
import { textBlock } from "./prompt.mjs";
|
|
12
11
|
import { routeMessage } from "./routing.mjs";
|
|
12
|
+
import { sendServiceInput } from "./service-input.mjs";
|
|
13
13
|
const AGENT_SCHEDULES_SPECIFIER = "@finalai/final-agent-provider/channels/agent-schedules";
|
|
14
14
|
const AGENT_SCHEDULES_TURN_POLICY = TurnPolicy.Steer;
|
|
15
15
|
const IF_NEEDED_INSTRUCTION = "This is a scheduled check with delivery=if_needed. Reply only if something needs attention; when there is nothing worth reporting, end your turn without writing a message.";
|
|
@@ -25,6 +25,8 @@ const scheduleFiringInboundSchema = z.object({
|
|
|
25
25
|
prompt: z.string().min(1),
|
|
26
26
|
scheduledFor: z.string().min(1),
|
|
27
27
|
displayName: z.string().min(1).nullish(),
|
|
28
|
+
// The caption of the agent's reply ("After the 9:00 schedule"); derived when absent.
|
|
29
|
+
label: z.string().min(1).nullish(),
|
|
28
30
|
// Defaults to scheduleFiringClientMessageId(scheduleId, scheduledFor).
|
|
29
31
|
clientMessageId: z.string().min(1).nullish(),
|
|
30
32
|
// Absent means always.
|
|
@@ -56,24 +58,21 @@ const firingContent = (firing) => firing.delivery === ScheduleDelivery.IfNeeded
|
|
|
56
58
|
const receiveScheduleFiring = async (input, ctx) => {
|
|
57
59
|
const firing = scheduleFiringInboundSchema.parse(input);
|
|
58
60
|
const conversation = await conversationForFiring(firing, ctx);
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
kind: MessageKind.Message,
|
|
61
|
+
const agent = (await ctx.platform.conversations.participants(conversation.conversationId)).find(
|
|
62
|
+
(participant) => participant.kind === ParticipantKind.Agent && !participant.left && participant.definitionId === firing.definitionId
|
|
63
|
+
);
|
|
64
|
+
if (agent == null) {
|
|
65
|
+
throw new Error(`schedule ${firing.scheduleId} has no agent in its conversation`);
|
|
66
|
+
}
|
|
67
|
+
await sendServiceInput(ctx.platform, {
|
|
68
|
+
room: conversation.conversationId,
|
|
69
|
+
participantId: agent.id,
|
|
69
70
|
content: firingContent(firing),
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
conversationId: conversation.conversationId,
|
|
76
|
-
messageId: message.messageId
|
|
71
|
+
principal: { principalId: scheduleSourceRef(firing.scheduleId), authenticator: "final" },
|
|
72
|
+
displayName: firing.displayName ?? firing.scheduleKey,
|
|
73
|
+
idempotencyKey: firing.clientMessageId ?? scheduleFiringClientMessageId(firing.scheduleId, firing.scheduledFor),
|
|
74
|
+
label: firing.label ?? `After the ${firing.displayName ?? firing.scheduleKey} schedule`,
|
|
75
|
+
turnPolicy: AGENT_SCHEDULES_TURN_POLICY
|
|
77
76
|
});
|
|
78
77
|
return { conversationId: conversation.conversationId };
|
|
79
78
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/channels/agent-schedules.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ContentBlock } from '@agentclientprotocol/sdk/experimental/v2';\nimport { FinalContentRole, withFinalMeta } from '@finalai/acp-session';\nimport {\n defineChannel,\n
|
|
5
|
-
"mappings": "AACA,SAAS,kBAAkB,qBAAqB;AAChD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,
|
|
4
|
+
"sourcesContent": ["import type { ContentBlock } from '@agentclientprotocol/sdk/experimental/v2';\nimport { FinalContentRole, withFinalMeta } from '@finalai/acp-session';\nimport {\n defineChannel,\n ParticipantKind,\n ScheduleDelivery,\n ScheduleTarget,\n TurnPolicy,\n type ChannelDefinitionIface,\n type ChannelReceiveContextIface,\n type ConversationIface,\n type ConversationRefIface,\n type JsonValue,\n} from '@finalai/agent-provider';\nimport * as z from 'zod';\nimport { textBlock } from \"./prompt.mjs\";\nimport { routeMessage } from \"./routing.mjs\";\nimport { sendServiceInput } from \"./service-input.mjs\";\n\nexport const AGENT_SCHEDULES_SPECIFIER = '@finalai/final-agent-provider/channels/agent-schedules';\nexport const AGENT_SCHEDULES_TURN_POLICY = TurnPolicy.Steer;\n\n// The instruction an if_needed firing carries (an empty turn projects nothing).\nexport const IF_NEEDED_INSTRUCTION =\n 'This is a scheduled check with delivery=if_needed. Reply only if something needs attention; when there is nothing worth reporting, end your turn without writing a message.';\n\n// One firing of an agent schedule. The session service's\n// ScheduleFire reconcile builds this; `clientMessageId` makes a retried firing\n// one input to the schedule's agent.\nexport const scheduleFiringInboundSchema = z.object({\n organizationId: z.string().min(1),\n scheduleId: z.string().min(1),\n scheduleKey: z.string().min(1),\n definitionId: z.string().min(1),\n // Required for owner-direct schedules.\n ownerUserId: z.string().min(1).nullable(),\n target: z.nativeEnum(ScheduleTarget),\n conversationId: z.string().min(1).nullable(),\n prompt: z.string().min(1),\n scheduledFor: z.string().min(1),\n displayName: z.string().min(1).nullish(),\n // The caption of the agent's reply (\"After the 9:00 schedule\"); derived when absent.\n label: z.string().min(1).nullish(),\n // Defaults to scheduleFiringClientMessageId(scheduleId, scheduledFor).\n clientMessageId: z.string().min(1).nullish(),\n // Absent means always.\n delivery: z.nativeEnum(ScheduleDelivery).nullish(),\n});\n\nexport type ScheduleFiringInboundIface = z.infer<typeof scheduleFiringInboundSchema>;\n\nexport const scheduleSourceRef = (scheduleId: string): string => `schedule:${scheduleId}`;\n\nexport const scheduleFiringClientMessageId = (scheduleId: string, scheduledFor: string): string =>\n `schedule:${scheduleId}:${scheduledFor}`;\n\nconst conversationForFiring = async (\n firing: ScheduleFiringInboundIface,\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationIface> => {\n if (firing.target === ScheduleTarget.OwnerDirect) {\n if (firing.ownerUserId == null) {\n throw new Error(`schedule ${firing.scheduleId} has no owner`);\n }\n return ctx.platform.conversations.findOrCreateDirect({\n organizationId: firing.organizationId,\n userId: firing.ownerUserId,\n definitionId: firing.definitionId,\n });\n }\n const bound =\n firing.conversationId == null\n ? ctx.bindingId == null\n ? null\n : await ctx.platform.conversations.boundTo(ctx.bindingId)\n : await ctx.platform.conversations.get(firing.conversationId);\n if (bound == null) {\n throw new Error(`schedule ${firing.scheduleId} has no bound conversation`);\n }\n return bound;\n};\n\nconst firingContent = (firing: ScheduleFiringInboundIface): ContentBlock[] =>\n firing.delivery === ScheduleDelivery.IfNeeded\n ? [\n textBlock(firing.prompt),\n withFinalMeta(textBlock(IF_NEEDED_INSTRUCTION), { role: FinalContentRole.Instruction }),\n ]\n : [textBlock(firing.prompt)];\n\n// A firing is input to the schedule's own agent from the schedule as a service\n// principal: no message is posted, and the agent's reply carries the caption.\nexport const receiveScheduleFiring = async (\n input: JsonValue,\n ctx: ChannelReceiveContextIface,\n): Promise<ConversationRefIface> => {\n const firing = scheduleFiringInboundSchema.parse(input);\n const conversation = await conversationForFiring(firing, ctx);\n const agent = (await ctx.platform.conversations.participants(conversation.conversationId)).find(\n (participant) =>\n participant.kind === ParticipantKind.Agent &&\n !participant.left &&\n participant.definitionId === firing.definitionId,\n );\n if (agent == null) {\n throw new Error(`schedule ${firing.scheduleId} has no agent in its conversation`);\n }\n await sendServiceInput(ctx.platform, {\n room: conversation.conversationId,\n participantId: agent.id,\n content: firingContent(firing),\n principal: { principalId: scheduleSourceRef(firing.scheduleId), authenticator: 'final' },\n displayName: firing.displayName ?? firing.scheduleKey,\n idempotencyKey:\n firing.clientMessageId ??\n scheduleFiringClientMessageId(firing.scheduleId, firing.scheduledFor),\n label: firing.label ?? `After the ${firing.displayName ?? firing.scheduleKey} schedule`,\n turnPolicy: AGENT_SCHEDULES_TURN_POLICY,\n });\n return { conversationId: conversation.conversationId };\n};\n\n// Firings land in conversations whose own channel (direct or group messaging)\n// projects the replies, so this channel projects nothing.\nexport const createAgentSchedulesChannel = (): ChannelDefinitionIface<JsonValue, JsonValue> =>\n defineChannel<JsonValue, JsonValue>({\n receive: receiveScheduleFiring,\n route: routeMessage,\n turnPolicy: AGENT_SCHEDULES_TURN_POLICY,\n project: async () => {},\n });\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -19,6 +19,7 @@ export declare const effectiveTurnPolicy: (args: {
|
|
|
19
19
|
channel: TurnPolicy;
|
|
20
20
|
conversation: TurnPolicy;
|
|
21
21
|
}) => TurnPolicy;
|
|
22
|
+
export declare const humanAudience: (participants: ParticipantIface[]) => string[];
|
|
22
23
|
export declare const audienceFor: (author: ParticipantIface | null, participants: ParticipantIface[]) => string[];
|
|
23
24
|
export declare const deliveryIdempotencyKey: (messageId: string, participantId: string) => string;
|
|
24
25
|
export declare const deliverMessage: (args: DeliverMessageArgsIface) => Promise<DeliveryOutcomeIface[]>;
|
|
@@ -26,7 +27,6 @@ export interface ObserveNoticeArgsIface {
|
|
|
26
27
|
platform: ChannelPlatformIface;
|
|
27
28
|
recipients: ParticipantIface[];
|
|
28
29
|
text: string;
|
|
29
|
-
sourceParticipantId: string;
|
|
30
30
|
idempotencyKey: string;
|
|
31
31
|
}
|
|
32
32
|
export declare const observeNotice: (args: ObserveNoticeArgsIface) => Promise<string[]>;
|