@finalai/final-agent-provider 0.10.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/HOSTING.md +334 -245
  2. package/README.md +125 -46
  3. package/WORKSPACE-EGRESS.md +11 -11
  4. package/dist/modules/catalog.d.mts +9 -0
  5. package/dist/modules/catalog.mjs +21 -0
  6. package/dist/modules/catalog.mjs.map +7 -0
  7. package/dist/modules/harnesses/acp-agent.d.mts +4 -0
  8. package/dist/modules/harnesses/acp-agent.mjs +35 -0
  9. package/dist/modules/harnesses/acp-agent.mjs.map +7 -0
  10. package/dist/modules/harnesses/adapters.d.mts +7 -0
  11. package/dist/modules/harnesses/adapters.mjs +74 -0
  12. package/dist/modules/harnesses/adapters.mjs.map +7 -0
  13. package/dist/modules/harnesses/claude-code.d.mts +14 -0
  14. package/dist/modules/harnesses/claude-code.mjs +79 -0
  15. package/dist/modules/harnesses/claude-code.mjs.map +7 -0
  16. package/dist/modules/harnesses/codex.d.mts +12 -0
  17. package/dist/modules/harnesses/codex.mjs +90 -0
  18. package/dist/modules/harnesses/codex.mjs.map +7 -0
  19. package/dist/modules/harnesses/config-fields.d.mts +98 -57
  20. package/dist/modules/harnesses/config-fields.mjs +58 -35
  21. package/dist/modules/harnesses/config-fields.mjs.map +3 -3
  22. package/dist/modules/harnesses/definitions.d.mts +3 -0
  23. package/dist/modules/harnesses/definitions.mjs +21 -0
  24. package/dist/modules/harnesses/definitions.mjs.map +7 -0
  25. package/dist/modules/harnesses/fidelity.d.mts +1 -1
  26. package/dist/modules/harnesses/fidelity.mjs +17 -14
  27. package/dist/modules/harnesses/fidelity.mjs.map +2 -2
  28. package/dist/modules/harnesses/final.d.mts +12 -0
  29. package/dist/modules/harnesses/final.mjs +70 -0
  30. package/dist/modules/harnesses/final.mjs.map +7 -0
  31. package/dist/modules/harnesses/index.d.mts +13 -12
  32. package/dist/modules/harnesses/index.mjs +86 -45
  33. package/dist/modules/harnesses/index.mjs.map +3 -3
  34. package/dist/modules/harnesses/names.d.mts +43 -0
  35. package/dist/modules/harnesses/names.mjs +59 -0
  36. package/dist/modules/harnesses/names.mjs.map +7 -0
  37. package/dist/modules/harnesses/nanocode-claude.d.mts +18 -0
  38. package/dist/modules/harnesses/nanocode-claude.mjs +101 -0
  39. package/dist/modules/harnesses/nanocode-claude.mjs.map +7 -0
  40. package/dist/modules/harnesses/nanocode-codex.d.mts +13 -0
  41. package/dist/modules/harnesses/nanocode-codex.mjs +64 -0
  42. package/dist/modules/harnesses/nanocode-codex.mjs.map +7 -0
  43. package/dist/modules/harnesses/pi.d.mts +12 -0
  44. package/dist/modules/harnesses/pi.mjs +71 -0
  45. package/dist/modules/harnesses/pi.mjs.map +7 -0
  46. package/dist/modules/integrations.d.mts +9 -0
  47. package/dist/modules/integrations.mjs +29 -0
  48. package/dist/modules/integrations.mjs.map +7 -0
  49. package/dist/modules/provider/general.bundle.d.mts +1 -0
  50. package/dist/modules/provider/general.bundle.mjs +5 -0
  51. package/dist/modules/provider/general.bundle.mjs.map +7 -0
  52. package/dist/modules/provider/general.d.mts +11 -0
  53. package/dist/modules/provider/general.mjs +130 -0
  54. package/dist/modules/provider/general.mjs.map +7 -0
  55. package/dist/modules/provider/index.d.mts +3 -0
  56. package/dist/modules/provider/index.mjs +13 -0
  57. package/dist/modules/provider/index.mjs.map +7 -0
  58. package/dist/modules/sandboxes/access.d.mts +34 -0
  59. package/dist/modules/sandboxes/access.mjs +15 -0
  60. package/dist/modules/sandboxes/access.mjs.map +7 -0
  61. package/dist/modules/sandboxes/computer.d.mts +24 -51
  62. package/dist/modules/sandboxes/computer.mjs +523 -888
  63. package/dist/modules/sandboxes/computer.mjs.map +3 -3
  64. package/dist/modules/sandboxes/computers-api.d.mts +3 -2
  65. package/dist/modules/sandboxes/computers-api.mjs +2 -4
  66. package/dist/modules/sandboxes/computers-api.mjs.map +2 -2
  67. package/dist/modules/sandboxes/device-api.d.mts +4 -3
  68. package/dist/modules/sandboxes/device-api.mjs +2 -4
  69. package/dist/modules/sandboxes/device-api.mjs.map +2 -2
  70. package/dist/modules/sandboxes/device.d.mts +6 -6
  71. package/dist/modules/sandboxes/device.mjs +126 -121
  72. package/dist/modules/sandboxes/device.mjs.map +3 -3
  73. package/dist/modules/sandboxes/egress.d.mts +10 -9
  74. package/dist/modules/sandboxes/egress.mjs +73 -56
  75. package/dist/modules/sandboxes/egress.mjs.map +2 -2
  76. package/dist/modules/sandboxes/environment.d.mts +35 -269
  77. package/dist/modules/sandboxes/environment.mjs +27 -104
  78. package/dist/modules/sandboxes/environment.mjs.map +3 -3
  79. package/dist/modules/sandboxes/index.d.mts +9 -69
  80. package/dist/modules/sandboxes/index.mjs +35 -95
  81. package/dist/modules/sandboxes/index.mjs.map +3 -3
  82. package/dist/modules/sandboxes/local.d.mts +29 -0
  83. package/dist/modules/sandboxes/local.mjs +555 -0
  84. package/dist/modules/sandboxes/local.mjs.map +7 -0
  85. package/dist/modules/sandboxes/session.d.mts +0 -3
  86. package/dist/modules/sandboxes/session.mjs +2 -22
  87. package/dist/modules/sandboxes/session.mjs.map +2 -2
  88. package/dist/modules/sandboxes/testing/fake-machine.mjs +0 -28
  89. package/dist/modules/sandboxes/testing/fake-machine.mjs.map +2 -2
  90. package/package.json +73 -137
  91. package/dist/modules/authoring-final-channel.d.mts +0 -3
  92. package/dist/modules/authoring-final-channel.mjs +0 -10
  93. package/dist/modules/authoring-final-channel.mjs.map +0 -7
  94. package/dist/modules/channel-factories.d.mts +0 -40
  95. package/dist/modules/channel-factories.mjs +0 -212
  96. package/dist/modules/channel-factories.mjs.map +0 -7
  97. package/dist/modules/channels/content.d.mts +0 -6
  98. package/dist/modules/channels/content.mjs +0 -31
  99. package/dist/modules/channels/content.mjs.map +0 -7
  100. package/dist/modules/channels/delivery.d.mts +0 -54
  101. package/dist/modules/channels/delivery.mjs +0 -243
  102. package/dist/modules/channels/delivery.mjs.map +0 -7
  103. package/dist/modules/channels/direct-messaging.d.mts +0 -5
  104. package/dist/modules/channels/direct-messaging.mjs +0 -8
  105. package/dist/modules/channels/direct-messaging.mjs.map +0 -7
  106. package/dist/modules/channels/fake-platform.d.mts +0 -36
  107. package/dist/modules/channels/fake-platform.mjs +0 -168
  108. package/dist/modules/channels/fake-platform.mjs.map +0 -7
  109. package/dist/modules/channels/group-messaging.d.mts +0 -5
  110. package/dist/modules/channels/group-messaging.mjs +0 -8
  111. package/dist/modules/channels/group-messaging.mjs.map +0 -7
  112. package/dist/modules/channels/inbound.d.mts +0 -52
  113. package/dist/modules/channels/inbound.mjs +0 -42
  114. package/dist/modules/channels/inbound.mjs.map +0 -7
  115. package/dist/modules/channels/index.d.mts +0 -9
  116. package/dist/modules/channels/index.mjs +0 -10
  117. package/dist/modules/channels/index.mjs.map +0 -7
  118. package/dist/modules/channels/messaging-channel.d.mts +0 -7
  119. package/dist/modules/channels/messaging-channel.mjs +0 -99
  120. package/dist/modules/channels/messaging-channel.mjs.map +0 -7
  121. package/dist/modules/channels/projection.d.mts +0 -36
  122. package/dist/modules/channels/projection.mjs +0 -233
  123. package/dist/modules/channels/projection.mjs.map +0 -7
  124. package/dist/modules/channels/prompt.d.mts +0 -72
  125. package/dist/modules/channels/prompt.mjs +0 -208
  126. package/dist/modules/channels/prompt.mjs.map +0 -7
  127. package/dist/modules/channels/routing.d.mts +0 -5
  128. package/dist/modules/channels/routing.mjs +0 -53
  129. package/dist/modules/channels/routing.mjs.map +0 -7
  130. package/dist/modules/connections.d.mts +0 -11
  131. package/dist/modules/connections.mjs +0 -16
  132. package/dist/modules/connections.mjs.map +0 -7
  133. package/dist/modules/harnesses/acp-describe.d.mts +0 -20
  134. package/dist/modules/harnesses/acp-describe.mjs +0 -110
  135. package/dist/modules/harnesses/acp-describe.mjs.map +0 -7
  136. package/dist/modules/harnesses/local-stdio.d.mts +0 -47
  137. package/dist/modules/harnesses/local-stdio.mjs +0 -41
  138. package/dist/modules/harnesses/local-stdio.mjs.map +0 -7
  139. package/dist/modules/harnesses/remote-acp.d.mts +0 -76
  140. package/dist/modules/harnesses/remote-acp.mjs +0 -83
  141. package/dist/modules/harnesses/remote-acp.mjs.map +0 -7
  142. package/dist/modules/harnesses/remote-claude-code.d.mts +0 -88
  143. package/dist/modules/harnesses/remote-claude-code.mjs +0 -113
  144. package/dist/modules/harnesses/remote-claude-code.mjs.map +0 -7
  145. package/dist/modules/harnesses/remote-client-tls.d.mts +0 -35
  146. package/dist/modules/harnesses/remote-client-tls.mjs +0 -37
  147. package/dist/modules/harnesses/remote-client-tls.mjs.map +0 -7
  148. package/dist/modules/harnesses/remote-codex.d.mts +0 -98
  149. package/dist/modules/harnesses/remote-codex.mjs +0 -128
  150. package/dist/modules/harnesses/remote-codex.mjs.map +0 -7
  151. package/dist/modules/harnesses/remote-pi.d.mts +0 -78
  152. package/dist/modules/harnesses/remote-pi.mjs +0 -104
  153. package/dist/modules/harnesses/remote-pi.mjs.map +0 -7
  154. package/dist/modules/harnesses/remote-url.d.mts +0 -5
  155. package/dist/modules/harnesses/remote-url.mjs +0 -19
  156. package/dist/modules/harnesses/remote-url.mjs.map +0 -7
  157. package/dist/modules/harnesses/serverless-final.d.mts +0 -63
  158. package/dist/modules/harnesses/serverless-final.mjs +0 -88
  159. package/dist/modules/harnesses/serverless-final.mjs.map +0 -7
  160. package/dist/modules/harnesses/serverless-nanocode-claude.d.mts +0 -64
  161. package/dist/modules/harnesses/serverless-nanocode-claude.mjs +0 -105
  162. package/dist/modules/harnesses/serverless-nanocode-claude.mjs.map +0 -7
  163. package/dist/modules/harnesses/serverless-nanocode-codex.d.mts +0 -66
  164. package/dist/modules/harnesses/serverless-nanocode-codex.mjs +0 -113
  165. package/dist/modules/harnesses/serverless-nanocode-codex.mjs.map +0 -7
  166. package/dist/modules/harnesses/serverless-pi.d.mts +0 -64
  167. package/dist/modules/harnesses/serverless-pi.mjs +0 -98
  168. package/dist/modules/harnesses/serverless-pi.mjs.map +0 -7
  169. package/dist/modules/runtime/index.d.mts +0 -7
  170. package/dist/modules/runtime/index.mjs +0 -18
  171. package/dist/modules/runtime/index.mjs.map +0 -7
  172. package/dist/modules/runtime/local-stdio.d.mts +0 -10
  173. package/dist/modules/runtime/local-stdio.mjs +0 -106
  174. package/dist/modules/runtime/local-stdio.mjs.map +0 -7
  175. package/dist/modules/runtime/remote-acp.d.mts +0 -16
  176. package/dist/modules/runtime/remote-acp.mjs +0 -152
  177. package/dist/modules/runtime/remote-acp.mjs.map +0 -7
  178. package/dist/modules/runtime/remote-claude-code.d.mts +0 -5
  179. package/dist/modules/runtime/remote-claude-code.mjs +0 -47
  180. package/dist/modules/runtime/remote-claude-code.mjs.map +0 -7
  181. package/dist/modules/runtime/remote-codex.d.mts +0 -5
  182. package/dist/modules/runtime/remote-codex.mjs +0 -47
  183. package/dist/modules/runtime/remote-codex.mjs.map +0 -7
  184. package/dist/modules/runtime/remote-host.d.mts +0 -127
  185. package/dist/modules/runtime/remote-host.mjs +0 -387
  186. package/dist/modules/runtime/remote-host.mjs.map +0 -7
  187. package/dist/modules/runtime/remote-pi.d.mts +0 -5
  188. package/dist/modules/runtime/remote-pi.mjs +0 -44
  189. package/dist/modules/runtime/remote-pi.mjs.map +0 -7
  190. package/dist/modules/sandboxes/guide.d.mts +0 -35
  191. package/dist/modules/sandboxes/guide.mjs +0 -119
  192. package/dist/modules/sandboxes/guide.mjs.map +0 -7
  193. package/dist/modules/sandboxes/workspace-setup.d.mts +0 -42
  194. package/dist/modules/sandboxes/workspace-setup.mjs +0 -242
  195. package/dist/modules/sandboxes/workspace-setup.mjs.map +0 -7
  196. package/dist/modules/testing/harness.d.mts +0 -9
  197. package/dist/modules/testing/harness.mjs +0 -123
  198. package/dist/modules/testing/harness.mjs.map +0 -7
@@ -1,40 +0,0 @@
1
- import type { SessionUpdate } from '@agentclientprotocol/sdk/experimental/v2';
2
- import { TurnPolicy, type RoomAuthIface, type RoomSurfaceDefinitionIface, type RoomInputResponseIface, type ChannelMessageCompletedDataIface, type ChannelMessageDeltaDataIface, type RoomReceiveContextIface, type ChannelTurnEventDataIface, type ChannelTurnStateIface, type ConversationMessageIface, type DecisionCreatedDataIface, type DecisionResolvedDataIface, type JsonValue } from '@finalai/agent-provider';
3
- export { RoomPrincipalType, type RoomAuthIface } from '@finalai/agent-provider';
4
- export interface ChannelAdmissionIface {
5
- auth: RoomAuthIface | null;
6
- context?: string[];
7
- title?: string;
8
- }
9
- export interface FinalMessageContextIface extends RoomReceiveContextIface {
10
- defaultAuth: RoomAuthIface | null;
11
- }
12
- export interface FinalChannelContextIface {
13
- final: {
14
- post(message: ChannelMessageCompletedDataIface['message']): Promise<ConversationMessageIface>;
15
- };
16
- }
17
- export interface FinalSessionContextIface {
18
- sessionId: string | null;
19
- turnId: string;
20
- state: ChannelTurnStateIface<JsonValue>;
21
- }
22
- export type FinalChannelEventHandler<Data> = (data: Data, channel: FinalChannelContextIface, ctx: FinalSessionContextIface) => void | Promise<void>;
23
- export interface FinalChannelEventHandlersIface {
24
- 'message.delta'?: FinalChannelEventHandler<ChannelMessageDeltaDataIface>;
25
- 'message.completed'?: FinalChannelEventHandler<ChannelMessageCompletedDataIface>;
26
- 'turn.started'?: FinalChannelEventHandler<ChannelTurnEventDataIface>;
27
- 'turn.completed'?: FinalChannelEventHandler<ChannelTurnEventDataIface>;
28
- 'decision.created'?: FinalChannelEventHandler<DecisionCreatedDataIface>;
29
- 'decision.resolved'?: FinalChannelEventHandler<DecisionResolvedDataIface>;
30
- }
31
- export interface FinalChannelOptionsIface {
32
- turnPolicy?: TurnPolicy | `${TurnPolicy}`;
33
- updateIntervalMs?: number;
34
- route?: RoomSurfaceDefinitionIface<JsonValue, JsonValue>['route'];
35
- onMessage?: (ctx: FinalMessageContextIface, message: ConversationMessageIface) => ChannelAdmissionIface | null | Promise<ChannelAdmissionIface | null>;
36
- onInputResponse?: (ctx: FinalMessageContextIface, response: RoomInputResponseIface) => ChannelAdmissionIface | null | Promise<ChannelAdmissionIface | null>;
37
- events?: FinalChannelEventHandlersIface;
38
- renderer?: (update: SessionUpdate, channel: FinalChannelContextIface, ctx: FinalSessionContextIface, next: () => Promise<void>) => void | Promise<void>;
39
- }
40
- export declare const finalChannel: (inputOptions?: FinalChannelOptionsIface) => RoomSurfaceDefinitionIface<JsonValue, JsonValue>;
@@ -1,212 +0,0 @@
1
- import {
2
- RoomPrincipalType,
3
- SemanticChannelEventKind,
4
- TurnPolicy,
5
- roomAuthSchema,
6
- channelMessageCompletedSchema,
7
- decisionCreatedDataSchema,
8
- decisionResolvedDataSchema,
9
- defineRoomSurface,
10
- jsonObjectSchema
11
- } from "@finalai/agent-provider";
12
- import * as z from "zod";
13
- import { contentBlocksOf } from "./channels/content.mjs";
14
- import { conversationEventInboundSchema, messageInboundSchema } from "./channels/inbound.mjs";
15
- import { createMessagingChannel } from "./channels/messaging-channel.mjs";
16
- import { RoomPrincipalType as RoomPrincipalType2 } from "@finalai/agent-provider";
17
- const admissionSchema = z.object({
18
- auth: roomAuthSchema.nullable(),
19
- context: z.array(z.string()).optional(),
20
- title: z.string().optional()
21
- });
22
- const optionsSchema = z.object({
23
- turnPolicy: z.nativeEnum(TurnPolicy).default(TurnPolicy.Steer),
24
- updateIntervalMs: z.number().finite().nonnegative().optional()
25
- });
26
- const defaultAuthOf = (author) => {
27
- if (author == null) return null;
28
- return {
29
- principalId: author.userId ?? author.definitionId ?? author.id,
30
- principalType: author.userId == null ? RoomPrincipalType.Service : RoomPrincipalType.User,
31
- authenticator: "final",
32
- displayName: author.displayName,
33
- attributes: { participant_id: author.id }
34
- };
35
- };
36
- const finalChannel = (inputOptions = {}) => {
37
- const options = {
38
- ...inputOptions,
39
- events: inputOptions.events == null ? void 0 : { ...inputOptions.events }
40
- };
41
- const callbacks = {
42
- onMessage: options.onMessage,
43
- onInputResponse: options.onInputResponse,
44
- renderer: options.renderer,
45
- route: options.route,
46
- ...options.events
47
- };
48
- for (const [name, callback] of Object.entries(callbacks))
49
- if (callback != null && !z.function().safeParse(callback).success)
50
- throw new Error(`Final channel ${name} must be a function`);
51
- const supportedEvents = /* @__PURE__ */ new Set([
52
- "message.delta",
53
- "message.completed",
54
- "turn.started",
55
- "turn.completed",
56
- "decision.created",
57
- "decision.resolved"
58
- ]);
59
- for (const kind of Object.keys(options.events ?? {}))
60
- if (!supportedEvents.has(kind)) throw new Error(`unsupported Final channel event: ${kind}`);
61
- const config = optionsSchema.parse(options);
62
- const base = createMessagingChannel({ ...config, route: options.route });
63
- const receive = async (input, ctx) => {
64
- if (conversationEventInboundSchema.safeParse(input).success) return base.receive(input, ctx);
65
- const parsed = messageInboundSchema.parse(input);
66
- const participants = ctx.participants ?? await ctx.platform.conversations.participants(parsed.conversationId);
67
- const author = participants.find(
68
- (participant) => participant.id === parsed.authorParticipantId
69
- );
70
- const message = ctx.message ?? await ctx.platform.conversations.postMessage({
71
- ...parsed,
72
- content: contentBlocksOf(parsed.content)
73
- });
74
- if (ctx.definitionId == null) throw new Error("Final channel has no agent definition");
75
- const messageContext = {
76
- ...ctx,
77
- defaultAuth: defaultAuthOf(author)
78
- };
79
- const accepted = options.onMessage == null ? { auth: messageContext.defaultAuth } : await options.onMessage(messageContext, message);
80
- const admission = accepted == null ? null : admissionSchema.parse(accepted);
81
- if (admission == null) return { conversationId: parsed.conversationId };
82
- const context = admission.context ?? [];
83
- const injected = context.map((text) => ({ type: "text", text }));
84
- return base.receive(
85
- {
86
- ...parsed,
87
- content: [...context.map((text) => ({ type: "text", text })), ...parsed.content]
88
- },
89
- {
90
- ...ctx,
91
- platform: {
92
- ...ctx.platform,
93
- sessions: {
94
- ...ctx.platform.sessions,
95
- prompt: (args) => ctx.platform.sessions.prompt({
96
- ...args,
97
- auth: admission.auth,
98
- title: admission.title
99
- })
100
- }
101
- },
102
- message: { ...message, content: [...injected, ...message.content] }
103
- }
104
- );
105
- };
106
- const channelContext = (ctx) => {
107
- const { conversation, agentParticipant } = ctx;
108
- if (conversation == null || agentParticipant == null || agentParticipant.definitionId == null)
109
- throw new Error("Final platform context requires a Final conversation");
110
- return {
111
- final: {
112
- post: async (message) => {
113
- if (ctx.platform.conversations.dispatchMessage == null)
114
- throw new Error("channel dispatch is unavailable");
115
- const posted = await ctx.platform.conversations.postMessage({
116
- conversationId: conversation.conversationId,
117
- authorParticipantId: agentParticipant.id,
118
- content: contentBlocksOf(message.content),
119
- clientMessageId: `channel:${ctx.turn.id}:${message.id}`,
120
- originTurnId: ctx.turn.id
121
- });
122
- await ctx.platform.conversations.dispatchMessage({
123
- conversationId: posted.conversationId,
124
- messageId: posted.messageId
125
- });
126
- return posted;
127
- }
128
- }
129
- };
130
- };
131
- const sessionContext = (ctx) => ({
132
- sessionId: ctx.sessionId ?? null,
133
- turnId: ctx.turn.id,
134
- state: ctx.state
135
- });
136
- const wrap = (schema, handler) => handler == null ? void 0 : async (event, ctx) => handler(schema.parse(event.data), channelContext(ctx), sessionContext(ctx));
137
- const authoredEvents = {
138
- [SemanticChannelEventKind.MessageCompleted]: wrap(
139
- channelMessageCompletedSchema,
140
- options.events?.["message.completed"]
141
- ),
142
- [SemanticChannelEventKind.MessageDelta]: wrap(
143
- z.object({ messageId: z.string(), delta: jsonObjectSchema }),
144
- options.events?.["message.delta"]
145
- ),
146
- [SemanticChannelEventKind.TurnStarted]: wrap(
147
- z.object({ turnId: z.string() }),
148
- options.events?.["turn.started"]
149
- ),
150
- [SemanticChannelEventKind.TurnCompleted]: wrap(
151
- z.object({ turnId: z.string(), stopReason: z.string().nullable() }),
152
- options.events?.["turn.completed"]
153
- ),
154
- "decision.created": wrap(decisionCreatedDataSchema, options.events?.["decision.created"]),
155
- "decision.resolved": wrap(decisionResolvedDataSchema, options.events?.["decision.resolved"])
156
- };
157
- const events = { ...base.events };
158
- for (const [kind, handler] of Object.entries(authoredEvents))
159
- if (handler != null) events[kind] = handler;
160
- return Object.freeze(
161
- defineRoomSurface({
162
- ...base,
163
- config: jsonObjectSchema.parse(config),
164
- configure: (next) => finalChannel({ ...options, ...optionsSchema.parse({ ...config, ...next }) }),
165
- receive,
166
- respond: async (input, ctx) => {
167
- const conversation = z.string().min(1).parse(ctx.conversationId);
168
- const participants = await ctx.platform.conversations.participants(conversation);
169
- const author = participants.find(
170
- (participant) => participant.id === input.actorParticipantId
171
- );
172
- const defaultAuth = defaultAuthOf(author);
173
- let admission = { auth: defaultAuth };
174
- if (options.onInputResponse != null) {
175
- const accepted = await options.onInputResponse({ ...ctx, defaultAuth }, input);
176
- if (accepted == null) return { resolved: false };
177
- admission = admissionSchema.parse(accepted);
178
- }
179
- if (ctx.platform.sessions.respond == null)
180
- throw new Error("response submission is unavailable");
181
- return ctx.platform.sessions.respond({ ...input, auth: admission.auth });
182
- },
183
- cancel: async (ctx) => {
184
- if (ctx.agentParticipantId == null) return { accepted: false };
185
- const conversation = z.string().min(1).parse(ctx.conversationId);
186
- const participants = await ctx.platform.conversations.participants(conversation);
187
- const agent = participants.find((participant) => participant.id === ctx.agentParticipantId);
188
- if (agent?.sessionId == null) return { accepted: false };
189
- await ctx.platform.sessions.cancel({
190
- participantId: agent.id,
191
- reason: ctx.cancelReason,
192
- throughMessageSeq: ctx.cancelThroughMessageSeq
193
- });
194
- return { accepted: true };
195
- },
196
- project: async (update, ctx) => {
197
- const next = () => options.events?.["message.completed"] == null ? base.project(update, ctx) : Promise.resolve();
198
- if (options.renderer != null) {
199
- await options.renderer(update, channelContext(ctx), sessionContext(ctx), next);
200
- return;
201
- }
202
- await next();
203
- },
204
- events: Object.freeze(events)
205
- })
206
- );
207
- };
208
- export {
209
- RoomPrincipalType2 as RoomPrincipalType,
210
- finalChannel
211
- };
212
- //# sourceMappingURL=channel-factories.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/channel-factories.ts"],
4
- "sourcesContent": ["import type { ContentBlock, SessionUpdate } from '@agentclientprotocol/sdk/experimental/v2';\nimport {\n RoomPrincipalType,\n SemanticChannelEventKind,\n TurnPolicy,\n roomAuthSchema,\n channelMessageCompletedSchema,\n decisionCreatedDataSchema,\n decisionResolvedDataSchema,\n defineRoomSurface,\n jsonObjectSchema,\n type RoomAuthIface,\n type RoomSurfaceDefinitionIface,\n type RoomEventHandler,\n type RoomInputResponseIface,\n type ChannelMessageCompletedDataIface,\n type ChannelMessageDeltaDataIface,\n type RoomReceiveContextIface,\n type ChannelTurnEventDataIface,\n type ChannelTurnStateIface,\n type ConversationMessageIface,\n type DecisionCreatedDataIface,\n type DecisionResolvedDataIface,\n type JsonValue,\n type ProjectionContextIface,\n} from '@finalai/agent-provider';\nimport * as z from 'zod';\nimport { contentBlocksOf } from \"./channels/content.mjs\";\nimport { conversationEventInboundSchema, messageInboundSchema } from \"./channels/inbound.mjs\";\nimport { createMessagingChannel } from \"./channels/messaging-channel.mjs\";\n\nexport { RoomPrincipalType, type RoomAuthIface } from '@finalai/agent-provider';\n\nexport interface ChannelAdmissionIface {\n auth: RoomAuthIface | null;\n context?: string[];\n title?: string;\n}\n\nexport interface FinalMessageContextIface extends RoomReceiveContextIface {\n defaultAuth: RoomAuthIface | null;\n}\n\nexport interface FinalChannelContextIface {\n final: {\n post(message: ChannelMessageCompletedDataIface['message']): Promise<ConversationMessageIface>;\n };\n}\nexport interface FinalSessionContextIface {\n sessionId: string | null;\n turnId: string;\n state: ChannelTurnStateIface<JsonValue>;\n}\nexport type FinalChannelEventHandler<Data> = (\n data: Data,\n channel: FinalChannelContextIface,\n ctx: FinalSessionContextIface,\n) => void | Promise<void>;\nexport interface FinalChannelEventHandlersIface {\n 'message.delta'?: FinalChannelEventHandler<ChannelMessageDeltaDataIface>;\n 'message.completed'?: FinalChannelEventHandler<ChannelMessageCompletedDataIface>;\n 'turn.started'?: FinalChannelEventHandler<ChannelTurnEventDataIface>;\n 'turn.completed'?: FinalChannelEventHandler<ChannelTurnEventDataIface>;\n 'decision.created'?: FinalChannelEventHandler<DecisionCreatedDataIface>;\n 'decision.resolved'?: FinalChannelEventHandler<DecisionResolvedDataIface>;\n}\n\nexport interface FinalChannelOptionsIface {\n turnPolicy?: TurnPolicy | `${TurnPolicy}`;\n updateIntervalMs?: number;\n route?: RoomSurfaceDefinitionIface<JsonValue, JsonValue>['route'];\n onMessage?: (\n ctx: FinalMessageContextIface,\n message: ConversationMessageIface,\n ) => ChannelAdmissionIface | null | Promise<ChannelAdmissionIface | null>;\n onInputResponse?: (\n ctx: FinalMessageContextIface,\n response: RoomInputResponseIface,\n ) => ChannelAdmissionIface | null | Promise<ChannelAdmissionIface | null>;\n events?: FinalChannelEventHandlersIface;\n renderer?: (\n update: SessionUpdate,\n channel: FinalChannelContextIface,\n ctx: FinalSessionContextIface,\n next: () => Promise<void>,\n ) => void | Promise<void>;\n}\n\nconst admissionSchema = z.object({\n auth: roomAuthSchema.nullable(),\n context: z.array(z.string()).optional(),\n title: z.string().optional(),\n});\n\nconst optionsSchema = z.object({\n turnPolicy: z.nativeEnum(TurnPolicy).default(TurnPolicy.Steer),\n updateIntervalMs: z.number().finite().nonnegative().optional(),\n});\n\n// A room member as a principal: a person by user id, an agent by definition id.\nconst defaultAuthOf = (\n author: import('@finalai/agent-provider').ParticipantIface | undefined,\n): RoomAuthIface | null => {\n if (author == null) return null;\n return {\n principalId: author.userId ?? author.definitionId ?? author.id,\n principalType: author.userId == null ? RoomPrincipalType.Service : RoomPrincipalType.User,\n authenticator: 'final',\n displayName: author.displayName,\n attributes: { participant_id: author.id },\n };\n};\n\nexport const finalChannel = (\n inputOptions: FinalChannelOptionsIface = {},\n): RoomSurfaceDefinitionIface<JsonValue, JsonValue> => {\n const options = {\n ...inputOptions,\n events: inputOptions.events == null ? undefined : { ...inputOptions.events },\n };\n const callbacks = {\n onMessage: options.onMessage,\n onInputResponse: options.onInputResponse,\n renderer: options.renderer,\n route: options.route,\n ...options.events,\n };\n for (const [name, callback] of Object.entries(callbacks))\n if (callback != null && !z.function().safeParse(callback).success)\n throw new Error(`Final channel ${name} must be a function`);\n const supportedEvents = new Set([\n 'message.delta',\n 'message.completed',\n 'turn.started',\n 'turn.completed',\n 'decision.created',\n 'decision.resolved',\n ]);\n for (const kind of Object.keys(options.events ?? {}))\n if (!supportedEvents.has(kind)) throw new Error(`unsupported Final channel event: ${kind}`);\n const config = optionsSchema.parse(options);\n const base = createMessagingChannel({ ...config, route: options.route });\n const receive: typeof base.receive = async (input, ctx) => {\n if (conversationEventInboundSchema.safeParse(input).success) return base.receive(input, ctx);\n const parsed = messageInboundSchema.parse(input);\n const participants =\n ctx.participants ?? (await ctx.platform.conversations.participants(parsed.conversationId));\n const author = participants.find(\n (participant) => participant.id === parsed.authorParticipantId,\n );\n const message =\n ctx.message ??\n (await ctx.platform.conversations.postMessage({\n ...parsed,\n content: contentBlocksOf(parsed.content),\n }));\n if (ctx.definitionId == null) throw new Error('Final channel has no agent definition');\n const messageContext: FinalMessageContextIface = {\n ...ctx,\n defaultAuth: defaultAuthOf(author),\n };\n const accepted =\n options.onMessage == null\n ? { auth: messageContext.defaultAuth }\n : await options.onMessage(messageContext, message);\n const admission = accepted == null ? null : admissionSchema.parse(accepted);\n if (admission == null) return { conversationId: parsed.conversationId };\n const context = admission.context ?? [];\n const injected: ContentBlock[] = context.map((text) => ({ type: 'text', text }));\n return base.receive(\n {\n ...parsed,\n content: [...context.map((text) => ({ type: 'text', text })), ...parsed.content],\n },\n {\n ...ctx,\n platform: {\n ...ctx.platform,\n sessions: {\n ...ctx.platform.sessions,\n prompt: (args) =>\n ctx.platform.sessions.prompt({\n ...args,\n auth: admission.auth,\n title: admission.title,\n }),\n },\n },\n message: { ...message, content: [...injected, ...message.content] },\n },\n );\n };\n const channelContext = (ctx: ProjectionContextIface): FinalChannelContextIface => {\n const { conversation, agentParticipant } = ctx;\n if (conversation == null || agentParticipant == null || agentParticipant.definitionId == null)\n throw new Error('Final platform context requires a Final conversation');\n return {\n final: {\n post: async (message) => {\n if (ctx.platform.conversations.dispatchMessage == null)\n throw new Error('channel dispatch is unavailable');\n const posted = await ctx.platform.conversations.postMessage({\n conversationId: conversation.conversationId,\n authorParticipantId: agentParticipant.id,\n content: contentBlocksOf(message.content),\n clientMessageId: `channel:${ctx.turn.id}:${message.id}`,\n originTurnId: ctx.turn.id,\n });\n await ctx.platform.conversations.dispatchMessage({\n conversationId: posted.conversationId,\n messageId: posted.messageId,\n });\n return posted;\n },\n },\n };\n };\n const sessionContext = (ctx: ProjectionContextIface): FinalSessionContextIface => ({\n sessionId: ctx.sessionId ?? null,\n turnId: ctx.turn.id,\n state: ctx.state,\n });\n const wrap = <Data>(\n schema: z.ZodType<Data>,\n handler: FinalChannelEventHandler<Data> | undefined,\n ): RoomEventHandler | undefined =>\n handler == null\n ? undefined\n : async (event, ctx) =>\n handler(schema.parse(event.data), channelContext(ctx), sessionContext(ctx));\n const authoredEvents = {\n [SemanticChannelEventKind.MessageCompleted]: wrap(\n channelMessageCompletedSchema,\n options.events?.['message.completed'],\n ),\n [SemanticChannelEventKind.MessageDelta]: wrap(\n z.object({ messageId: z.string(), delta: jsonObjectSchema }),\n options.events?.['message.delta'],\n ),\n [SemanticChannelEventKind.TurnStarted]: wrap(\n z.object({ turnId: z.string() }),\n options.events?.['turn.started'],\n ),\n [SemanticChannelEventKind.TurnCompleted]: wrap(\n z.object({ turnId: z.string(), stopReason: z.string().nullable() }),\n options.events?.['turn.completed'],\n ),\n 'decision.created': wrap(decisionCreatedDataSchema, options.events?.['decision.created']),\n 'decision.resolved': wrap(decisionResolvedDataSchema, options.events?.['decision.resolved']),\n };\n const events = { ...base.events };\n for (const [kind, handler] of Object.entries(authoredEvents))\n if (handler != null) events[kind] = handler;\n return Object.freeze(\n defineRoomSurface({\n ...base,\n config: jsonObjectSchema.parse(config),\n configure: (next) =>\n finalChannel({ ...options, ...optionsSchema.parse({ ...config, ...next }) }),\n receive,\n respond: async (input, ctx) => {\n const conversation = z.string().min(1).parse(ctx.conversationId);\n const participants = await ctx.platform.conversations.participants(conversation);\n const author = participants.find(\n (participant) => participant.id === input.actorParticipantId,\n );\n const defaultAuth = defaultAuthOf(author);\n let admission: ChannelAdmissionIface = { auth: defaultAuth };\n if (options.onInputResponse != null) {\n const accepted = await options.onInputResponse({ ...ctx, defaultAuth }, input);\n if (accepted == null) return { resolved: false };\n admission = admissionSchema.parse(accepted);\n }\n if (ctx.platform.sessions.respond == null)\n throw new Error('response submission is unavailable');\n return ctx.platform.sessions.respond({ ...input, auth: admission.auth });\n },\n cancel: async (ctx) => {\n if (ctx.agentParticipantId == null) return { accepted: false };\n const conversation = z.string().min(1).parse(ctx.conversationId);\n const participants = await ctx.platform.conversations.participants(conversation);\n const agent = participants.find((participant) => participant.id === ctx.agentParticipantId);\n if (agent?.sessionId == null) return { accepted: false };\n await ctx.platform.sessions.cancel({\n participantId: agent.id,\n reason: ctx.cancelReason,\n throughMessageSeq: ctx.cancelThroughMessageSeq,\n });\n return { accepted: true };\n },\n project: async (update, ctx) => {\n const next = () =>\n options.events?.['message.completed'] == null\n ? base.project(update, ctx)\n : Promise.resolve();\n if (options.renderer != null) {\n await options.renderer(update, channelContext(ctx), sessionContext(ctx), next);\n return;\n }\n await next();\n },\n events: Object.freeze(events),\n }),\n );\n};\n"],
5
- "mappings": "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",
6
- "names": ["RoomPrincipalType"]
7
- }
@@ -1,6 +0,0 @@
1
- import type { ContentBlock } from '@agentclientprotocol/sdk/experimental/v2';
2
- import { type JsonObject, type JsonValue } from '@finalai/agent-provider';
3
- export declare const contentBlockOf: (value: JsonValue | undefined) => ContentBlock | null;
4
- export declare const contentBlocksOf: (value: JsonValue | undefined) => ContentBlock[];
5
- export declare const jsonOfContentBlock: (block: ContentBlock) => JsonObject;
6
- export declare const jsonOfContent: (content: ContentBlock[]) => JsonObject[];
@@ -1,31 +0,0 @@
1
- import { contentBlockSchemas, ContentBlockType } from "@finalai/acp-session";
2
- import { jsonObjectSchema } from "@finalai/agent-provider";
3
- const contentBlockOf = (value) => {
4
- if (value == null) {
5
- return null;
6
- }
7
- const text = contentBlockSchemas[ContentBlockType.Text].safeParse(value);
8
- if (text.success) return text.data;
9
- const image = contentBlockSchemas[ContentBlockType.Image].safeParse(value);
10
- if (image.success) return image.data;
11
- const audio = contentBlockSchemas[ContentBlockType.Audio].safeParse(value);
12
- if (audio.success) return audio.data;
13
- const link = contentBlockSchemas[ContentBlockType.ResourceLink].safeParse(value);
14
- if (link.success) return link.data;
15
- const resource = contentBlockSchemas[ContentBlockType.Resource].safeParse(value);
16
- if (resource.success) return resource.data;
17
- return null;
18
- };
19
- const contentBlocksOf = (value) => Array.isArray(value) ? value.flatMap((item) => contentBlockOf(item) ?? []) : [];
20
- const jsonOfContentBlock = (block) => {
21
- const parsed = jsonObjectSchema.safeParse(JSON.parse(JSON.stringify(block)));
22
- return parsed.success ? parsed.data : { type: "text", text: "" };
23
- };
24
- const jsonOfContent = (content) => content.map(jsonOfContentBlock);
25
- export {
26
- contentBlockOf,
27
- contentBlocksOf,
28
- jsonOfContent,
29
- jsonOfContentBlock
30
- };
31
- //# sourceMappingURL=content.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../src/channels/content.ts"],
4
- "sourcesContent": ["import type { ContentBlock } from '@agentclientprotocol/sdk/experimental/v2';\nimport { contentBlockSchemas, ContentBlockType } from '@finalai/acp-session';\nimport { jsonObjectSchema, type JsonObject, type JsonValue } from '@finalai/agent-provider';\n\n// Content blocks cross JSON boundaries (Postgres jsonb, projection state, wire\n// bodies). Only the standard ACP block types survive the trip back; custom\n// `_`-prefixed blocks are dropped rather than trusted.\nexport const contentBlockOf = (value: JsonValue | undefined): ContentBlock | null => {\n if (value == null) {\n return null;\n }\n const text = contentBlockSchemas[ContentBlockType.Text].safeParse(value);\n if (text.success) return text.data;\n const image = contentBlockSchemas[ContentBlockType.Image].safeParse(value);\n if (image.success) return image.data;\n const audio = contentBlockSchemas[ContentBlockType.Audio].safeParse(value);\n if (audio.success) return audio.data;\n const link = contentBlockSchemas[ContentBlockType.ResourceLink].safeParse(value);\n if (link.success) return link.data;\n const resource = contentBlockSchemas[ContentBlockType.Resource].safeParse(value);\n if (resource.success) return resource.data;\n return null;\n};\n\nexport const contentBlocksOf = (value: JsonValue | undefined): ContentBlock[] =>\n Array.isArray(value) ? value.flatMap((item) => contentBlockOf(item) ?? []) : [];\n\nexport const jsonOfContentBlock = (block: ContentBlock): JsonObject => {\n const parsed = jsonObjectSchema.safeParse(JSON.parse(JSON.stringify(block)));\n return parsed.success ? parsed.data : { type: 'text', text: '' };\n};\n\nexport const jsonOfContent = (content: ContentBlock[]): JsonObject[] =>\n content.map(jsonOfContentBlock);\n"],
5
- "mappings": "AACA,SAAS,qBAAqB,wBAAwB;AACtD,SAAS,wBAAyD;AAK3D,MAAM,iBAAiB,CAAC,UAAsD;AACnF,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,EACT;AACA,QAAM,OAAO,oBAAoB,iBAAiB,IAAI,EAAE,UAAU,KAAK;AACvE,MAAI,KAAK,QAAS,QAAO,KAAK;AAC9B,QAAM,QAAQ,oBAAoB,iBAAiB,KAAK,EAAE,UAAU,KAAK;AACzE,MAAI,MAAM,QAAS,QAAO,MAAM;AAChC,QAAM,QAAQ,oBAAoB,iBAAiB,KAAK,EAAE,UAAU,KAAK;AACzE,MAAI,MAAM,QAAS,QAAO,MAAM;AAChC,QAAM,OAAO,oBAAoB,iBAAiB,YAAY,EAAE,UAAU,KAAK;AAC/E,MAAI,KAAK,QAAS,QAAO,KAAK;AAC9B,QAAM,WAAW,oBAAoB,iBAAiB,QAAQ,EAAE,UAAU,KAAK;AAC/E,MAAI,SAAS,QAAS,QAAO,SAAS;AACtC,SAAO;AACT;AAEO,MAAM,kBAAkB,CAAC,UAC9B,MAAM,QAAQ,KAAK,IAAI,MAAM,QAAQ,CAAC,SAAS,eAAe,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC;AAEzE,MAAM,qBAAqB,CAAC,UAAoC;AACrE,QAAM,SAAS,iBAAiB,UAAU,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC,CAAC;AAC3E,SAAO,OAAO,UAAU,OAAO,OAAO,EAAE,MAAM,QAAQ,MAAM,GAAG;AACjE;AAEO,MAAM,gBAAgB,CAAC,YAC5B,QAAQ,IAAI,kBAAkB;",
6
- "names": []
7
- }
@@ -1,54 +0,0 @@
1
- import { Delivery, TurnPolicy, type RoomPlatformIface, type ConversationIface, type ConversationMessageIface, type ParticipantIface, type RouteArgsIface, type RouteDecisionIface } from '@finalai/agent-provider';
2
- export declare const CONTEXT_WINDOW_MESSAGES = 50;
3
- export interface DeliveryOutcomeIface {
4
- participantId: string;
5
- delivery: Delivery;
6
- sent: 'prompt' | 'observe' | 'silent-prompt' | 'skipped' | 'failed';
7
- messageId: string | null;
8
- error: string | null;
9
- }
10
- export interface DeliverMessageArgsIface {
11
- platform: RoomPlatformIface;
12
- route: (args: RouteArgsIface) => RouteDecisionIface[] | Promise<RouteDecisionIface[]>;
13
- conversation: ConversationIface;
14
- message: ConversationMessageIface;
15
- participants?: ParticipantIface[];
16
- turnPolicy: TurnPolicy;
17
- }
18
- export declare const effectiveTurnPolicy: (args: {
19
- channel: TurnPolicy;
20
- conversation: TurnPolicy;
21
- }) => TurnPolicy;
22
- export declare const humanAudience: (participants: ParticipantIface[]) => string[];
23
- export declare const audienceFor: (author: ParticipantIface | null, participants: ParticipantIface[]) => string[];
24
- export declare const deliveryIdempotencyKey: (messageId: string, participantId: string) => string;
25
- export declare const deliverMessage: (args: DeliverMessageArgsIface) => Promise<DeliveryOutcomeIface[]>;
26
- export interface ObserveNoticeArgsIface {
27
- platform: RoomPlatformIface;
28
- recipients: ParticipantIface[];
29
- text: string;
30
- idempotencyKey: string;
31
- }
32
- export declare const observeNotice: (args: ObserveNoticeArgsIface) => Promise<string[]>;
33
- export interface ReactionNoticeArgsIface {
34
- platform: RoomPlatformIface;
35
- participants: ParticipantIface[];
36
- message: ConversationMessageIface;
37
- isLatestOfAuthor: boolean;
38
- reactorParticipantId: string;
39
- emoji: string;
40
- eventId?: string;
41
- }
42
- export declare const reactionNotice: (args: ReactionNoticeArgsIface) => Promise<string[]>;
43
- export declare enum MembershipChange {
44
- Joined = "joined",
45
- Left = "left"
46
- }
47
- export interface MembershipNoticeArgsIface {
48
- platform: RoomPlatformIface;
49
- participants: ParticipantIface[];
50
- subject: ParticipantIface;
51
- change: MembershipChange;
52
- idempotencyKey: string;
53
- }
54
- export declare const membershipNotice: (args: MembershipNoticeArgsIface) => Promise<string[]>;
@@ -1,243 +0,0 @@
1
- import {
2
- Delivery,
3
- ParticipantKind,
4
- RoutingMode,
5
- TurnPolicy
6
- } from "@finalai/agent-provider";
7
- import * as z from "zod";
8
- import {
9
- authorPrefixedContent,
10
- buildPromptContent,
11
- catchUpFor,
12
- excerpt,
13
- finalAuthorOf,
14
- finalContextOf,
15
- messageRefOf,
16
- messageSummary,
17
- renderReplyContext,
18
- systemNoticeBlock
19
- } from "./prompt.mjs";
20
- import { MAX_AGENT_HOP_DEPTH } from "./routing.mjs";
21
- const thrownMessageSchema = z.object({ message: z.string() });
22
- const CONTEXT_WINDOW_MESSAGES = 50;
23
- const effectiveTurnPolicy = (args) => args.conversation === TurnPolicy.Queue ? TurnPolicy.Queue : args.channel;
24
- const humanAudience = (participants) => participants.filter((participant) => !participant.left && participant.kind === ParticipantKind.User).map((participant) => participant.id);
25
- const audienceFor = (author, participants) => author?.kind === ParticipantKind.User ? [author.id] : humanAudience(participants);
26
- const replyContextFor = async (args) => {
27
- const byId = new Map(args.earlier.map((message) => [message.messageId, message]));
28
- const referenced = [
29
- args.message.replyToMessageId,
30
- args.message.threadRootId,
31
- ...args.message.quotedMessageIds
32
- ].flatMap((id) => id == null || byId.has(id) ? [] : [id]);
33
- if (referenced.length > 0) {
34
- const found = await args.platform.conversations.getMessages({
35
- conversationId: args.message.conversationId,
36
- messageIds: [...new Set(referenced)]
37
- });
38
- for (const message of found) byId.set(message.messageId, message);
39
- }
40
- const replyTo = args.message.replyToMessageId == null ? null : byId.get(args.message.replyToMessageId) ?? null;
41
- const root = args.message.threadRootId == null ? null : byId.get(args.message.threadRootId) ?? null;
42
- const rootAuthor = root == null ? null : args.participants.find((participant) => participant.id === root.authorParticipantId);
43
- return {
44
- replyTo: replyTo == null || replyTo.messageId === root?.messageId ? null : messageRefOf(replyTo, args.participants),
45
- thread: args.message.threadRootId == null ? null : {
46
- rootMessageId: args.message.threadRootId,
47
- rootExcerpt: root == null ? "" : excerpt(messageSummary(root.content)),
48
- rootAuthor: rootAuthor == null ? null : finalAuthorOf(rootAuthor)
49
- },
50
- quotes: args.message.quotedMessageIds.flatMap((id) => {
51
- const quoted = byId.get(id);
52
- return quoted == null ? [] : [messageRefOf(quoted, args.participants)];
53
- })
54
- };
55
- };
56
- const deliveryIdempotencyKey = (messageId, participantId) => `${messageId}:${participantId}`;
57
- const deliverMessage = async (args) => {
58
- const { platform, conversation, message } = args;
59
- const participants = args.participants ?? await platform.conversations.participants(conversation.conversationId);
60
- const decisions = await args.route({ conversation, message, participants });
61
- const author = participants.find((participant) => participant.id === message.authorParticipantId) ?? null;
62
- for (const participant of participants) {
63
- if (participant.kind !== ParticipantKind.Agent) continue;
64
- const decision = decisions.find((candidate) => candidate.participantId === participant.id);
65
- platform.log("channel route decision", {
66
- observed_at: (/* @__PURE__ */ new Date()).toISOString(),
67
- organization_id: conversation.organizationId,
68
- conversation_id: conversation.conversationId,
69
- conversation_kind: conversation.kind,
70
- message_id: message.messageId,
71
- author_kind: author?.kind ?? "",
72
- participant_id: participant.id,
73
- routing_mode: participant.routingMode ?? "",
74
- delivery: decision?.delivery ?? "skipped",
75
- reason: participant.left ? "left conversation" : participant.id === message.authorParticipantId ? "author" : decision == null ? "not selected by route" : "selected by route",
76
- hop_depth: message.hopDepth
77
- });
78
- }
79
- if (decisions.length === 0) return [];
80
- const earlier = await platform.conversations.recentMessages({
81
- conversationId: conversation.conversationId,
82
- limit: CONTEXT_WINDOW_MESSAGES,
83
- beforeSeq: message.seq
84
- });
85
- const replyContext = await replyContextFor({ platform, message, earlier, participants });
86
- const turnPolicy = effectiveTurnPolicy({
87
- channel: args.turnPolicy,
88
- conversation: conversation.turnPolicy
89
- });
90
- const audience = audienceFor(author, participants);
91
- const authorParticipant = author ?? {
92
- id: message.authorParticipantId,
93
- kind: ParticipantKind.User,
94
- displayName: "Someone",
95
- userId: null,
96
- definitionId: null,
97
- routingMode: null,
98
- sessionId: null,
99
- supportsObserve: null,
100
- rendersAuthorMeta: null,
101
- left: true
102
- };
103
- const deliverOne = async (decision) => {
104
- const recipient = participants.find((participant) => participant.id === decision.participantId);
105
- const base = { participantId: decision.participantId, delivery: decision.delivery };
106
- if (recipient == null) {
107
- return { ...base, sent: "skipped", messageId: null, error: null };
108
- }
109
- const idempotencyKey = deliveryIdempotencyKey(message.messageId, recipient.id);
110
- const prompt = async (content, replyExpected) => {
111
- const result = await platform.sessions.prompt({
112
- participantId: recipient.id,
113
- content,
114
- turnPolicy,
115
- replyExpected,
116
- idempotencyKey,
117
- authorParticipantId: message.authorParticipantId,
118
- audienceParticipantIds: audience,
119
- sourceMessageId: message.messageId
120
- });
121
- return result.messageId;
122
- };
123
- try {
124
- if (decision.delivery === Delivery.Prompt) {
125
- const content2 = buildPromptContent({
126
- message,
127
- author: authorParticipant,
128
- recipient,
129
- replyContext,
130
- catchUp: catchUpFor({ recipient, earlier, participants })
131
- });
132
- return { ...base, sent: "prompt", messageId: await prompt(content2, true), error: null };
133
- }
134
- if (recipient.sessionId == null) {
135
- return { ...base, sent: "skipped", messageId: null, error: null };
136
- }
137
- const contextBlock = renderReplyContext(replyContext);
138
- const content = [
139
- ...contextBlock == null ? [] : [contextBlock],
140
- ...authorPrefixedContent({
141
- content: message.content,
142
- author: finalAuthorOf(authorParticipant),
143
- rendersAuthorMeta: recipient.rendersAuthorMeta ?? false,
144
- context: finalContextOf(replyContext)
145
- })
146
- ];
147
- if (recipient.supportsObserve === false) {
148
- if (message.hopDepth >= MAX_AGENT_HOP_DEPTH) {
149
- return { ...base, sent: "skipped", messageId: null, error: null };
150
- }
151
- return {
152
- ...base,
153
- sent: "silent-prompt",
154
- messageId: await prompt(content, false),
155
- error: null
156
- };
157
- }
158
- await platform.sessions.observe({ participantId: recipient.id, content, idempotencyKey });
159
- return { ...base, sent: "observe", messageId: null, error: null };
160
- } catch (error) {
161
- const reason = error instanceof Error ? error.message : thrownMessageSchema.safeParse(error).data?.message ?? String(error);
162
- platform.log("channel delivery failed", {
163
- conversationId: conversation.conversationId,
164
- messageId: message.messageId,
165
- participantId: recipient.id,
166
- delivery: decision.delivery,
167
- error: reason
168
- });
169
- return { ...base, sent: "failed", messageId: null, error: reason };
170
- }
171
- };
172
- return Promise.all(decisions.map(deliverOne));
173
- };
174
- const observeNotice = async (args) => {
175
- const delivered = [];
176
- for (const recipient of args.recipients) {
177
- if (recipient.sessionId == null || recipient.supportsObserve === false || recipient.left)
178
- continue;
179
- try {
180
- await args.platform.sessions.observe({
181
- participantId: recipient.id,
182
- content: [systemNoticeBlock({ text: args.text })],
183
- idempotencyKey: `${args.idempotencyKey}:${recipient.id}`
184
- });
185
- delivered.push(recipient.id);
186
- } catch (error) {
187
- args.platform.log("channel notice failed", {
188
- participantId: recipient.id,
189
- error: error instanceof Error ? error.message : String(error)
190
- });
191
- }
192
- }
193
- return delivered;
194
- };
195
- const reactionNotice = async (args) => {
196
- const author = args.participants.find(
197
- (participant) => participant.id === args.message.authorParticipantId
198
- );
199
- const reactor = args.participants.find(
200
- (participant) => participant.id === args.reactorParticipantId
201
- );
202
- if (author == null || author.kind !== ParticipantKind.Agent || reactor == null || reactor.id === author.id) {
203
- return [];
204
- }
205
- const target = args.isLatestOfAuthor ? "your last message" : `your message "${excerpt(messageSummary(args.message.content), 120)}"`;
206
- const reactionId = `reaction:${args.message.messageId}:${reactor.id}:${args.emoji}`;
207
- return observeNotice({
208
- platform: args.platform,
209
- recipients: [author],
210
- text: `${reactor.displayName} reacted ${args.emoji} to ${target}`,
211
- idempotencyKey: args.eventId == null ? reactionId : `${reactionId}:${args.eventId}`
212
- });
213
- };
214
- var MembershipChange = /* @__PURE__ */ ((MembershipChange2) => {
215
- MembershipChange2["Joined"] = "joined";
216
- MembershipChange2["Left"] = "left";
217
- return MembershipChange2;
218
- })(MembershipChange || {});
219
- const membershipNotice = async (args) => {
220
- const recipients = args.participants.filter(
221
- (participant) => participant.kind === ParticipantKind.Agent && participant.id !== args.subject.id && (participant.routingMode === RoutingMode.All || participant.routingMode === RoutingMode.Default)
222
- );
223
- const verb = args.change === "joined" /* Joined */ ? "joined" : "left";
224
- return observeNotice({
225
- platform: args.platform,
226
- recipients,
227
- text: `${args.subject.displayName} ${verb} the conversation`,
228
- idempotencyKey: args.idempotencyKey
229
- });
230
- };
231
- export {
232
- CONTEXT_WINDOW_MESSAGES,
233
- MembershipChange,
234
- audienceFor,
235
- deliverMessage,
236
- deliveryIdempotencyKey,
237
- effectiveTurnPolicy,
238
- humanAudience,
239
- membershipNotice,
240
- observeNotice,
241
- reactionNotice
242
- };
243
- //# sourceMappingURL=delivery.mjs.map