@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,36 +0,0 @@
1
- import type { ContentBlock, SessionUpdate } from '@agentclientprotocol/sdk/experimental/v2';
2
- import { TurnPolicy, type JsonValue, type ProjectionContextIface } from '@finalai/agent-provider';
3
- import * as z from 'zod';
4
- export declare const DEFAULT_PROJECTION_UPDATE_INTERVAL_MS = 300;
5
- export declare const projectionStateSchema: z.ZodObject<{
6
- messageId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
7
- messageSeq: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
8
- fromSeq: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
9
- lastSeq: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
10
- lastFlushAt: z.ZodDefault<z.ZodNumber>;
11
- dirty: z.ZodDefault<z.ZodBoolean>;
12
- segments: z.ZodArray<z.ZodObject<{
13
- messageId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
14
- messageSeq: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
15
- fromSeq: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
16
- lastSeq: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
17
- lastFlushAt: z.ZodDefault<z.ZodNumber>;
18
- dirty: z.ZodDefault<z.ZodBoolean>;
19
- acpMessageId: z.ZodString;
20
- blocks: z.ZodArray<z.ZodType<import("@finalai/agent-provider").JsonObject, unknown, z.core.$ZodTypeInternals<import("@finalai/agent-provider").JsonObject, unknown>>>;
21
- }, z.core.$strip>>;
22
- }, z.core.$strip>;
23
- export type ProjectionStateIface = z.infer<typeof projectionStateSchema>;
24
- export interface ProjectorConfigIface {
25
- updateIntervalMs?: number;
26
- now?: () => number;
27
- turnPolicy?: TurnPolicy;
28
- }
29
- export declare const emptyProjectionState: () => ProjectionStateIface;
30
- export declare const projectionStateOf: (state: JsonValue | null) => ProjectionStateIface;
31
- export declare const visibleContent: (state: Pick<ProjectionStateIface, "segments">) => ContentBlock[];
32
- export declare const accumulateUpdate: (state: ProjectionStateIface, update: SessionUpdate) => ProjectionStateIface["segments"][number] | null;
33
- export interface ProjectorIface {
34
- project(update: SessionUpdate, ctx: ProjectionContextIface): Promise<void>;
35
- }
36
- export declare const createProjector: (config?: ProjectorConfigIface) => ProjectorIface;
@@ -1,233 +0,0 @@
1
- import { textOfBlock } from "@finalai/acp-session";
2
- import {
3
- jsonObjectSchema,
4
- MessageKind,
5
- turnEndOf,
6
- TurnPolicy
7
- } from "@finalai/agent-provider";
8
- import * as z from "zod";
9
- import { contentBlockOf, jsonOfContentBlock } from "./content.mjs";
10
- const DEFAULT_PROJECTION_UPDATE_INTERVAL_MS = 300;
11
- const projectedMessageSchema = z.object({
12
- messageId: z.string().nullable().default(null),
13
- // The reply's conversation seq, so the finished reply is read back by
14
- // position however many messages arrived meanwhile.
15
- messageSeq: z.number().nullable().default(null),
16
- fromSeq: z.number().nullable().default(null),
17
- lastSeq: z.number().nullable().default(null),
18
- lastFlushAt: z.number().default(0),
19
- dirty: z.boolean().default(false)
20
- });
21
- const segmentSchema = projectedMessageSchema.extend({
22
- acpMessageId: z.string(),
23
- blocks: z.array(jsonObjectSchema)
24
- });
25
- const projectionStateSchema = projectedMessageSchema.extend({
26
- segments: z.array(segmentSchema)
27
- });
28
- const agentChunkSchema = z.object({
29
- sessionUpdate: z.literal("agent_message_chunk"),
30
- messageId: z.string(),
31
- content: jsonObjectSchema
32
- });
33
- const agentMessageSchema = z.object({
34
- sessionUpdate: z.literal("agent_message"),
35
- messageId: z.string(),
36
- content: z.array(jsonObjectSchema).nullish()
37
- });
38
- const updateJson = (update) => {
39
- const parsed = jsonObjectSchema.safeParse(JSON.parse(JSON.stringify(update)));
40
- return parsed.success ? parsed.data : null;
41
- };
42
- const emptyProjectionState = () => ({
43
- messageId: null,
44
- messageSeq: null,
45
- fromSeq: null,
46
- lastSeq: null,
47
- lastFlushAt: 0,
48
- dirty: false,
49
- segments: []
50
- });
51
- const projectionStateOf = (state) => {
52
- const parsed = projectionStateSchema.safeParse(state);
53
- return parsed.success ? parsed.data : emptyProjectionState();
54
- };
55
- const plainText = (block) => block == null || block._meta != null ? null : textOfBlock(block);
56
- const appendBlock = (blocks, block, separator) => {
57
- const lastText = plainText(blocks.at(-1));
58
- const nextText = plainText(block);
59
- if (lastText != null && nextText != null) {
60
- blocks[blocks.length - 1] = { type: "text", text: `${lastText}${separator}${nextText}` };
61
- } else {
62
- blocks.push(block);
63
- }
64
- };
65
- const visibleContent = (state) => {
66
- const content = [];
67
- for (const segment of state.segments) {
68
- const blocks = [];
69
- for (const block of segment.blocks) {
70
- const parsed = contentBlockOf(block);
71
- if (parsed != null) appendBlock(blocks, parsed, "");
72
- }
73
- for (const block of blocks) appendBlock(content, block, "\n\n");
74
- }
75
- return content.flatMap((block) => {
76
- const text = textOfBlock(block);
77
- if (text == null) return [block];
78
- const trimmed = text.trim();
79
- return trimmed.length === 0 ? [] : [{ ...block, type: "text", text: trimmed }];
80
- });
81
- };
82
- const segmentFor = (state, acpMessageId) => {
83
- const existing = state.segments.find((segment2) => segment2.acpMessageId === acpMessageId);
84
- if (existing != null) {
85
- return existing;
86
- }
87
- const segment = segmentSchema.parse({ acpMessageId, blocks: [] });
88
- state.segments.push(segment);
89
- return segment;
90
- };
91
- const accumulateUpdate = (state, update) => {
92
- const json = updateJson(update);
93
- const chunk = agentChunkSchema.safeParse(json);
94
- if (chunk.success) {
95
- const block = contentBlockOf(chunk.data.content);
96
- if (block == null) return null;
97
- const segment = segmentFor(state, chunk.data.messageId);
98
- const last = segment.blocks.at(-1);
99
- const lastBlock = last == null ? null : contentBlockOf(last);
100
- const lastText = lastBlock == null ? null : plainText(lastBlock);
101
- const nextText = plainText(block);
102
- if (lastText != null && nextText != null)
103
- segment.blocks[segment.blocks.length - 1] = { type: "text", text: `${lastText}${nextText}` };
104
- else segment.blocks.push(jsonOfContentBlock(block));
105
- return segment;
106
- }
107
- const message = agentMessageSchema.safeParse(json);
108
- if (message.success) {
109
- if (message.data.content === void 0) return null;
110
- const blocks = (message.data.content ?? []).flatMap((block) => {
111
- const parsed = contentBlockOf(block);
112
- return parsed == null ? [] : [jsonOfContentBlock(parsed)];
113
- });
114
- const segment = segmentFor(state, message.data.messageId);
115
- segment.blocks = blocks;
116
- return segment;
117
- }
118
- return null;
119
- };
120
- const createProjector = (config = {}) => {
121
- const now = config.now ?? Date.now;
122
- const interval = config.updateIntervalMs ?? DEFAULT_PROJECTION_UPDATE_INTERVAL_MS;
123
- const fold = async (update, ctx) => {
124
- const state = projectionStateOf(ctx.state.get());
125
- const segment = accumulateUpdate(state, update);
126
- if (state.messageId == null && (segment == null || segment.messageId == null)) {
127
- for (const previous of state.segments) {
128
- if (previous === segment || !previous.dirty || previous.messageId == null) continue;
129
- await ctx.platform.conversations.updateMessage({
130
- messageId: previous.messageId,
131
- content: visibleContent({ segments: [previous] }),
132
- final: false
133
- });
134
- previous.lastFlushAt = now();
135
- previous.dirty = false;
136
- }
137
- }
138
- if (segment == null) {
139
- ctx.state.set(state);
140
- return;
141
- }
142
- const target = state.messageId == null ? segment : state;
143
- target.lastSeq = ctx.seq;
144
- const content = () => visibleContent({ segments: target === state ? state.segments : [segment] });
145
- if (target.messageId == null) {
146
- const visible = content();
147
- if (visible.length === 0) {
148
- ctx.state.set(state);
149
- return;
150
- }
151
- const message = await ctx.platform.conversations.postMessage({
152
- conversationId: ctx.conversation.conversationId,
153
- authorParticipantId: ctx.agentParticipant.id,
154
- kind: MessageKind.Message,
155
- content: visible,
156
- source: { turnId: ctx.turn.id, fromSeq: ctx.seq, toSeq: ctx.seq }
157
- });
158
- target.messageId = message.messageId;
159
- target.messageSeq = message.seq;
160
- target.fromSeq = ctx.seq;
161
- target.lastFlushAt = now();
162
- target.dirty = false;
163
- } else if (now() - target.lastFlushAt >= interval) {
164
- await ctx.platform.conversations.updateMessage({
165
- messageId: target.messageId,
166
- content: content(),
167
- final: false
168
- });
169
- target.lastFlushAt = now();
170
- target.dirty = false;
171
- } else {
172
- target.dirty = true;
173
- }
174
- ctx.state.set(state);
175
- };
176
- const finish = async (ctx) => {
177
- const state = projectionStateOf(ctx.state.get());
178
- if (state.messageId != null) {
179
- await finishMessage(ctx, state, visibleContent(state));
180
- return;
181
- }
182
- for (const segment of state.segments) {
183
- await finishMessage(ctx, segment, visibleContent({ segments: [segment] }));
184
- }
185
- };
186
- const finishMessage = async (ctx, state, content) => {
187
- if (state.messageId == null) {
188
- return;
189
- }
190
- await ctx.platform.conversations.updateMessage({
191
- messageId: state.messageId,
192
- content,
193
- final: true
194
- });
195
- const reply = state.messageSeq == null ? null : (await ctx.platform.conversations.recentMessages({
196
- conversationId: ctx.conversation.conversationId,
197
- beforeSeq: state.messageSeq + 1,
198
- limit: 1
199
- })).find((message) => message.messageId === state.messageId);
200
- if (reply == null) {
201
- ctx.platform.log("finished reply not found for routing", {
202
- messageId: state.messageId,
203
- seq: state.messageSeq
204
- });
205
- }
206
- if (reply != null) {
207
- if (ctx.platform.conversations.dispatchMessage == null)
208
- throw new Error("channel dispatch is unavailable");
209
- await ctx.platform.conversations.dispatchMessage({
210
- conversationId: reply.conversationId,
211
- messageId: reply.messageId
212
- });
213
- }
214
- };
215
- const project = async (update, ctx) => {
216
- const { conversation, agentParticipant } = ctx;
217
- if (conversation == null || agentParticipant == null)
218
- throw new Error("Final rendering requires a Final conversation");
219
- const context = { ...ctx, conversation, agentParticipant };
220
- return turnEndOf(update) == null ? fold(update, context) : finish(context);
221
- };
222
- return { project };
223
- };
224
- export {
225
- DEFAULT_PROJECTION_UPDATE_INTERVAL_MS,
226
- accumulateUpdate,
227
- createProjector,
228
- emptyProjectionState,
229
- projectionStateOf,
230
- projectionStateSchema,
231
- visibleContent
232
- };
233
- //# sourceMappingURL=projection.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../src/channels/projection.ts"],
4
- "sourcesContent": ["import type { ContentBlock, SessionUpdate } from '@agentclientprotocol/sdk/experimental/v2';\nimport { textOfBlock } from '@finalai/acp-session';\nimport {\n jsonObjectSchema,\n MessageKind,\n turnEndOf,\n TurnPolicy,\n type JsonValue,\n type ProjectionContextIface,\n} from '@finalai/agent-provider';\nimport * as z from 'zod';\nimport { contentBlockOf, jsonOfContentBlock } from \"./content.mjs\";\n\n// Each ACP message ID owns a visible conversation message. The message is\n// created on its first visible chunk (streaming),\n// updated at most every `updateIntervalMs`, and finalized at the idle\n// state_update that ends the turn. The fold lives in the turn state the\n// platform keeps (ctx.state). An empty turn projects nothing.\n\nexport const DEFAULT_PROJECTION_UPDATE_INTERVAL_MS = 300;\n\nconst projectedMessageSchema = z.object({\n messageId: z.string().nullable().default(null),\n // The reply's conversation seq, so the finished reply is read back by\n // position however many messages arrived meanwhile.\n messageSeq: z.number().nullable().default(null),\n fromSeq: z.number().nullable().default(null),\n lastSeq: z.number().nullable().default(null),\n lastFlushAt: z.number().default(0),\n dirty: z.boolean().default(false),\n});\n\nconst segmentSchema = projectedMessageSchema.extend({\n acpMessageId: z.string(),\n blocks: z.array(jsonObjectSchema),\n});\n\n// Root message fields are retained for turns created by the old projector.\n// Those turns finish in their existing combined row; new turns use segment rows.\nexport const projectionStateSchema = projectedMessageSchema.extend({\n segments: z.array(segmentSchema),\n});\n\nexport type ProjectionStateIface = z.infer<typeof projectionStateSchema>;\n\nexport interface ProjectorConfigIface {\n updateIntervalMs?: number;\n now?: () => number;\n // The channel's turnPolicy, for routing finished replies (default steer).\n turnPolicy?: TurnPolicy;\n}\n\nconst agentChunkSchema = z.object({\n sessionUpdate: z.literal('agent_message_chunk'),\n messageId: z.string(),\n content: jsonObjectSchema,\n});\n\nconst agentMessageSchema = z.object({\n sessionUpdate: z.literal('agent_message'),\n messageId: z.string(),\n content: z.array(jsonObjectSchema).nullish(),\n});\n\nconst updateJson = (update: SessionUpdate): JsonValue => {\n const parsed = jsonObjectSchema.safeParse(JSON.parse(JSON.stringify(update)));\n return parsed.success ? parsed.data : null;\n};\n\nexport const emptyProjectionState = (): ProjectionStateIface => ({\n messageId: null,\n messageSeq: null,\n fromSeq: null,\n lastSeq: null,\n lastFlushAt: 0,\n dirty: false,\n segments: [],\n});\n\nexport const projectionStateOf = (state: JsonValue | null): ProjectionStateIface => {\n const parsed = projectionStateSchema.safeParse(state);\n return parsed.success ? parsed.data : emptyProjectionState();\n};\n\n// Plain text (no `_meta`) of a block, the only kind consecutive chunks merge into.\nconst plainText = (block: ContentBlock | undefined): string | null =>\n block == null || block._meta != null ? null : textOfBlock(block);\n\nconst appendBlock = (blocks: ContentBlock[], block: ContentBlock, separator: string): void => {\n const lastText = plainText(blocks.at(-1));\n const nextText = plainText(block);\n if (lastText != null && nextText != null) {\n blocks[blocks.length - 1] = { type: 'text', text: `${lastText}${separator}${nextText}` };\n } else {\n blocks.push(block);\n }\n};\n\n// The visible content of the turn: segments in order of first appearance,\n// separated by a blank line between text runs.\nexport const visibleContent = (state: Pick<ProjectionStateIface, 'segments'>): ContentBlock[] => {\n const content: ContentBlock[] = [];\n for (const segment of state.segments) {\n const blocks: ContentBlock[] = [];\n for (const block of segment.blocks) {\n const parsed = contentBlockOf(block);\n if (parsed != null) appendBlock(blocks, parsed, '');\n }\n for (const block of blocks) appendBlock(content, block, '\\n\\n');\n }\n return content.flatMap((block): ContentBlock[] => {\n const text = textOfBlock(block);\n if (text == null) return [block];\n const trimmed = text.trim();\n return trimmed.length === 0 ? [] : [{ ...block, type: 'text', text: trimmed }];\n });\n};\n\nconst segmentFor = (\n state: ProjectionStateIface,\n acpMessageId: string,\n): ProjectionStateIface['segments'][number] => {\n const existing = state.segments.find((segment) => segment.acpMessageId === acpMessageId);\n if (existing != null) {\n return existing;\n }\n const segment = segmentSchema.parse({ acpMessageId, blocks: [] });\n state.segments.push(segment);\n return segment;\n};\n\n// Folds one ACP update into the state and returns the affected segment, or null\n// for updates that are not visible output.\nexport const accumulateUpdate = (\n state: ProjectionStateIface,\n update: SessionUpdate,\n): ProjectionStateIface['segments'][number] | null => {\n const json = updateJson(update);\n const chunk = agentChunkSchema.safeParse(json);\n if (chunk.success) {\n const block = contentBlockOf(chunk.data.content);\n if (block == null) return null;\n const segment = segmentFor(state, chunk.data.messageId);\n // Plain text joins the run before it as it arrives (visibleContent joins\n // them the same way), so the state and each fold stay the same size\n // however long the reply grows.\n const last = segment.blocks.at(-1);\n const lastBlock = last == null ? null : contentBlockOf(last);\n const lastText = lastBlock == null ? null : plainText(lastBlock);\n const nextText = plainText(block);\n if (lastText != null && nextText != null)\n segment.blocks[segment.blocks.length - 1] = { type: 'text', text: `${lastText}${nextText}` };\n else segment.blocks.push(jsonOfContentBlock(block));\n return segment;\n }\n const message = agentMessageSchema.safeParse(json);\n if (message.success) {\n // ACP v2 upsert: a concrete array replaces the message's content; omitted leaves it.\n if (message.data.content === undefined) return null;\n const blocks = (message.data.content ?? []).flatMap((block) => {\n const parsed = contentBlockOf(block);\n return parsed == null ? [] : [jsonOfContentBlock(parsed)];\n });\n const segment = segmentFor(state, message.data.messageId);\n segment.blocks = blocks;\n return segment;\n }\n return null;\n};\n\ninterface ConversationProjectionContextIface extends ProjectionContextIface {\n conversation: NonNullable<ProjectionContextIface['conversation']>;\n agentParticipant: NonNullable<ProjectionContextIface['agentParticipant']>;\n}\n\nexport interface ProjectorIface {\n // RoomSurfaceDefinitionIface['project'] for the messaging channels: folds visible\n // output into separate messages and, at the turn-ending idle state_update,\n // finalizes and routes them in order of first appearance.\n project(update: SessionUpdate, ctx: ProjectionContextIface): Promise<void>;\n}\n\nexport const createProjector = (config: ProjectorConfigIface = {}): ProjectorIface => {\n const now = config.now ?? Date.now;\n const interval = config.updateIntervalMs ?? DEFAULT_PROJECTION_UPDATE_INTERVAL_MS;\n\n const fold = async (\n update: SessionUpdate,\n ctx: ConversationProjectionContextIface,\n ): Promise<void> => {\n const state = projectionStateOf(ctx.state.get());\n const segment = accumulateUpdate(state, update);\n if (state.messageId == null && (segment == null || segment.messageId == null)) {\n for (const previous of state.segments) {\n if (previous === segment || !previous.dirty || previous.messageId == null) continue;\n await ctx.platform.conversations.updateMessage({\n messageId: previous.messageId,\n content: visibleContent({ segments: [previous] }),\n final: false,\n });\n previous.lastFlushAt = now();\n previous.dirty = false;\n }\n }\n if (segment == null) {\n ctx.state.set(state);\n return;\n }\n const target = state.messageId == null ? segment : state;\n target.lastSeq = ctx.seq;\n // Built only when it is written: between flushes a chunk only folds.\n const content = () =>\n visibleContent({ segments: target === state ? state.segments : [segment] });\n if (target.messageId == null) {\n const visible = content();\n if (visible.length === 0) {\n ctx.state.set(state);\n return;\n }\n const message = await ctx.platform.conversations.postMessage({\n conversationId: ctx.conversation.conversationId,\n authorParticipantId: ctx.agentParticipant.id,\n kind: MessageKind.Message,\n content: visible,\n source: { turnId: ctx.turn.id, fromSeq: ctx.seq, toSeq: ctx.seq },\n });\n target.messageId = message.messageId;\n target.messageSeq = message.seq;\n target.fromSeq = ctx.seq;\n target.lastFlushAt = now();\n target.dirty = false;\n } else if (now() - target.lastFlushAt >= interval) {\n await ctx.platform.conversations.updateMessage({\n messageId: target.messageId,\n content: content(),\n final: false,\n });\n target.lastFlushAt = now();\n target.dirty = false;\n } else {\n target.dirty = true;\n }\n ctx.state.set(state);\n };\n\n const finish = async (ctx: ConversationProjectionContextIface): Promise<void> => {\n const state = projectionStateOf(ctx.state.get());\n if (state.messageId != null) {\n await finishMessage(ctx, state, visibleContent(state));\n return;\n }\n for (const segment of state.segments) {\n await finishMessage(ctx, segment, visibleContent({ segments: [segment] }));\n }\n };\n\n const finishMessage = async (\n ctx: ConversationProjectionContextIface,\n state: z.infer<typeof projectedMessageSchema>,\n content: ContentBlock[],\n ): Promise<void> => {\n if (state.messageId == null) {\n return;\n }\n await ctx.platform.conversations.updateMessage({\n messageId: state.messageId,\n content,\n final: true,\n });\n // The finished reply is routed like any message: other agents may observe\n // it or, when mentioned within the hop limit, be prompted.\n const reply =\n state.messageSeq == null\n ? null\n : (\n await ctx.platform.conversations.recentMessages({\n conversationId: ctx.conversation.conversationId,\n beforeSeq: state.messageSeq + 1,\n limit: 1,\n })\n ).find((message) => message.messageId === state.messageId);\n if (reply == null) {\n ctx.platform.log('finished reply not found for routing', {\n messageId: state.messageId,\n seq: state.messageSeq,\n });\n }\n if (reply != null) {\n if (ctx.platform.conversations.dispatchMessage == null)\n throw new Error('channel dispatch is unavailable');\n await ctx.platform.conversations.dispatchMessage({\n conversationId: reply.conversationId,\n messageId: reply.messageId,\n });\n }\n };\n\n const project: ProjectorIface['project'] = async (update, ctx) => {\n const { conversation, agentParticipant } = ctx;\n if (conversation == null || agentParticipant == null)\n throw new Error('Final rendering requires a Final conversation');\n const context = { ...ctx, conversation, agentParticipant };\n return turnEndOf(update) == null ? fold(update, context) : finish(context);\n };\n\n return { project };\n};\n"],
5
- "mappings": "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",
6
- "names": ["segment"]
7
- }
@@ -1,72 +0,0 @@
1
- import type { ContentBlock } from '@agentclientprotocol/sdk/experimental/v2';
2
- import { type FinalAuthorIface, type FinalContextIface, type FinalMessageRefIface } from '@finalai/acp-session';
3
- import { type RoomAuthIface, type ConversationMessageIface, type ParticipantIface } from '@finalai/agent-provider/room-surface';
4
- export declare const EXCERPT_CHARS = 280;
5
- export declare const CATCH_UP_MAX_MESSAGES = 20;
6
- export declare const CATCH_UP_MAX_CHARS = 4000;
7
- export declare const textBlock: (text: string) => ContentBlock;
8
- export declare const contentText: (content: ContentBlock[]) => string;
9
- export declare const messageSummary: (content: ContentBlock[]) => string;
10
- export declare const excerpt: (text: string, maxChars?: number) => string;
11
- export declare const finalAuthorOf: (participant: ParticipantIface) => FinalAuthorIface;
12
- export declare const principalAuthorOf: (args: {
13
- auth: RoomAuthIface;
14
- agent?: boolean;
15
- }) => FinalAuthorIface;
16
- export interface AuthorPrefixedContentArgsIface {
17
- content: ContentBlock[];
18
- author: FinalAuthorIface;
19
- rendersAuthorMeta: boolean;
20
- context?: FinalContextIface;
21
- }
22
- export declare const authorPrefixedContent: (args: AuthorPrefixedContentArgsIface) => ContentBlock[];
23
- export interface ReplyContextArgsIface {
24
- replyTo?: FinalMessageRefIface | null;
25
- thread?: {
26
- rootMessageId: string;
27
- rootExcerpt: string;
28
- rootAuthor?: FinalAuthorIface | null;
29
- } | null;
30
- quotes?: FinalMessageRefIface[];
31
- }
32
- export declare const finalContextOf: (args: ReplyContextArgsIface) => FinalContextIface | undefined;
33
- export declare const renderReplyContext: (args: ReplyContextArgsIface) => ContentBlock | null;
34
- export declare const messageRefOf: (message: ConversationMessageIface, participants: ParticipantIface[]) => FinalMessageRefIface;
35
- export declare enum CatchUpSince {
36
- Start = "start",
37
- LastContact = "last-contact"
38
- }
39
- export interface CatchUpArgsIface {
40
- messages: ConversationMessageIface[];
41
- participants: ParticipantIface[];
42
- agentParticipantId: string;
43
- since: CatchUpSince;
44
- maxMessages?: number;
45
- maxChars?: number;
46
- }
47
- export declare const buildCatchUpBlock: (args: CatchUpArgsIface) => ContentBlock | null;
48
- export declare const systemNoticeBlock: (args: {
49
- text: string;
50
- }) => ContentBlock;
51
- export declare const catchUpFor: (args: {
52
- recipient: ParticipantIface;
53
- earlier: ConversationMessageIface[];
54
- participants: ParticipantIface[];
55
- }) => ContentBlock | null;
56
- export interface PromptContentArgsIface {
57
- message: ConversationMessageIface;
58
- author: ParticipantIface;
59
- recipient: ParticipantIface;
60
- replyContext: ReplyContextArgsIface;
61
- catchUp: ContentBlock | null;
62
- }
63
- export declare const buildPromptContent: (args: PromptContentArgsIface) => ContentBlock[];
64
- export interface ServiceInputPromptArgsIface {
65
- content: ContentBlock[];
66
- context?: string[];
67
- author: FinalAuthorIface;
68
- recipient: ParticipantIface;
69
- earlier: ConversationMessageIface[];
70
- participants: ParticipantIface[];
71
- }
72
- export declare const buildServiceInputPrompt: (args: ServiceInputPromptArgsIface) => ContentBlock[];
@@ -1,208 +0,0 @@
1
- import {
2
- FinalAuthorKind,
3
- FinalContentRole,
4
- promptTextWithAuthorPrefix,
5
- textOf,
6
- withFinalMeta
7
- } from "@finalai/acp-session";
8
- import {
9
- RoomPrincipalType,
10
- MessageKind,
11
- ParticipantKind,
12
- principalDisplayName,
13
- RoutingMode
14
- } from "@finalai/agent-provider/room-surface";
15
- const EXCERPT_CHARS = 280;
16
- const CATCH_UP_MAX_MESSAGES = 20;
17
- const CATCH_UP_MAX_CHARS = 4e3;
18
- const textBlock = (text) => ({ type: "text", text });
19
- const contentText = (content) => textOf(content, { separator: "\n" }).trim();
20
- const messageSummary = (content) => {
21
- const text = contentText(content);
22
- if (text.length > 0) {
23
- return text;
24
- }
25
- const attachments = content.filter((block) => block.type !== "text").length;
26
- return attachments === 0 ? "" : `[${attachments} attachment${attachments === 1 ? "" : "s"}]`;
27
- };
28
- const excerpt = (text, maxChars = EXCERPT_CHARS) => {
29
- const normalized = text.replace(/\s+/gu, " ").trim();
30
- return normalized.length <= maxChars ? normalized : `${normalized.slice(0, maxChars - 1)}\u2026`;
31
- };
32
- const finalAuthorOf = (participant) => ({
33
- participantId: participant.id,
34
- kind: participant.kind === ParticipantKind.Agent ? FinalAuthorKind.Agent : FinalAuthorKind.User,
35
- displayName: participant.displayName
36
- });
37
- const principalAuthorOf = (args) => ({
38
- kind: args.agent === true ? FinalAuthorKind.Agent : args.auth.principalType === RoomPrincipalType.User ? FinalAuthorKind.User : FinalAuthorKind.Service,
39
- displayName: principalDisplayName(args.auth),
40
- principal: {
41
- principalId: args.auth.principalId,
42
- principalType: args.auth.principalType,
43
- authenticator: args.auth.authenticator
44
- }
45
- });
46
- const withContentRole = (block, context) => withFinalMeta(block, { role: FinalContentRole.Context, context });
47
- const authorPrefixedContent = (args) => {
48
- const blocks = args.rendersAuthorMeta ? args.content : promptTextWithAuthorPrefix(args.content, args.author.displayName);
49
- return blocks.map(
50
- (block, index) => withFinalMeta(block, { author: args.author, context: index === 0 ? args.context : void 0 })
51
- );
52
- };
53
- const finalContextOf = (args) => {
54
- const context = {};
55
- if (args.replyTo != null) context.replyTo = args.replyTo;
56
- if (args.thread != null) {
57
- context.thread = {
58
- rootMessageId: args.thread.rootMessageId,
59
- rootExcerpt: args.thread.rootExcerpt
60
- };
61
- }
62
- if (args.quotes != null && args.quotes.length > 0) context.quotes = args.quotes;
63
- return Object.keys(context).length === 0 ? void 0 : context;
64
- };
65
- const renderReplyContext = (args) => {
66
- const context = finalContextOf(args);
67
- if (context == null) {
68
- return null;
69
- }
70
- const lines = [];
71
- if (args.thread != null) {
72
- const by = args.thread.rootAuthor == null ? "" : ` started by ${args.thread.rootAuthor.displayName}`;
73
- lines.push(`In a thread${by}: "${args.thread.rootExcerpt}"`);
74
- }
75
- if (args.replyTo != null) {
76
- lines.push(
77
- `Replying to ${args.replyTo.author?.displayName ?? "a message"}: "${args.replyTo.excerpt}"`
78
- );
79
- }
80
- for (const quote of args.quotes ?? []) {
81
- lines.push(`Quoting ${quote.author?.displayName ?? "a message"}: "${quote.excerpt}"`);
82
- }
83
- return withContentRole(textBlock(lines.join("\n")), context);
84
- };
85
- const messageRefOf = (message, participants) => {
86
- const author = participants.find((participant) => participant.id === message.authorParticipantId);
87
- return {
88
- messageId: message.messageId,
89
- author: author == null ? null : finalAuthorOf(author),
90
- excerpt: excerpt(messageSummary(message.content))
91
- };
92
- };
93
- const transcriptLine = (message, participants) => {
94
- const author = participants.find((participant) => participant.id === message.authorParticipantId);
95
- return `${author?.displayName ?? "Someone"}: ${messageSummary(message.content)}`;
96
- };
97
- const visibleForTranscript = (message) => message.kind !== MessageKind.Card && messageSummary(message.content).length > 0;
98
- const boundedLines = (args) => {
99
- const lines = [];
100
- let chars = 0;
101
- const ordered = [...args.messages].sort((left, right) => right.seq - left.seq);
102
- for (const message of ordered) {
103
- const line = transcriptLine(message, args.participants);
104
- if (lines.length >= args.maxMessages || chars + line.length > args.maxChars) {
105
- break;
106
- }
107
- lines.push(line);
108
- chars += line.length + 1;
109
- }
110
- return { lines: lines.reverse(), omitted: ordered.length - lines.length };
111
- };
112
- var CatchUpSince = /* @__PURE__ */ ((CatchUpSince2) => {
113
- CatchUpSince2["Start"] = "start";
114
- CatchUpSince2["LastContact"] = "last-contact";
115
- return CatchUpSince2;
116
- })(CatchUpSince || {});
117
- const buildCatchUpBlock = (args) => {
118
- let unseen = args.messages.filter(
119
- (message) => visibleForTranscript(message) && message.authorParticipantId !== args.agentParticipantId
120
- );
121
- if (args.since === "last-contact" /* LastContact */) {
122
- const lastContactSeq = args.messages.reduce(
123
- (latest, message) => message.authorParticipantId === args.agentParticipantId || message.mentionedParticipantIds.includes(args.agentParticipantId) ? Math.max(latest, message.seq) : latest,
124
- -1
125
- );
126
- unseen = unseen.filter((message) => message.seq > lastContactSeq);
127
- }
128
- if (unseen.length === 0) {
129
- return null;
130
- }
131
- const { lines, omitted } = boundedLines({
132
- messages: unseen,
133
- participants: args.participants,
134
- maxMessages: args.maxMessages ?? CATCH_UP_MAX_MESSAGES,
135
- maxChars: args.maxChars ?? CATCH_UP_MAX_CHARS
136
- });
137
- if (lines.length === 0) {
138
- return null;
139
- }
140
- const header = "Earlier in this conversation, not previously shown:";
141
- const omittedLine = omitted > 0 ? [`(${omitted} earlier message${omitted === 1 ? "" : "s"} omitted)`] : [];
142
- return withContentRole(textBlock([header, ...omittedLine, ...lines].join("\n")));
143
- };
144
- const systemNoticeBlock = (args) => withFinalMeta(textBlock(args.text), {
145
- author: { kind: FinalAuthorKind.Service, displayName: "Final" }
146
- });
147
- const catchUpFor = (args) => {
148
- const since = args.recipient.sessionId == null ? "start" /* Start */ : args.recipient.routingMode === RoutingMode.Mention ? "last-contact" /* LastContact */ : null;
149
- if (since == null) return null;
150
- return buildCatchUpBlock({
151
- messages: args.earlier,
152
- participants: args.participants,
153
- agentParticipantId: args.recipient.id,
154
- since
155
- });
156
- };
157
- const buildPromptContent = (args) => {
158
- const contextBlock = renderReplyContext(args.replyContext);
159
- const body = authorPrefixedContent({
160
- content: args.message.content.length > 0 ? args.message.content : [textBlock(args.message.body)],
161
- author: finalAuthorOf(args.author),
162
- rendersAuthorMeta: args.recipient.rendersAuthorMeta ?? false,
163
- context: finalContextOf(args.replyContext)
164
- });
165
- return [
166
- ...args.catchUp == null ? [] : [args.catchUp],
167
- ...contextBlock == null ? [] : [contextBlock],
168
- ...body
169
- ];
170
- };
171
- const buildServiceInputPrompt = (args) => {
172
- const catchUp = catchUpFor({
173
- recipient: args.recipient,
174
- earlier: args.earlier,
175
- participants: args.participants
176
- });
177
- return [
178
- ...catchUp == null ? [] : [catchUp],
179
- ...(args.context ?? []).map((text) => withContentRole(textBlock(text))),
180
- ...authorPrefixedContent({
181
- content: args.content,
182
- author: args.author,
183
- rendersAuthorMeta: args.recipient.rendersAuthorMeta ?? false
184
- })
185
- ];
186
- };
187
- export {
188
- CATCH_UP_MAX_CHARS,
189
- CATCH_UP_MAX_MESSAGES,
190
- CatchUpSince,
191
- EXCERPT_CHARS,
192
- authorPrefixedContent,
193
- buildCatchUpBlock,
194
- buildPromptContent,
195
- buildServiceInputPrompt,
196
- catchUpFor,
197
- contentText,
198
- excerpt,
199
- finalAuthorOf,
200
- finalContextOf,
201
- messageRefOf,
202
- messageSummary,
203
- principalAuthorOf,
204
- renderReplyContext,
205
- systemNoticeBlock,
206
- textBlock
207
- };
208
- //# sourceMappingURL=prompt.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../src/channels/prompt.ts"],
4
- "sourcesContent": ["import type { ContentBlock } from '@agentclientprotocol/sdk/experimental/v2';\nimport {\n FinalAuthorKind,\n FinalContentRole,\n promptTextWithAuthorPrefix,\n textOf,\n withFinalMeta,\n type FinalAuthorIface,\n type FinalContextIface,\n type FinalMessageRefIface,\n} from '@finalai/acp-session';\nimport {\n RoomPrincipalType,\n MessageKind,\n ParticipantKind,\n principalDisplayName,\n RoutingMode,\n type RoomAuthIface,\n type ConversationMessageIface,\n type ParticipantIface,\n} from '@finalai/agent-provider/room-surface';\n\nexport const EXCERPT_CHARS = 280;\nexport const CATCH_UP_MAX_MESSAGES = 20;\nexport const CATCH_UP_MAX_CHARS = 4_000;\n\nexport const textBlock = (text: string): ContentBlock => ({ type: 'text', text });\n\nexport const contentText = (content: ContentBlock[]): string =>\n textOf(content, { separator: '\\n' }).trim();\n\n// A one-line description of a message for previews, excerpts and transcripts.\nexport const messageSummary = (content: ContentBlock[]): string => {\n const text = contentText(content);\n if (text.length > 0) {\n return text;\n }\n const attachments = content.filter((block) => block.type !== 'text').length;\n return attachments === 0 ? '' : `[${attachments} attachment${attachments === 1 ? '' : 's'}]`;\n};\n\nexport const excerpt = (text: string, maxChars: number = EXCERPT_CHARS): string => {\n const normalized = text.replace(/\\s+/gu, ' ').trim();\n return normalized.length <= maxChars ? normalized : `${normalized.slice(0, maxChars - 1)}\u2026`;\n};\n\nexport const finalAuthorOf = (participant: ParticipantIface): FinalAuthorIface => ({\n participantId: participant.id,\n kind: participant.kind === ParticipantKind.Agent ? FinalAuthorKind.Agent : FinalAuthorKind.User,\n displayName: participant.displayName,\n});\n\n// The author an agent sees for channel input from no member: the principal the\n// channel authenticated, named as the channel named it. `agent` marks input an\n// agent wrote elsewhere (another chat), so the recipient knows it is not a person.\nexport const principalAuthorOf = (args: {\n auth: RoomAuthIface;\n agent?: boolean;\n}): FinalAuthorIface => ({\n kind:\n args.agent === true\n ? FinalAuthorKind.Agent\n : args.auth.principalType === RoomPrincipalType.User\n ? FinalAuthorKind.User\n : FinalAuthorKind.Service,\n displayName: principalDisplayName(args.auth),\n principal: {\n principalId: args.auth.principalId,\n principalType: args.auth.principalType,\n authenticator: args.auth.authenticator,\n },\n});\n\nconst withContentRole = (block: ContentBlock, context?: FinalContextIface): ContentBlock =>\n withFinalMeta(block, { role: FinalContentRole.Context, context });\n\n// Attribution: `_meta[\"final.ai\"].author` on every block, plus a\n// `<name>: ` prefix for harnesses that do not render author meta.\nexport interface AuthorPrefixedContentArgsIface {\n content: ContentBlock[];\n author: FinalAuthorIface;\n rendersAuthorMeta: boolean;\n context?: FinalContextIface;\n}\n\nexport const authorPrefixedContent = (args: AuthorPrefixedContentArgsIface): ContentBlock[] => {\n const blocks: ContentBlock[] = args.rendersAuthorMeta\n ? args.content\n : promptTextWithAuthorPrefix(args.content, args.author.displayName);\n return blocks.map((block, index) =>\n withFinalMeta(block, { author: args.author, context: index === 0 ? args.context : undefined }),\n );\n};\n\nexport interface ReplyContextArgsIface {\n replyTo?: FinalMessageRefIface | null;\n thread?: {\n rootMessageId: string;\n rootExcerpt: string;\n rootAuthor?: FinalAuthorIface | null;\n } | null;\n quotes?: FinalMessageRefIface[];\n}\n\nexport const finalContextOf = (args: ReplyContextArgsIface): FinalContextIface | undefined => {\n const context: FinalContextIface = {};\n if (args.replyTo != null) context.replyTo = args.replyTo;\n if (args.thread != null) {\n context.thread = {\n rootMessageId: args.thread.rootMessageId,\n rootExcerpt: args.thread.rootExcerpt,\n };\n }\n if (args.quotes != null && args.quotes.length > 0) context.quotes = args.quotes;\n return Object.keys(context).length === 0 ? undefined : context;\n};\n\n// The rendered reply/thread/quote block, for harnesses that ignore\n// `_meta`. Null when the message has no context.\nexport const renderReplyContext = (args: ReplyContextArgsIface): ContentBlock | null => {\n const context = finalContextOf(args);\n if (context == null) {\n return null;\n }\n const lines: string[] = [];\n if (args.thread != null) {\n const by =\n args.thread.rootAuthor == null ? '' : ` started by ${args.thread.rootAuthor.displayName}`;\n lines.push(`In a thread${by}: \"${args.thread.rootExcerpt}\"`);\n }\n if (args.replyTo != null) {\n lines.push(\n `Replying to ${args.replyTo.author?.displayName ?? 'a message'}: \"${args.replyTo.excerpt}\"`,\n );\n }\n for (const quote of args.quotes ?? []) {\n lines.push(`Quoting ${quote.author?.displayName ?? 'a message'}: \"${quote.excerpt}\"`);\n }\n return withContentRole(textBlock(lines.join('\\n')), context);\n};\n\nexport const messageRefOf = (\n message: ConversationMessageIface,\n participants: ParticipantIface[],\n): FinalMessageRefIface => {\n const author = participants.find((participant) => participant.id === message.authorParticipantId);\n return {\n messageId: message.messageId,\n author: author == null ? null : finalAuthorOf(author),\n excerpt: excerpt(messageSummary(message.content)),\n };\n};\n\nconst transcriptLine = (\n message: ConversationMessageIface,\n participants: ParticipantIface[],\n): string => {\n const author = participants.find((participant) => participant.id === message.authorParticipantId);\n return `${author?.displayName ?? 'Someone'}: ${messageSummary(message.content)}`;\n};\n\nconst visibleForTranscript = (message: ConversationMessageIface): boolean =>\n message.kind !== MessageKind.Card && messageSummary(message.content).length > 0;\n\ninterface BoundedLinesArgsIface {\n messages: ConversationMessageIface[];\n participants: ParticipantIface[];\n maxMessages: number;\n maxChars: number;\n}\n\ninterface BoundedLinesIface {\n lines: string[];\n omitted: number;\n}\n\n// Lines from newest backwards until a bound is hit, returned oldest first.\nconst boundedLines = (args: BoundedLinesArgsIface): BoundedLinesIface => {\n const lines: string[] = [];\n let chars = 0;\n const ordered = [...args.messages].sort((left, right) => right.seq - left.seq);\n for (const message of ordered) {\n const line = transcriptLine(message, args.participants);\n if (lines.length >= args.maxMessages || chars + line.length > args.maxChars) {\n break;\n }\n lines.push(line);\n chars += line.length + 1;\n }\n return { lines: lines.reverse(), omitted: ordered.length - lines.length };\n};\n\nexport enum CatchUpSince {\n // A session that has never seen this conversation (new or reset).\n Start = 'start',\n // An agent that does not observe: since it last spoke or was mentioned.\n LastContact = 'last-contact',\n}\n\nexport interface CatchUpArgsIface {\n // Messages before the one being delivered, any order.\n messages: ConversationMessageIface[];\n participants: ParticipantIface[];\n agentParticipantId: string;\n since: CatchUpSince;\n maxMessages?: number;\n maxChars?: number;\n}\n\n// \"Earlier in this conversation, not previously shown: \u2026\", marked\n// as context. Null when there is nothing the agent has not seen.\nexport const buildCatchUpBlock = (args: CatchUpArgsIface): ContentBlock | null => {\n let unseen = args.messages.filter(\n (message) =>\n visibleForTranscript(message) && message.authorParticipantId !== args.agentParticipantId,\n );\n if (args.since === CatchUpSince.LastContact) {\n const lastContactSeq = args.messages.reduce(\n (latest, message) =>\n message.authorParticipantId === args.agentParticipantId ||\n message.mentionedParticipantIds.includes(args.agentParticipantId)\n ? Math.max(latest, message.seq)\n : latest,\n -1,\n );\n unseen = unseen.filter((message) => message.seq > lastContactSeq);\n }\n if (unseen.length === 0) {\n return null;\n }\n const { lines, omitted } = boundedLines({\n messages: unseen,\n participants: args.participants,\n maxMessages: args.maxMessages ?? CATCH_UP_MAX_MESSAGES,\n maxChars: args.maxChars ?? CATCH_UP_MAX_CHARS,\n });\n if (lines.length === 0) {\n return null;\n }\n const header = 'Earlier in this conversation, not previously shown:';\n const omittedLine =\n omitted > 0 ? [`(${omitted} earlier message${omitted === 1 ? '' : 's'} omitted)`] : [];\n return withContentRole(textBlock([header, ...omittedLine, ...lines].join('\\n')));\n};\n\n// A notice from Final itself delivered by observe: reactions, membership changes.\nexport const systemNoticeBlock = (args: { text: string }): ContentBlock =>\n withFinalMeta(textBlock(args.text), {\n author: { kind: FinalAuthorKind.Service, displayName: 'Final' },\n });\n\n// What a recipient has not seen of its conversation before a prompt: a fresh\n// session has seen nothing; a Mention agent sees only what it is prompted\n// with; everyone else has been observing.\nexport const catchUpFor = (args: {\n recipient: ParticipantIface;\n earlier: ConversationMessageIface[];\n participants: ParticipantIface[];\n}): ContentBlock | null => {\n const since =\n args.recipient.sessionId == null\n ? CatchUpSince.Start\n : args.recipient.routingMode === RoutingMode.Mention\n ? CatchUpSince.LastContact\n : null;\n if (since == null) return null;\n return buildCatchUpBlock({\n messages: args.earlier,\n participants: args.participants,\n agentParticipantId: args.recipient.id,\n since,\n });\n};\n\nexport interface PromptContentArgsIface {\n message: ConversationMessageIface;\n author: ParticipantIface;\n recipient: ParticipantIface;\n replyContext: ReplyContextArgsIface;\n catchUp: ContentBlock | null;\n}\n\n// The ACP prompt one agent receives for a conversation message.\nexport const buildPromptContent = (args: PromptContentArgsIface): ContentBlock[] => {\n const contextBlock = renderReplyContext(args.replyContext);\n const body = authorPrefixedContent({\n content:\n args.message.content.length > 0 ? args.message.content : [textBlock(args.message.body)],\n author: finalAuthorOf(args.author),\n rendersAuthorMeta: args.recipient.rendersAuthorMeta ?? false,\n context: finalContextOf(args.replyContext),\n });\n return [\n ...(args.catchUp == null ? [] : [args.catchUp]),\n ...(contextBlock == null ? [] : [contextBlock]),\n ...body,\n ];\n};\n\nexport interface ServiceInputPromptArgsIface {\n content: ContentBlock[];\n // Channel-supplied context lines, marked as context before the input.\n context?: string[];\n author: FinalAuthorIface;\n recipient: ParticipantIface;\n // The room's latest messages when the input is delivered, any order.\n earlier: ConversationMessageIface[];\n participants: ParticipantIface[];\n}\n\n// The ACP prompt a room's agent receives for channel input: what it has not seen\n// of the room up to its latest message, then the input attributed to its principal.\nexport const buildServiceInputPrompt = (args: ServiceInputPromptArgsIface): ContentBlock[] => {\n const catchUp = catchUpFor({\n recipient: args.recipient,\n earlier: args.earlier,\n participants: args.participants,\n });\n return [\n ...(catchUp == null ? [] : [catchUp]),\n ...(args.context ?? []).map((text) => withContentRole(textBlock(text))),\n ...authorPrefixedContent({\n content: args.content,\n author: args.author,\n rendersAuthorMeta: args.recipient.rendersAuthorMeta ?? false,\n }),\n ];\n};\n"],
5
- "mappings": "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",
6
- "names": ["CatchUpSince"]
7
- }
@@ -1,5 +0,0 @@
1
- import { type ParticipantIface, type RouteArgsIface, type RouteDecisionIface } from '@finalai/agent-provider/room-surface';
2
- export declare const MAX_AGENT_HOP_DEPTH = 2;
3
- export declare const effectiveDefaultAgent: (participants: ParticipantIface[]) => ParticipantIface | null;
4
- export declare const routeMessage: (args: RouteArgsIface) => RouteDecisionIface[];
5
- export declare const routeToParticipant: (participantId: string) => (args: RouteArgsIface) => RouteDecisionIface[];