@finalai/final-agent-provider 0.6.2 → 0.7.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 (94) hide show
  1. package/HOSTING.md +4 -4
  2. package/README.md +94 -2
  3. package/dist/modules/authoring-final-channel.mjs +2 -2
  4. package/dist/modules/authoring-final-channel.mjs.map +2 -2
  5. package/dist/modules/channel-factories.d.mts +5 -7
  6. package/dist/modules/channel-factories.mjs +4 -50
  7. package/dist/modules/channel-factories.mjs.map +2 -2
  8. package/dist/modules/channels/channel-utils.d.mts +132 -0
  9. package/dist/modules/channels/channel-utils.mjs +445 -0
  10. package/dist/modules/channels/channel-utils.mjs.map +7 -0
  11. package/dist/modules/channels/delivery.d.mts +5 -5
  12. package/dist/modules/channels/delivery.mjs.map +1 -1
  13. package/dist/modules/channels/direct-messaging.d.mts +2 -2
  14. package/dist/modules/channels/direct-messaging.mjs.map +2 -2
  15. package/dist/modules/channels/discord-dispatch.d.mts +17 -0
  16. package/dist/modules/channels/discord-dispatch.mjs +139 -0
  17. package/dist/modules/channels/discord-dispatch.mjs.map +7 -0
  18. package/dist/modules/channels/discord-gateway.d.mts +19 -0
  19. package/dist/modules/channels/discord-gateway.mjs +233 -0
  20. package/dist/modules/channels/discord-gateway.mjs.map +7 -0
  21. package/dist/modules/channels/discord.d.mts +9 -0
  22. package/dist/modules/channels/discord.mjs +904 -0
  23. package/dist/modules/channels/discord.mjs.map +7 -0
  24. package/dist/modules/channels/fake-platform.d.mts +2 -7
  25. package/dist/modules/channels/fake-platform.mjs +2 -38
  26. package/dist/modules/channels/fake-platform.mjs.map +2 -2
  27. package/dist/modules/channels/github.d.mts +5 -0
  28. package/dist/modules/channels/github.mjs +720 -0
  29. package/dist/modules/channels/github.mjs.map +7 -0
  30. package/dist/modules/channels/group-messaging.d.mts +2 -2
  31. package/dist/modules/channels/group-messaging.mjs.map +2 -2
  32. package/dist/modules/channels/index.d.mts +7 -3
  33. package/dist/modules/channels/index.mjs +7 -3
  34. package/dist/modules/channels/index.mjs.map +2 -2
  35. package/dist/modules/channels/linear.d.mts +4 -0
  36. package/dist/modules/channels/linear.mjs +621 -0
  37. package/dist/modules/channels/linear.mjs.map +7 -0
  38. package/dist/modules/channels/messaging-channel.d.mts +3 -3
  39. package/dist/modules/channels/messaging-channel.mjs +2 -2
  40. package/dist/modules/channels/messaging-channel.mjs.map +2 -2
  41. package/dist/modules/channels/phone.d.mts +8 -0
  42. package/dist/modules/channels/phone.mjs +382 -0
  43. package/dist/modules/channels/phone.mjs.map +7 -0
  44. package/dist/modules/channels/projection.mjs.map +1 -1
  45. package/dist/modules/channels/reply-receipts.d.mts +31 -0
  46. package/dist/modules/channels/reply-receipts.mjs +63 -0
  47. package/dist/modules/channels/reply-receipts.mjs.map +7 -0
  48. package/dist/modules/channels/routing.d.mts +1 -0
  49. package/dist/modules/channels/routing.mjs +5 -1
  50. package/dist/modules/channels/routing.mjs.map +2 -2
  51. package/dist/modules/channels/slack.d.mts +7 -0
  52. package/dist/modules/channels/slack.mjs +1134 -0
  53. package/dist/modules/channels/slack.mjs.map +7 -0
  54. package/dist/modules/channels/voice-recording.d.mts +7 -0
  55. package/dist/modules/channels/voice-recording.mjs +49 -0
  56. package/dist/modules/channels/voice-recording.mjs.map +7 -0
  57. package/dist/modules/channels/voice.d.mts +33 -0
  58. package/dist/modules/channels/voice.mjs +851 -0
  59. package/dist/modules/channels/voice.mjs.map +7 -0
  60. package/dist/modules/channels/webhook.d.mts +5 -0
  61. package/dist/modules/channels/webhook.mjs +76 -0
  62. package/dist/modules/channels/webhook.mjs.map +7 -0
  63. package/dist/modules/harnesses/acp-describe.mjs +1 -1
  64. package/dist/modules/harnesses/acp-describe.mjs.map +2 -2
  65. package/dist/modules/harnesses/config-fields.d.mts +6 -1
  66. package/dist/modules/harnesses/config-fields.mjs +7 -0
  67. package/dist/modules/harnesses/config-fields.mjs.map +3 -3
  68. package/dist/modules/harnesses/fidelity.mjs +17 -17
  69. package/dist/modules/harnesses/fidelity.mjs.map +2 -2
  70. package/dist/modules/harnesses/remote-claude-code.d.mts +14 -2
  71. package/dist/modules/harnesses/remote-claude-code.mjs +5 -3
  72. package/dist/modules/harnesses/remote-claude-code.mjs.map +2 -2
  73. package/dist/modules/harnesses/remote-url.mjs.map +1 -1
  74. package/dist/modules/harnesses/serverless-nanocode-codex.d.mts +3 -1
  75. package/dist/modules/harnesses/serverless-nanocode-codex.mjs +6 -0
  76. package/dist/modules/harnesses/serverless-nanocode-codex.mjs.map +2 -2
  77. package/dist/modules/runtime/remote-host.mjs.map +1 -1
  78. package/dist/modules/sandboxes/build-scripts.mjs.map +1 -1
  79. package/dist/modules/sandboxes/paths.mjs.map +1 -1
  80. package/dist/modules/testing/harness.mjs +2 -2
  81. package/dist/modules/testing/harness.mjs.map +1 -1
  82. package/package.json +45 -19
  83. package/dist/modules/channels/address-context.d.mts +0 -7
  84. package/dist/modules/channels/address-context.mjs +0 -80
  85. package/dist/modules/channels/address-context.mjs.map +0 -7
  86. package/dist/modules/channels/agent-events.d.mts +0 -103
  87. package/dist/modules/channels/agent-events.mjs +0 -341
  88. package/dist/modules/channels/agent-events.mjs.map +0 -7
  89. package/dist/modules/channels/agent-schedules.d.mts +0 -25
  90. package/dist/modules/channels/agent-schedules.mjs +0 -96
  91. package/dist/modules/channels/agent-schedules.mjs.map +0 -7
  92. package/dist/modules/channels/service-input.d.mts +0 -22
  93. package/dist/modules/channels/service-input.mjs +0 -32
  94. package/dist/modules/channels/service-input.mjs.map +0 -7
package/HOSTING.md CHANGED
@@ -240,7 +240,7 @@ before running. Shared manifest resolution rejects null results for required slo
240
240
  even if a host catches a resolver exception and returns null. Hosts must propagate
241
241
  that failure to startup. Session-started values stay pinned across turns and resume.
242
242
 
243
- This PR adds no configuration UI. A host can use the compiled requirements to show
243
+ Hosts can use the compiled requirements to show
244
244
  which names need configuration and return an actionable deployment-specific error.
245
245
 
246
246
  ## Host integration
@@ -269,6 +269,6 @@ Optional readers preserve source compatibility with existing hosts. Definitions
269
269
  requesting bindings fail clearly if hosting does not provide them. Installing these
270
270
  packages alone does not change Final's deployed service wiring or provision secrets.
271
271
 
272
- New compiles emit manifest version 3, so older hosts reject them rather than
273
- stripping required-binding metadata. Updated readers still accept persisted
274
- version 2 revisions. Upgrade hosting before publishing newly compiled agents.
272
+ New compiles emit manifest version 4. Hosts and stored revisions must use v4;
273
+ recompile older definitions before loading them. Upgrade hosting before
274
+ publishing newly compiled agents.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @finalai/final-agent-provider
2
2
 
3
- Pure configuration helpers for Final harnesses, computer/device sandboxes, and
4
- channels. Import helpers from `/harnesses`, `/sandboxes`, or `/channels/final`.
3
+ Provider helpers for harnesses, computer and device sandboxes, the Final room, and
4
+ external channels. Import helpers from `/harnesses`, `/sandboxes`, or `/channels/final`.
5
5
  `/connections` provides `defineFinalConnection` for session-scoped Final MCP access.
6
6
 
7
7
  Optional Node ACP adapters are exposed under `/runtime/*`. Sandbox adapters use
@@ -41,3 +41,95 @@ In 0.4, passive Computer recovery follows the read-only viewer contract even wit
41
41
  a networking extension. Use ordinary resume for execution. The bundled adapters
42
42
  cache deferred setup failures per handle; reconnect to retry rather than replaying
43
43
  partially completed user setup commands on each MCP poll.
44
+
45
+ ## Provider channels
46
+
47
+ Use the same provider package with your own app or a shared installation:
48
+
49
+ ```ts
50
+ import { slackChannel } from '@finalai/final-agent-provider/channels/slack';
51
+ export default slackChannel();
52
+ ```
53
+
54
+ Factories also exist for Discord, GitHub, Linear, authenticated webhooks, voice,
55
+ and Twilio phone calls. Slack uses a separate OpenID identity flow; Linear uses
56
+ `actor=user` for identity proof and `actor=app` for application installation.
57
+ Provider principals are never matched by email. Slack Enterprise Grid principals
58
+ use the enterprise user/enterprise namespace when available.
59
+
60
+ Slack installs are scoped to a workspace, including workspaces in Enterprise Grid. Organization-wide installs with no workspace claim are rejected; install the app in each workspace that should connect. Discord guilds share the installed application bot token. Slack group direct messages are not subscribed; use a direct message or mention the app in a workspace channel.
61
+
62
+ Slack and Discord default to `history: 'none'`. Opt into `linked-members` to send
63
+ only currently linked members' thread history to the agent. Shared places default
64
+ to member-only input and origin-only replies. Configure `replies: all` explicitly
65
+ to mirror the chat. Provider signature verification is required on `/webhook`;
66
+ Discord also maintains a Gateway listener without the privileged message-content
67
+ intent. Requests must still fit the provider application's installed scopes.
68
+
69
+ `webhookChannel({secret})` verifies `X-Final-Signature: sha256=<HMAC hex>` over the
70
+ raw body. Its envelope is `{place,label,content,idempotencyKey,context?}`. Connect
71
+ its place before delivering events. Retries reuse the event's idempotency key.
72
+
73
+ `voiceChannel()` verifies a Final OAuth identity with PKCE, then serves `/stream`.
74
+ A JSON `start` frame selects PCM16 at 16 kHz and the authenticated principal;
75
+ binary frames carry microphone samples. `cancel` interrupts a turn and `stop`
76
+ finishes input while output drains. Only `speech.end` with `final: true` marks
77
+ the drained terminal response; per-turn ends use `final: false`. Server frames report transcripts, speech
78
+ boundaries, stage timestamps and errors, interleaved with binary PCM output.
79
+ An `error` with `recoverable: true` is advisory; other error frames are terminal.
80
+ A `notice` ends microphone capture while its spoken explanation drains. Stop
81
+ sending audio, display the notice and continue playback until the terminal
82
+ `speech.end`, including when the server ends the call without a client `stop`.
83
+ Only final utterances are posted. Once-only permission choices and empty-schema
84
+ confirmations can be answered by voice; other forms remain in Final. When recording is enabled, the channel attaches recordings without starting another turn.
85
+ Clients opt in to recording in the start frame after displaying the recording notice.
86
+ Saved recordings are PCM16 WAV attachments, split below 10 MiB including base64 serialization.
87
+
88
+ `phoneChannel({accountSid,fromNumber})` adapts the same core to signed Twilio call
89
+ webhooks and 8 kHz mu-law streams. It uses the declared `twilio-auth-token` secret
90
+ and an SMS challenge for identity. An unlinked member caller receives the account-link
91
+ URL by SMS, signs in and verifies their number, then calls again. Each linked call also requires a fresh SMS code
92
+ entered on the call; caller ID alone cannot act as a member. Configure `audience:'anyone'` explicitly for
93
+ anonymous support calls; those calls use captioned input and group defaults.
94
+
95
+ Provider delivery receipts expire after 90 days; later provider edits may no longer find their original delivery.
96
+ Provider mutation support varies: Slack, Discord and GitHub update bot-owned
97
+ replies. Linear activities are emitted as separate entries and are not edited by
98
+ this adapter. GitHub has no inbound reaction
99
+ webhook. Final room customization remains `finalChannel` from `/channels/final`.
100
+
101
+ Slack direct-message replies stay in a thread under the original request, so each
102
+ reply, edit and reaction remains associated with its source message. Approvals
103
+ show the requested action and the provider's one-time option names. Ambiguous
104
+ spoken answers and decisions that require a form must be answered in Final;
105
+ channels do not offer permanent approval choices.
106
+
107
+ Slack Grid workspace removals revoke that workspace's routes and identities. An
108
+ enterprise identity remains linked while another workspace has successfully
109
+ proven an active grant. Tracking is bounded to 256 workspaces per enterprise;
110
+ overflow conservatively requires enterprise identities to link again after the
111
+ next workspace removal. Phone verification requests use a per-number cooldown.
112
+
113
+ Configure Slack's `/final` slash command and interactivity callback in your app
114
+ settings. Register Discord's `/final` application command with `connect`,
115
+ `disconnect` and `unlink` subcommands. The SDK handles dispatched commands and
116
+ keeps your application's command registry under your control.
117
+
118
+ `replies: all` mirrors new messages. Slack, Discord, and GitHub can edit or remove
119
+ existing copies and synchronize supported reactions while their delivery receipts
120
+ are retained. Missing or deleted copies are not recreated by later mutations.
121
+ Apps can modify only messages they own. The Linear adapter does not propagate
122
+ Final edits, removals, or reactions to its activity entries. Provider permissions
123
+ and receipt retention limit later synchronization.
124
+
125
+ Hosts that terminate TLS upstream must give channel routes the public request URL,
126
+ including its scheme; Twilio verifies the complete URL. Voice closes a connection
127
+ if pending microphone audio exceeds 2 MiB instead of retaining an unbounded queue.
128
+ Discord guild removal ends that guild's connections while preserving identity
129
+ proofs usable in other guilds or direct messages.
130
+
131
+ Discord guild history is limited to content the bot can read without privileged
132
+ message-content access, such as mentions; unavailable content is omitted. GitHub
133
+ installation suspension pauses incoming delivery without deleting connections;
134
+ unsuspending resumes it. Voice synthesizes text replies through the configured
135
+ speech service; audio attachments remain available in Final.
@@ -1,9 +1,9 @@
1
- import { defineProviderChannel } from "@finalai/agent-definition/authoring";
1
+ import { defineRoomSurface } from "@finalai/agent-definition/authoring";
2
2
  import {
3
3
  finalChannel as createFinalChannel
4
4
  } from "./channel-factories.mjs";
5
5
  export * from "./channel-factories.mjs";
6
- const finalChannel = (options = {}) => defineProviderChannel(createFinalChannel(options));
6
+ const finalChannel = (options = {}) => defineRoomSurface(createFinalChannel(options));
7
7
  export {
8
8
  finalChannel
9
9
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/authoring-final-channel.ts"],
4
- "sourcesContent": ["import { defineProviderChannel } from '@finalai/agent-definition/authoring';\nimport {\n finalChannel as createFinalChannel,\n type FinalChannelOptionsIface,\n} from \"./channel-factories.mjs\";\nexport * from \"./channel-factories.mjs\";\nexport const finalChannel = (\n options: FinalChannelOptionsIface = {},\n): ReturnType<typeof createFinalChannel> => defineProviderChannel(createFinalChannel(options));\n"],
5
- "mappings": "AAAA,SAAS,6BAA6B;AACtC;AAAA,EACE,gBAAgB;AAAA,OAEX;AACP,cAAc;AACP,MAAM,eAAe,CAC1B,UAAoC,CAAC,MACK,sBAAsB,mBAAmB,OAAO,CAAC;",
4
+ "sourcesContent": ["import { defineRoomSurface } from '@finalai/agent-definition/authoring';\nimport {\n finalChannel as createFinalChannel,\n type FinalChannelOptionsIface,\n} from \"./channel-factories.mjs\";\nexport * from \"./channel-factories.mjs\";\nexport const finalChannel = (\n options: FinalChannelOptionsIface = {},\n): ReturnType<typeof createFinalChannel> => defineRoomSurface(createFinalChannel(options));\n"],
5
+ "mappings": "AAAA,SAAS,yBAAyB;AAClC;AAAA,EACE,gBAAgB;AAAA,OAEX;AACP,cAAc;AACP,MAAM,eAAe,CAC1B,UAAoC,CAAC,MACK,kBAAkB,mBAAmB,OAAO,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,5 @@
1
1
  import type { SessionUpdate } from '@agentclientprotocol/sdk/experimental/v2';
2
- import { TurnPolicy, type ChannelAddressContextIface, type ChannelAuthIface, type ChannelDefinitionIface, type ChannelInputReceiptIface, type ChannelInputResponseIface, type ChannelMessageCompletedDataIface, type ChannelMessageDeltaDataIface, type ChannelReceiveContextIface, type ChannelTurnEventDataIface, type ChannelTurnStateIface, type ConversationMessageIface, type DecisionCreatedDataIface, type DecisionResolvedDataIface, type JsonValue } from '@finalai/agent-provider';
3
- import { type ServiceInputArgsIface } from "./channels/service-input.mjs";
2
+ import { TurnPolicy, type ChannelAuthIface, type RoomSurfaceDefinitionIface, type ChannelInputResponseIface, type ChannelMessageCompletedDataIface, type ChannelMessageDeltaDataIface, type RoomReceiveContextIface, type ChannelTurnEventDataIface, type ChannelTurnStateIface, type ConversationMessageIface, type DecisionCreatedDataIface, type DecisionResolvedDataIface, type JsonValue } from '@finalai/agent-provider';
4
3
  export declare const FINAL_CHANNEL_SPECIFIER = "@finalai/final-agent-provider/channels/final";
5
4
  export { ChannelPrincipalType, type ChannelAuthIface } from '@finalai/agent-provider';
6
5
  export interface ChannelAdmissionIface {
@@ -8,13 +7,12 @@ export interface ChannelAdmissionIface {
8
7
  context?: string[];
9
8
  title?: string;
10
9
  }
11
- export interface FinalMessageContextIface extends ChannelReceiveContextIface, ChannelAddressContextIface {
10
+ export interface FinalMessageContextIface extends RoomReceiveContextIface {
12
11
  defaultAuth: ChannelAuthIface | null;
13
12
  }
14
- export interface FinalChannelContextIface extends ChannelAddressContextIface {
13
+ export interface FinalChannelContextIface {
15
14
  final: {
16
15
  post(message: ChannelMessageCompletedDataIface['message']): Promise<ConversationMessageIface>;
17
- sendServiceInput(args: ServiceInputArgsIface): Promise<ChannelInputReceiptIface>;
18
16
  };
19
17
  }
20
18
  export interface FinalSessionContextIface {
@@ -34,10 +32,10 @@ export interface FinalChannelEventHandlersIface {
34
32
  export interface FinalChannelOptionsIface {
35
33
  turnPolicy?: TurnPolicy | `${TurnPolicy}`;
36
34
  updateIntervalMs?: number;
37
- route?: ChannelDefinitionIface<JsonValue, JsonValue>['route'];
35
+ route?: RoomSurfaceDefinitionIface<JsonValue, JsonValue>['route'];
38
36
  onMessage?: (ctx: FinalMessageContextIface, message: ConversationMessageIface) => ChannelAdmissionIface | null | Promise<ChannelAdmissionIface | null>;
39
37
  onInputResponse?: (ctx: FinalMessageContextIface, response: ChannelInputResponseIface) => ChannelAdmissionIface | null | Promise<ChannelAdmissionIface | null>;
40
38
  events?: FinalChannelEventHandlersIface;
41
39
  renderer?: (update: SessionUpdate, channel: FinalChannelContextIface, ctx: FinalSessionContextIface, next: () => Promise<void>) => void | Promise<void>;
42
40
  }
43
- export declare const finalChannel: (inputOptions?: FinalChannelOptionsIface) => ChannelDefinitionIface<JsonValue, JsonValue>;
41
+ export declare const finalChannel: (inputOptions?: FinalChannelOptionsIface) => RoomSurfaceDefinitionIface<JsonValue, JsonValue>;
@@ -2,21 +2,18 @@ import {
2
2
  ChannelPrincipalType,
3
3
  SemanticChannelEventKind,
4
4
  TurnPolicy,
5
- channelAccessors,
6
5
  channelAuthSchema,
7
6
  channelMessageCompletedSchema,
8
7
  decisionCreatedDataSchema,
9
8
  decisionResolvedDataSchema,
10
- defineChannel,
9
+ defineRoomSurface,
11
10
  jsonObjectSchema,
12
11
  packageRef
13
12
  } from "@finalai/agent-provider";
14
13
  import * as z from "zod";
15
- import { finalAddressContext } from "./channels/address-context.mjs";
16
14
  import { contentBlocksOf } from "./channels/content.mjs";
17
15
  import { conversationEventInboundSchema, messageInboundSchema } from "./channels/inbound.mjs";
18
16
  import { createMessagingChannel } from "./channels/messaging-channel.mjs";
19
- import { sendServiceInput } from "./channels/service-input.mjs";
20
17
  const FINAL_CHANNEL_SPECIFIER = "@finalai/final-agent-provider/channels/final";
21
18
  import { ChannelPrincipalType as ChannelPrincipalType2 } from "@finalai/agent-provider";
22
19
  const admissionSchema = z.object({
@@ -38,21 +35,6 @@ const defaultAuthOf = (author) => {
38
35
  attributes: { participant_id: author.id }
39
36
  };
40
37
  };
41
- const handoffSchema = z.object({
42
- target: z.object({
43
- conversationId: z.string().min(1),
44
- participantId: z.string().min(1).optional()
45
- }),
46
- content: z.array(jsonObjectSchema).min(1),
47
- idempotencyKey: z.string().min(1),
48
- auth: channelAuthSchema,
49
- context: z.array(z.string()).optional(),
50
- title: z.string().optional(),
51
- actingUserId: z.string().min(1).optional(),
52
- originTurnId: z.string().min(1).optional(),
53
- source: z.object({ label: z.string().min(1) }).optional(),
54
- turnPolicy: z.nativeEnum(TurnPolicy).optional()
55
- });
56
38
  const finalChannel = (inputOptions = {}) => {
57
39
  const options = {
58
40
  ...inputOptions,
@@ -82,20 +64,6 @@ const finalChannel = (inputOptions = {}) => {
82
64
  const base = createMessagingChannel({ ...config, route: options.route });
83
65
  const receive = async (input, ctx) => {
84
66
  if (conversationEventInboundSchema.safeParse(input).success) return base.receive(input, ctx);
85
- const handoff = handoffSchema.safeParse(input);
86
- if (handoff.success) {
87
- if (ctx.platform.channelSessions == null)
88
- throw new Error("channel session operations are unavailable");
89
- const { target, ...rest } = handoff.data;
90
- await ctx.platform.channelSessions.send(target, {
91
- ...rest,
92
- content: contentBlocksOf(rest.content),
93
- source: rest.source,
94
- // The sender's policy, else the receiving channel's.
95
- turnPolicy: rest.turnPolicy ?? config.turnPolicy
96
- });
97
- return { conversationId: target.conversationId };
98
- }
99
67
  const parsed = messageInboundSchema.parse(input);
100
68
  const participants = ctx.participants ?? await ctx.platform.conversations.participants(parsed.conversationId);
101
69
  const author = participants.find(
@@ -108,11 +76,6 @@ const finalChannel = (inputOptions = {}) => {
108
76
  if (ctx.definitionId == null) throw new Error("Final channel has no agent definition");
109
77
  const messageContext = {
110
78
  ...ctx,
111
- ...finalAddressContext({
112
- platform: ctx.platform,
113
- definitionId: ctx.definitionId,
114
- turnPolicy: config.turnPolicy
115
- }),
116
79
  defaultAuth: defaultAuthOf(author)
117
80
  };
118
81
  const accepted = options.onMessage == null ? { auth: messageContext.defaultAuth } : await options.onMessage(messageContext, message);
@@ -147,11 +110,6 @@ const finalChannel = (inputOptions = {}) => {
147
110
  if (conversation == null || agentParticipant == null || agentParticipant.definitionId == null)
148
111
  throw new Error("Final platform context requires a Final conversation");
149
112
  return {
150
- ...finalAddressContext({
151
- platform: ctx.platform,
152
- definitionId: agentParticipant.definitionId,
153
- turnPolicy: config.turnPolicy
154
- }),
155
113
  final: {
156
114
  post: async (message) => {
157
115
  if (ctx.platform.conversations.dispatchMessage == null)
@@ -168,8 +126,7 @@ const finalChannel = (inputOptions = {}) => {
168
126
  messageId: posted.messageId
169
127
  });
170
128
  return posted;
171
- },
172
- sendServiceInput: (input) => sendServiceInput(ctx.platform, input)
129
+ }
173
130
  }
174
131
  };
175
132
  };
@@ -203,7 +160,7 @@ const finalChannel = (inputOptions = {}) => {
203
160
  for (const [kind, handler] of Object.entries(authoredEvents))
204
161
  if (handler != null) events[kind] = handler;
205
162
  return Object.freeze(
206
- defineChannel({
163
+ defineRoomSurface({
207
164
  ...base,
208
165
  config: jsonObjectSchema.parse(config),
209
166
  installed: options.onMessage == null && options.onInputResponse == null && options.events == null && options.renderer == null && options.route == null ? packageRef(FINAL_CHANNEL_SPECIFIER) : void 0,
@@ -218,10 +175,7 @@ const finalChannel = (inputOptions = {}) => {
218
175
  const defaultAuth = defaultAuthOf(author);
219
176
  let admission = { auth: defaultAuth };
220
177
  if (options.onInputResponse != null) {
221
- const accepted = await options.onInputResponse(
222
- { ...ctx, ...channelAccessors(ctx.platform), defaultAuth },
223
- input
224
- );
178
+ const accepted = await options.onInputResponse({ ...ctx, defaultAuth }, input);
225
179
  if (accepted == null) return { resolved: false };
226
180
  admission = admissionSchema.parse(accepted);
227
181
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/channel-factories.ts"],
4
- "sourcesContent": ["import type { ContentBlock, SessionUpdate } from '@agentclientprotocol/sdk/experimental/v2';\nimport {\n ChannelPrincipalType,\n SemanticChannelEventKind,\n TurnPolicy,\n channelAccessors,\n channelAuthSchema,\n channelMessageCompletedSchema,\n decisionCreatedDataSchema,\n decisionResolvedDataSchema,\n defineChannel,\n jsonObjectSchema,\n packageRef,\n type ChannelAddressContextIface,\n type ChannelAuthIface,\n type ChannelDefinitionIface,\n type ChannelEventHandler,\n type ChannelInputReceiptIface,\n type ChannelInputResponseIface,\n type ChannelMessageCompletedDataIface,\n type ChannelMessageDeltaDataIface,\n type ChannelReceiveContextIface,\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 { finalAddressContext } from \"./channels/address-context.mjs\";\nimport { contentBlocksOf } from \"./channels/content.mjs\";\nimport { conversationEventInboundSchema, messageInboundSchema } from \"./channels/inbound.mjs\";\nimport { createMessagingChannel } from \"./channels/messaging-channel.mjs\";\nimport { sendServiceInput, type ServiceInputArgsIface } from \"./channels/service-input.mjs\";\n\nexport const FINAL_CHANNEL_SPECIFIER = '@finalai/final-agent-provider/channels/final';\n\nexport { ChannelPrincipalType, type ChannelAuthIface } from '@finalai/agent-provider';\n\nexport interface ChannelAdmissionIface {\n auth: ChannelAuthIface | null;\n context?: string[];\n title?: string;\n}\n\nexport interface FinalMessageContextIface\n extends ChannelReceiveContextIface, ChannelAddressContextIface {\n defaultAuth: ChannelAuthIface | null;\n}\n\nexport interface FinalChannelContextIface extends ChannelAddressContextIface {\n final: {\n post(message: ChannelMessageCompletedDataIface['message']): Promise<ConversationMessageIface>;\n // Input to a room's agent from a principal that is no member of the room.\n sendServiceInput(args: ServiceInputArgsIface): Promise<ChannelInputReceiptIface>;\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?: ChannelDefinitionIface<JsonValue, JsonValue>['route'];\n onMessage?: (\n ctx: FinalMessageContextIface,\n message: ConversationMessageIface,\n ) => ChannelAdmissionIface | null | Promise<ChannelAdmissionIface | null>;\n onInputResponse?: (\n ctx: FinalMessageContextIface,\n response: ChannelInputResponseIface,\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: channelAuthSchema.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): ChannelAuthIface | null => {\n if (author == null) return null;\n return {\n principalId: author.userId ?? author.definitionId ?? author.id,\n principalType: author.userId == null ? ChannelPrincipalType.Service : ChannelPrincipalType.User,\n authenticator: 'final',\n displayName: author.displayName,\n attributes: { participant_id: author.id },\n };\n};\n\n// A handoff from another of the agent's channels (`ctx.to('final', target)`).\nconst handoffSchema = z.object({\n target: z.object({\n conversationId: z.string().min(1),\n participantId: z.string().min(1).optional(),\n }),\n content: z.array(jsonObjectSchema).min(1),\n idempotencyKey: z.string().min(1),\n auth: channelAuthSchema,\n context: z.array(z.string()).optional(),\n title: z.string().optional(),\n actingUserId: z.string().min(1).optional(),\n originTurnId: z.string().min(1).optional(),\n source: z.object({ label: z.string().min(1) }).optional(),\n turnPolicy: z.nativeEnum(TurnPolicy).optional(),\n});\n\nexport const finalChannel = (\n inputOptions: FinalChannelOptionsIface = {},\n): ChannelDefinitionIface<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 handoff = handoffSchema.safeParse(input);\n if (handoff.success) {\n if (ctx.platform.channelSessions == null)\n throw new Error('channel session operations are unavailable');\n const { target, ...rest } = handoff.data;\n await ctx.platform.channelSessions.send(target, {\n ...rest,\n content: contentBlocksOf(rest.content),\n source: rest.source,\n // The sender's policy, else the receiving channel's.\n turnPolicy: rest.turnPolicy ?? config.turnPolicy,\n });\n return { conversationId: target.conversationId };\n }\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 ...finalAddressContext({\n platform: ctx.platform,\n definitionId: ctx.definitionId,\n turnPolicy: config.turnPolicy,\n }),\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 ...finalAddressContext({\n platform: ctx.platform,\n definitionId: agentParticipant.definitionId,\n turnPolicy: config.turnPolicy,\n }),\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 sendServiceInput: (input) => sendServiceInput(ctx.platform, input),\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 ): ChannelEventHandler | 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 defineChannel({\n ...base,\n config: jsonObjectSchema.parse(config),\n installed:\n options.onMessage == null &&\n options.onInputResponse == null &&\n options.events == null &&\n options.renderer == null &&\n options.route == null\n ? packageRef(FINAL_CHANNEL_SPECIFIER)\n : undefined,\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(\n { ...ctx, ...channelAccessors(ctx.platform), defaultAuth },\n input,\n );\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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",
4
+ "sourcesContent": ["import type { ContentBlock, SessionUpdate } from '@agentclientprotocol/sdk/experimental/v2';\nimport {\n ChannelPrincipalType,\n SemanticChannelEventKind,\n TurnPolicy,\n channelAuthSchema,\n channelMessageCompletedSchema,\n decisionCreatedDataSchema,\n decisionResolvedDataSchema,\n defineRoomSurface,\n jsonObjectSchema,\n packageRef,\n type ChannelAuthIface,\n type RoomSurfaceDefinitionIface,\n type RoomEventHandler,\n type ChannelInputResponseIface,\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 const FINAL_CHANNEL_SPECIFIER = '@finalai/final-agent-provider/channels/final';\n\nexport { ChannelPrincipalType, type ChannelAuthIface } from '@finalai/agent-provider';\n\nexport interface ChannelAdmissionIface {\n auth: ChannelAuthIface | null;\n context?: string[];\n title?: string;\n}\n\nexport interface FinalMessageContextIface extends RoomReceiveContextIface {\n defaultAuth: ChannelAuthIface | 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: ChannelInputResponseIface,\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: channelAuthSchema.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): ChannelAuthIface | null => {\n if (author == null) return null;\n return {\n principalId: author.userId ?? author.definitionId ?? author.id,\n principalType: author.userId == null ? ChannelPrincipalType.Service : ChannelPrincipalType.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 installed:\n options.onMessage == null &&\n options.onInputResponse == null &&\n options.events == null &&\n options.renderer == null &&\n options.route == null\n ? packageRef(FINAL_CHANNEL_SPECIFIER)\n : undefined,\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
6
  "names": ["ChannelPrincipalType"]
7
7
  }
@@ -0,0 +1,132 @@
1
+ import type { ChannelReceiveContextIface, ChannelReceiveResult, JsonObject, JsonValue, PersonHandle, PlaceRef, PrincipalRef, Refusal } from '@finalai/agent-provider';
2
+ import * as z from 'zod';
3
+ export declare const channelBaseUrl: (config: {
4
+ baseUrl?: string;
5
+ }) => string;
6
+ export declare const providerPlaceKey: (place: PlaceRef) => string;
7
+ export declare const parseJson: (text: string) => unknown;
8
+ export declare const textOf: (content: readonly JsonObject[]) => string;
9
+ export declare const replyText: (data: {
10
+ messages?: {
11
+ content: JsonObject[];
12
+ }[];
13
+ content?: JsonObject[];
14
+ }) => string;
15
+ export declare const turnStatus: (data: {
16
+ stopReason?: string | null;
17
+ }) => string | null;
18
+ export declare const completionText: (data: {
19
+ messages?: {
20
+ content: JsonObject[];
21
+ }[];
22
+ content?: JsonObject[];
23
+ stopReason?: string | null;
24
+ }, partial?: string) => string;
25
+ export declare const hexBytes: (hex: string) => Uint8Array | null;
26
+ export declare const verifyHmac: (args: {
27
+ secret: string;
28
+ body: string;
29
+ signature: string;
30
+ algorithm?: "SHA-256" | "SHA-1";
31
+ encoding?: "hex" | "base64";
32
+ }) => Promise<boolean>;
33
+ export declare const freshTimestamp: (timestamp: string | null, now?: number) => timestamp is string;
34
+ export declare const refusal: (result: Refusal) => ChannelReceiveResult;
35
+ export declare const receipt: (result: {
36
+ messageId: string;
37
+ } | {
38
+ inputId: string;
39
+ } | Refusal) => ChannelReceiveResult;
40
+ export declare const personFor: <Config>(ctx: ChannelReceiveContextIface<Config>, principal: PrincipalRef) => Promise<PersonHandle | Refusal>;
41
+ export interface ReceivePersonMessageIface<Config> {
42
+ ctx: ChannelReceiveContextIface<Config>;
43
+ principal: PrincipalRef;
44
+ place: PlaceRef;
45
+ routePlace?: PlaceRef;
46
+ text: string;
47
+ externalKey: string;
48
+ ref?: JsonObject;
49
+ context?: string[];
50
+ loadContext?: () => Promise<string[]>;
51
+ waitForAcceptance?: boolean;
52
+ onAccepted?: (result: {
53
+ turnId?: string;
54
+ }) => Promise<void>;
55
+ resumeAfterLink?: boolean;
56
+ }
57
+ export declare const receivePersonMessage: <Config>(args: ReceivePersonMessageIface<Config>) => Promise<ChannelReceiveResult>;
58
+ export declare const externalKey: (place: PlaceRef, id: string) => string;
59
+ export declare const refString: (ref: JsonObject | undefined, name: string) => string | null;
60
+ export declare const responseJson: (response: Response) => Promise<unknown>;
61
+ export declare const deliveryRetention: {
62
+ ttlSeconds: number;
63
+ };
64
+ export declare const stateKey: (prefix: string, ...values: (string | null)[]) => string;
65
+ export declare const oauthStateSchema: z.ZodObject<{
66
+ ticket: z.ZodString;
67
+ principal: z.ZodObject<{
68
+ id: z.ZodString;
69
+ tenant: z.ZodOptional<z.ZodString>;
70
+ displayName: z.ZodOptional<z.ZodString>;
71
+ }, z.core.$strip>;
72
+ redirectUri: z.ZodString;
73
+ verifier: z.ZodOptional<z.ZodString>;
74
+ }, z.core.$strip>;
75
+ export declare const startOAuth: <Config>(args: {
76
+ ticket: string;
77
+ principal: PrincipalRef;
78
+ authorizeUrl: string;
79
+ clientId: string;
80
+ redirectUri: string;
81
+ scope: string;
82
+ extra?: Record<string, string>;
83
+ pkce?: boolean;
84
+ }, ctx: ChannelReceiveContextIface<Config>) => Promise<URL>;
85
+ export declare const takeOAuth: <Config>(request: Request, ctx: ChannelReceiveContextIface<Config>) => Promise<{
86
+ code: string;
87
+ ticket: string;
88
+ principal: {
89
+ id: string;
90
+ tenant?: string | undefined;
91
+ displayName?: string | undefined;
92
+ };
93
+ redirectUri: string;
94
+ verifier?: string | undefined;
95
+ } | null>;
96
+ export declare const confirmOAuth: <Config>(args: {
97
+ ticket: string;
98
+ expected: PrincipalRef;
99
+ actual: PrincipalRef;
100
+ }, ctx: ChannelReceiveContextIface<Config>) => Promise<Response>;
101
+ export interface DecisionChoiceIface {
102
+ label: string;
103
+ outcome: JsonValue;
104
+ answer: 'approve' | 'deny';
105
+ }
106
+ export declare const decisionSummary: (request: JsonObject) => string;
107
+ export declare const decisionAnswer: (choices: DecisionChoiceIface[], text: string) => DecisionChoiceIface | undefined;
108
+ export declare const decisionChoices: (request: JsonObject) => DecisionChoiceIface[];
109
+ export declare const createQueue: <T>() => {
110
+ push: (value: T) => void;
111
+ close: () => void;
112
+ stream: AsyncGenerator<T, any, any>;
113
+ };
114
+ export declare const inTenant: <Config>(ctx: ChannelReceiveContextIface<Config>, tenant: string) => ChannelReceiveContextIface<Config>;
115
+ export declare const providerOriginSchema: z.ZodObject<{
116
+ place: z.ZodLazy<z.ZodType<PlaceRef, unknown, z.core.$ZodTypeInternals<PlaceRef, unknown>>>;
117
+ externalKey: z.ZodString;
118
+ turnId: z.ZodOptional<z.ZodString>;
119
+ }, z.core.$strip>;
120
+ export declare const abortable: <T>(source: AsyncIterable<T>, signal: AbortSignal) => AsyncGenerator<T>;
121
+ interface SharedReactionArgsIface {
122
+ store: ChannelReceiveContextIface['store'];
123
+ key: string;
124
+ principal: PrincipalRef;
125
+ }
126
+ export declare const addSharedReaction: (args: SharedReactionArgsIface & {
127
+ add(): Promise<boolean>;
128
+ }) => Promise<void>;
129
+ export declare const removeSharedReaction: (args: SharedReactionArgsIface & {
130
+ remove(): Promise<void>;
131
+ }) => Promise<void>;
132
+ export {};