@finalai/agents 0.8.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.

Potentially problematic release.


This version of @finalai/agents might be problematic. Click here for more details.

Files changed (153) hide show
  1. package/README.md +30 -0
  2. package/dist/modules/agent-client/acp-frames.d.mts +19 -0
  3. package/dist/modules/agent-client/acp-frames.mjs +49 -0
  4. package/dist/modules/agent-client/acp-frames.mjs.map +7 -0
  5. package/dist/modules/agent-client/acp.d.mts +43 -0
  6. package/dist/modules/agent-client/acp.mjs +76 -0
  7. package/dist/modules/agent-client/acp.mjs.map +7 -0
  8. package/dist/modules/agent-client/async-queue.d.mts +10 -0
  9. package/dist/modules/agent-client/async-queue.mjs +66 -0
  10. package/dist/modules/agent-client/async-queue.mjs.map +7 -0
  11. package/dist/modules/agent-client/build.d.mts +107 -0
  12. package/dist/modules/agent-client/build.mjs +222 -0
  13. package/dist/modules/agent-client/build.mjs.map +7 -0
  14. package/dist/modules/agent-client/client.d.mts +111 -0
  15. package/dist/modules/agent-client/client.mjs +198 -0
  16. package/dist/modules/agent-client/client.mjs.map +7 -0
  17. package/dist/modules/agent-client/collection-events.d.mts +35 -0
  18. package/dist/modules/agent-client/collection-events.mjs +142 -0
  19. package/dist/modules/agent-client/collection-events.mjs.map +7 -0
  20. package/dist/modules/agent-client/config-options.d.mts +24 -0
  21. package/dist/modules/agent-client/config-options.mjs +49 -0
  22. package/dist/modules/agent-client/config-options.mjs.map +7 -0
  23. package/dist/modules/agent-client/context.d.mts +31 -0
  24. package/dist/modules/agent-client/context.mjs +11 -0
  25. package/dist/modules/agent-client/context.mjs.map +7 -0
  26. package/dist/modules/agent-client/conversations.d.mts +385 -0
  27. package/dist/modules/agent-client/conversations.mjs +1156 -0
  28. package/dist/modules/agent-client/conversations.mjs.map +7 -0
  29. package/dist/modules/agent-client/errors.d.mts +85 -0
  30. package/dist/modules/agent-client/errors.mjs +94 -0
  31. package/dist/modules/agent-client/errors.mjs.map +7 -0
  32. package/dist/modules/agent-client/event-stream.d.mts +14 -0
  33. package/dist/modules/agent-client/event-stream.mjs +89 -0
  34. package/dist/modules/agent-client/event-stream.mjs.map +7 -0
  35. package/dist/modules/agent-client/frame-stream.d.mts +51 -0
  36. package/dist/modules/agent-client/frame-stream.mjs +333 -0
  37. package/dist/modules/agent-client/frame-stream.mjs.map +7 -0
  38. package/dist/modules/agent-client/http.d.mts +68 -0
  39. package/dist/modules/agent-client/http.mjs +168 -0
  40. package/dist/modules/agent-client/http.mjs.map +7 -0
  41. package/dist/modules/agent-client/index.d.mts +17 -0
  42. package/dist/modules/agent-client/index.mjs +86 -0
  43. package/dist/modules/agent-client/index.mjs.map +7 -0
  44. package/dist/modules/agent-client/live-stream.d.mts +18 -0
  45. package/dist/modules/agent-client/live-stream.mjs +94 -0
  46. package/dist/modules/agent-client/live-stream.mjs.map +7 -0
  47. package/dist/modules/agent-client/realtime.d.mts +72 -0
  48. package/dist/modules/agent-client/realtime.mjs +186 -0
  49. package/dist/modules/agent-client/realtime.mjs.map +7 -0
  50. package/dist/modules/agent-client/sandbox-uri.d.mts +19 -0
  51. package/dist/modules/agent-client/sandbox-uri.mjs +43 -0
  52. package/dist/modules/agent-client/sandbox-uri.mjs.map +7 -0
  53. package/dist/modules/agent-client/sessions.d.mts +124 -0
  54. package/dist/modules/agent-client/sessions.mjs +350 -0
  55. package/dist/modules/agent-client/sessions.mjs.map +7 -0
  56. package/dist/modules/agent-client/test-fakes.d.mts +40 -0
  57. package/dist/modules/agent-client/test-fakes.mjs +94 -0
  58. package/dist/modules/agent-client/test-fakes.mjs.map +7 -0
  59. package/dist/modules/authoring/approval.d.mts +1 -0
  60. package/dist/modules/authoring/approval.mjs +2 -0
  61. package/dist/modules/authoring/approval.mjs.map +7 -0
  62. package/dist/modules/authoring/channels.d.mts +1 -0
  63. package/dist/modules/authoring/channels.mjs +2 -0
  64. package/dist/modules/authoring/channels.mjs.map +7 -0
  65. package/dist/modules/authoring/final-channel.d.mts +1 -0
  66. package/dist/modules/authoring/final-channel.mjs +2 -0
  67. package/dist/modules/authoring/final-channel.mjs.map +7 -0
  68. package/dist/modules/authoring/hooks.d.mts +1 -0
  69. package/dist/modules/authoring/hooks.mjs +2 -0
  70. package/dist/modules/authoring/hooks.mjs.map +7 -0
  71. package/dist/modules/authoring/index.d.mts +1 -0
  72. package/dist/modules/authoring/index.mjs +2 -0
  73. package/dist/modules/authoring/index.mjs.map +7 -0
  74. package/dist/modules/authoring/instructions.d.mts +1 -0
  75. package/dist/modules/authoring/instructions.mjs +2 -0
  76. package/dist/modules/authoring/instructions.mjs.map +7 -0
  77. package/dist/modules/authoring/providers.d.mts +2 -0
  78. package/dist/modules/authoring/providers.mjs +1 -0
  79. package/dist/modules/authoring/providers.mjs.map +7 -0
  80. package/dist/modules/authoring/tools.d.mts +1 -0
  81. package/dist/modules/authoring/tools.mjs +2 -0
  82. package/dist/modules/authoring/tools.mjs.map +7 -0
  83. package/dist/modules/cli/build.d.mts +22 -0
  84. package/dist/modules/cli/build.mjs +77 -0
  85. package/dist/modules/cli/build.mjs.map +7 -0
  86. package/dist/modules/cli/channel-socket.d.mts +9 -0
  87. package/dist/modules/cli/channel-socket.mjs +114 -0
  88. package/dist/modules/cli/channel-socket.mjs.map +7 -0
  89. package/dist/modules/cli/cli.d.mts +16 -0
  90. package/dist/modules/cli/cli.mjs +151 -0
  91. package/dist/modules/cli/cli.mjs.map +7 -0
  92. package/dist/modules/cli/conformance.d.mts +36 -0
  93. package/dist/modules/cli/conformance.mjs +220 -0
  94. package/dist/modules/cli/conformance.mjs.map +7 -0
  95. package/dist/modules/cli/dev.d.mts +24 -0
  96. package/dist/modules/cli/dev.mjs +263 -0
  97. package/dist/modules/cli/dev.mjs.map +7 -0
  98. package/dist/modules/cli/files.d.mts +18 -0
  99. package/dist/modules/cli/files.mjs +66 -0
  100. package/dist/modules/cli/files.mjs.map +7 -0
  101. package/dist/modules/cli/harness-descriptions.d.mts +20 -0
  102. package/dist/modules/cli/harness-descriptions.mjs +70 -0
  103. package/dist/modules/cli/harness-descriptions.mjs.map +7 -0
  104. package/dist/modules/cli/main.d.mts +2 -0
  105. package/dist/modules/cli/main.mjs +20 -0
  106. package/dist/modules/cli/main.mjs.map +7 -0
  107. package/dist/modules/cli/output.d.mts +14 -0
  108. package/dist/modules/cli/output.mjs +94 -0
  109. package/dist/modules/cli/output.mjs.map +7 -0
  110. package/dist/modules/cli/publish.d.mts +14 -0
  111. package/dist/modules/cli/publish.mjs +89 -0
  112. package/dist/modules/cli/publish.mjs.map +7 -0
  113. package/dist/modules/compile.d.mts +3 -0
  114. package/dist/modules/compile.mjs +62 -0
  115. package/dist/modules/compile.mjs.map +7 -0
  116. package/dist/modules/harnesses.d.mts +1 -0
  117. package/dist/modules/harnesses.mjs +2 -0
  118. package/dist/modules/harnesses.mjs.map +7 -0
  119. package/dist/modules/index.browser.d.mts +4 -0
  120. package/dist/modules/index.browser.mjs +8 -0
  121. package/dist/modules/index.browser.mjs.map +7 -0
  122. package/dist/modules/index.d.mts +3 -0
  123. package/dist/modules/index.mjs +6 -0
  124. package/dist/modules/index.mjs.map +7 -0
  125. package/dist/modules/models.d.mts +1 -0
  126. package/dist/modules/models.mjs +2 -0
  127. package/dist/modules/models.mjs.map +7 -0
  128. package/dist/modules/public.d.mts +6 -0
  129. package/dist/modules/public.mjs +68 -0
  130. package/dist/modules/public.mjs.map +7 -0
  131. package/dist/modules/sandboxes.d.mts +1 -0
  132. package/dist/modules/sandboxes.mjs +2 -0
  133. package/dist/modules/sandboxes.mjs.map +7 -0
  134. package/examples/custom-harness/README.md +16 -0
  135. package/examples/custom-harness/agent.ts +154 -0
  136. package/examples/custom-sandbox/README.md +12 -0
  137. package/examples/custom-sandbox/agent.ts +14 -0
  138. package/examples/custom-sandbox/sandbox.ts +22 -0
  139. package/examples/release-scout/README.md +11 -0
  140. package/examples/release-scout/agent/agent.ts +22 -0
  141. package/examples/release-scout/agent/channels/github-signature.ts +27 -0
  142. package/examples/release-scout/agent/channels/github.ts +38 -0
  143. package/examples/release-scout/agent/connections/linear.ts +9 -0
  144. package/examples/release-scout/agent/hooks/audit.ts +24 -0
  145. package/examples/release-scout/agent/instructions/org-context.ts +26 -0
  146. package/examples/release-scout/agent/instructions.md +2 -0
  147. package/examples/release-scout/agent/sandbox.ts +20 -0
  148. package/examples/release-scout/agent/schedules/daily-digest.md +7 -0
  149. package/examples/release-scout/agent/skills/triage/SKILL.md +8 -0
  150. package/examples/release-scout/agent/skills/triage/checklist.md +3 -0
  151. package/examples/release-scout/agent/tools/lookup_release_notes.ts +24 -0
  152. package/examples/release-scout/client.ts +123 -0
  153. package/package.json +126 -0
@@ -0,0 +1,263 @@
1
+ import {
2
+ DiagnosticSeverity,
3
+ hasErrors,
4
+ loadBundleInLocalIsolate
5
+ } from "@finalai/agent-definition/compiler";
6
+ import { ProviderRefKind } from "@finalai/agent-provider";
7
+ import { openChannelSocket } from "@finalai/agent-provider/local-channel-socket";
8
+ import { watch } from "node:fs";
9
+ import { createServer } from "node:http";
10
+ import * as z from "zod";
11
+ import { compile } from "../compile.mjs";
12
+ import { attachDevChannelSockets } from "./channel-socket.mjs";
13
+ import { diagnosticLine } from "./output.mjs";
14
+ const DEFAULT_DEV_PORT = 3e3;
15
+ const localSecretsSchema = z.record(z.string(), z.string());
16
+ const listeningAddressSchema = z.object({ port: z.number() });
17
+ const parseLocalSecrets = (text) => {
18
+ if (text == null || text.length === 0) return {};
19
+ try {
20
+ const parsed = localSecretsSchema.safeParse(JSON.parse(text));
21
+ return parsed.success ? parsed.data : null;
22
+ } catch {
23
+ return null;
24
+ }
25
+ };
26
+ const readBody = async (request) => {
27
+ const chunks = [];
28
+ for await (const chunk of request) chunks.push(Buffer.from(chunk));
29
+ return Buffer.concat(chunks);
30
+ };
31
+ const toRequest = async (request, origin) => {
32
+ const method = request.method ?? "GET";
33
+ const headers = new Headers();
34
+ for (const [name, value] of Object.entries(request.headers)) {
35
+ if (value == null) continue;
36
+ for (const item of Array.isArray(value) ? value : [value]) headers.append(name, item);
37
+ }
38
+ const body = method === "GET" || method === "HEAD" ? null : await readBody(request);
39
+ return new Request(new URL(request.url ?? "/", origin), {
40
+ method,
41
+ headers,
42
+ body: body == null || body.byteLength === 0 ? null : new Uint8Array(body)
43
+ });
44
+ };
45
+ const writeResponse = async (response, out) => {
46
+ out.statusCode = response.status;
47
+ response.headers.forEach((value, name) => out.setHeader(name, value));
48
+ out.end(Buffer.from(await response.arrayBuffer()));
49
+ };
50
+ const plain = (out, status, text) => {
51
+ out.statusCode = status;
52
+ out.setHeader("content-type", "text/plain; charset=utf-8");
53
+ out.end(`${text}
54
+ `);
55
+ };
56
+ const splitPath = (pathname) => {
57
+ const match = /^\/([^/]+)(\/.*)?$/.exec(pathname);
58
+ if (match?.[1] == null) return null;
59
+ return { stem: decodeURIComponent(match[1]), path: match[2] ?? "/" };
60
+ };
61
+ const loadAgent = async (args) => {
62
+ const result = await compile({ dir: args.dir });
63
+ for (const item of result.diagnostics) {
64
+ (item.severity === DiagnosticSeverity.Error ? args.output.stderr : args.output.stdout)(
65
+ diagnosticLine(item)
66
+ );
67
+ }
68
+ if (hasErrors(result.diagnostics) || result.manifest == null) return null;
69
+ const bundle = result.bundle == null ? null : await loadBundleInLocalIsolate(
70
+ result.bundle.code,
71
+ args.fetch == null ? {} : { fetch: args.fetch }
72
+ );
73
+ const channels = /* @__PURE__ */ new Map();
74
+ const routes = [];
75
+ for (const binding of result.manifest.channels) {
76
+ if (binding.channel.kind !== ProviderRefKind.Bundle) continue;
77
+ channels.set(binding.key, binding.channel.export);
78
+ for (const route of result.bundle?.channelRoutes[binding.channel.export] ?? []) {
79
+ routes.push({ stem: binding.key, method: route.method, path: route.path });
80
+ }
81
+ }
82
+ return { manifest: result.manifest, bundle, channels, routes };
83
+ };
84
+ const startDevServer = async (args) => {
85
+ const { output } = args;
86
+ let agent = null;
87
+ let origin = "";
88
+ const printRoutes = () => {
89
+ if (agent == null) return;
90
+ if (agent.routes.length === 0) {
91
+ output.stdout("no custom channel routes (channels/*.ts) to serve");
92
+ return;
93
+ }
94
+ for (const route of agent.routes) {
95
+ output.stdout(` ${route.method} ${origin}/${route.stem}${route.path}`);
96
+ }
97
+ };
98
+ const reload = async () => {
99
+ const next = await loadAgent({ dir: args.dir, output, fetch: args.fetch });
100
+ if (next == null) {
101
+ output.stderr(
102
+ agent == null ? "compile failed" : "compile failed; still serving the last bundle"
103
+ );
104
+ return false;
105
+ }
106
+ agent = next;
107
+ return true;
108
+ };
109
+ const handle = async (request, out) => {
110
+ const current = agent;
111
+ const target = splitPath(new URL(request.url ?? "/", origin).pathname);
112
+ const exportName = target == null ? null : current?.channels.get(target.stem) ?? null;
113
+ if (current?.bundle == null || target == null || exportName == null) {
114
+ plain(out, 404, "no custom channel route here");
115
+ return;
116
+ }
117
+ const allowed = new Set(current.manifest.secrets);
118
+ const stem = target.stem;
119
+ const response = await current.bundle.runtime.handleChannelRoute({
120
+ export: exportName,
121
+ request: await toRequest(request, origin),
122
+ path: target.path,
123
+ secrets: {
124
+ get: async (name) => {
125
+ if (!allowed.has(name)) {
126
+ output.stderr(`secrets.get(${JSON.stringify(name)}): not in the manifest's secrets`);
127
+ return null;
128
+ }
129
+ return args.secrets[name] ?? null;
130
+ }
131
+ },
132
+ receive: async (input) => {
133
+ output.stdout(`receive (${stem}): ${JSON.stringify(input)}`);
134
+ return { conversationId: "local" };
135
+ }
136
+ });
137
+ if (response == null) {
138
+ plain(out, 404, `no ${request.method ?? "GET"} ${target.path} route on channel ${stem}`);
139
+ return;
140
+ }
141
+ await writeResponse(response, out);
142
+ };
143
+ const server = createServer((request, out) => {
144
+ handle(request, out).catch((cause) => {
145
+ output.stderr(`route failed: ${cause instanceof Error ? cause.message : String(cause)}`);
146
+ if (!out.headersSent) plain(out, 500, "route failed");
147
+ else out.end();
148
+ });
149
+ });
150
+ const channelSockets = attachDevChannelSockets({
151
+ server,
152
+ log: output.stderr,
153
+ open: async (incoming, signal) => {
154
+ const current = agent;
155
+ const target = splitPath(new URL(incoming.url ?? "/", origin).pathname);
156
+ const exportName = target == null ? null : current?.channels.get(target.stem);
157
+ if (current?.bundle == null || target == null || exportName == null)
158
+ return {
159
+ ok: false,
160
+ response: new Response("No custom channel socket route", { status: 404 })
161
+ };
162
+ const bundle = current.bundle;
163
+ const allowed = new Set(current.manifest.secrets);
164
+ const request = new Request(await toRequest(incoming, origin), { signal });
165
+ return openChannelSocket({
166
+ signal,
167
+ context: {
168
+ request,
169
+ secrets: {
170
+ get: async (name) => allowed.has(name) ? args.secrets[name] ?? null : null
171
+ },
172
+ receive: async (input) => {
173
+ output.stdout(`receive (${target.stem}): ${JSON.stringify(input)}`);
174
+ return { conversationId: "local" };
175
+ }
176
+ },
177
+ handler: async (ctx) => {
178
+ const response = await bundle.runtime.handleChannelSocket({
179
+ export: exportName,
180
+ path: target.path,
181
+ ...ctx
182
+ });
183
+ return response === null ? new Response("No custom channel socket route", { status: 404 }) : response;
184
+ }
185
+ });
186
+ }
187
+ });
188
+ const hostname = args.hostname ?? "localhost";
189
+ await new Promise((done, fail) => {
190
+ server.once("error", fail);
191
+ server.listen(args.port, hostname, () => {
192
+ server.off("error", fail);
193
+ done();
194
+ });
195
+ });
196
+ const port = listeningAddressSchema.safeParse(server.address()).data?.port ?? args.port;
197
+ origin = `http://${hostname}:${port}`;
198
+ await reload();
199
+ output.stdout(`serving ${args.dir} at ${origin}`);
200
+ printRoutes();
201
+ return {
202
+ url: origin,
203
+ reload: async () => {
204
+ const ok = await reload();
205
+ if (ok) printRoutes();
206
+ return ok;
207
+ },
208
+ close: async () => {
209
+ await channelSockets.close();
210
+ await new Promise((done) => {
211
+ server.closeAllConnections();
212
+ server.close(() => done());
213
+ });
214
+ }
215
+ };
216
+ };
217
+ const RECOMPILE_DEBOUNCE_MS = 150;
218
+ const isBuildOutput = (path) => path.startsWith(".final") || path.split(/[\\/]/).includes("node_modules");
219
+ const runDev = async (args) => {
220
+ const secrets = parseLocalSecrets(args.env["AGENT_LOCAL_SECRETS_JSON"]);
221
+ if (secrets == null) {
222
+ args.output.stderr("error: AGENT_LOCAL_SECRETS_JSON must be a JSON object of name \u2192 value");
223
+ return 2;
224
+ }
225
+ let server;
226
+ try {
227
+ server = await startDevServer({ dir: args.dir, port: args.port, secrets, output: args.output });
228
+ } catch (cause) {
229
+ args.output.stderr(`error: ${cause instanceof Error ? cause.message : String(cause)}`);
230
+ return 1;
231
+ }
232
+ let timer = null;
233
+ let watcher = null;
234
+ try {
235
+ watcher = watch(args.dir, { recursive: true }, (_event, file) => {
236
+ if (file != null && isBuildOutput(file)) return;
237
+ if (timer != null) clearTimeout(timer);
238
+ timer = setTimeout(() => {
239
+ args.output.stdout("change detected; recompiling");
240
+ void server.reload();
241
+ }, RECOMPILE_DEBOUNCE_MS);
242
+ });
243
+ } catch (cause) {
244
+ args.output.stderr(
245
+ `not watching for changes: ${cause instanceof Error ? cause.message : String(cause)}`
246
+ );
247
+ }
248
+ await new Promise((done) => {
249
+ if (args.signal.aborted) done();
250
+ else args.signal.addEventListener("abort", () => done(), { once: true });
251
+ });
252
+ if (timer != null) clearTimeout(timer);
253
+ watcher?.close();
254
+ await server.close();
255
+ return 0;
256
+ };
257
+ export {
258
+ DEFAULT_DEV_PORT,
259
+ parseLocalSecrets,
260
+ runDev,
261
+ startDevServer
262
+ };
263
+ //# sourceMappingURL=dev.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/dev.ts"],
4
+ "sourcesContent": ["import {\n DiagnosticSeverity,\n hasErrors,\n loadBundleInLocalIsolate,\n type LoadedBundleIface,\n} from '@finalai/agent-definition/compiler';\nimport { ProviderRefKind, type AgentManifestIface, type JsonValue } from '@finalai/agent-provider';\nimport { openChannelSocket } from '@finalai/agent-provider/local-channel-socket';\nimport { watch, type FSWatcher } from 'node:fs';\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport * as z from 'zod';\nimport { compile } from \"../compile.mjs\";\nimport { attachDevChannelSockets } from \"./channel-socket.mjs\";\nimport { diagnosticLine, type OutputIface } from \"./output.mjs\";\n\n// `final agents dev`: serves the agent's custom channel\n// routes at http://localhost:<port>/<channel-stem><path>, the local\n// counterpart of https://agents.final.ai/<org>/<agent>/<channel-stem><path>.\n// Routes run in a local stand-in for the Worker isolate (a realm with Worker\n// globals only). There is no platform behind it: `receive` prints what the\n// route would deliver, and `secrets.get` reads AGENT_LOCAL_SECRETS_JSON,\n// limited to the manifest's secrets. Edits recompile and swap the bundle.\n\nexport const DEFAULT_DEV_PORT = 3000;\n\nconst localSecretsSchema = z.record(z.string(), z.string());\n\n// node:http's address() for a TCP listener.\nconst listeningAddressSchema = z.object({ port: z.number() });\n\nexport const parseLocalSecrets = (text: string | undefined): Record<string, string> | null => {\n if (text == null || text.length === 0) return {};\n try {\n const parsed = localSecretsSchema.safeParse(JSON.parse(text));\n return parsed.success ? parsed.data : null;\n } catch {\n return null;\n }\n};\n\ninterface LoadedAgentIface {\n manifest: AgentManifestIface;\n bundle: LoadedBundleIface | null;\n // Channel stem \u2192 bundle export, for the custom channels the bundle serves.\n channels: Map<string, string>;\n routes: { stem: string; method: string; path: string }[];\n}\n\nexport interface DevServerArgsIface {\n dir: string;\n port: number;\n hostname?: string;\n secrets: Record<string, string>;\n output: OutputIface;\n // The isolate realm's fetch (tests).\n fetch?: typeof fetch;\n}\n\nexport interface DevServerIface {\n url: string;\n // Recompiles; false (and the previous bundle kept) when the compile fails.\n reload(): Promise<boolean>;\n close(): Promise<void>;\n}\n\nconst readBody = async (request: IncomingMessage): Promise<Buffer> => {\n const chunks: Buffer[] = [];\n for await (const chunk of request) chunks.push(Buffer.from(chunk));\n return Buffer.concat(chunks);\n};\n\nconst toRequest = async (request: IncomingMessage, origin: string): Promise<Request> => {\n const method = request.method ?? 'GET';\n const headers = new Headers();\n for (const [name, value] of Object.entries(request.headers)) {\n if (value == null) continue;\n for (const item of Array.isArray(value) ? value : [value]) headers.append(name, item);\n }\n const body = method === 'GET' || method === 'HEAD' ? null : await readBody(request);\n return new Request(new URL(request.url ?? '/', origin), {\n method,\n headers,\n body: body == null || body.byteLength === 0 ? null : new Uint8Array(body),\n });\n};\n\nconst writeResponse = async (response: Response, out: ServerResponse): Promise<void> => {\n out.statusCode = response.status;\n response.headers.forEach((value, name) => out.setHeader(name, value));\n out.end(Buffer.from(await response.arrayBuffer()));\n};\n\nconst plain = (out: ServerResponse, status: number, text: string): void => {\n out.statusCode = status;\n out.setHeader('content-type', 'text/plain; charset=utf-8');\n out.end(`${text}\\n`);\n};\n\n// `/<stem><path>`: the first segment names the channel, the rest is its route path.\nconst splitPath = (pathname: string): { stem: string; path: string } | null => {\n const match = /^\\/([^/]+)(\\/.*)?$/.exec(pathname);\n if (match?.[1] == null) return null;\n return { stem: decodeURIComponent(match[1]), path: match[2] ?? '/' };\n};\n\nconst loadAgent = async (args: {\n dir: string;\n output: OutputIface;\n fetch?: typeof fetch;\n}): Promise<LoadedAgentIface | null> => {\n const result = await compile({ dir: args.dir });\n for (const item of result.diagnostics) {\n (item.severity === DiagnosticSeverity.Error ? args.output.stderr : args.output.stdout)(\n diagnosticLine(item),\n );\n }\n if (hasErrors(result.diagnostics) || result.manifest == null) return null;\n const bundle =\n result.bundle == null\n ? null\n : await loadBundleInLocalIsolate(\n result.bundle.code,\n args.fetch == null ? {} : { fetch: args.fetch },\n );\n const channels = new Map<string, string>();\n const routes: LoadedAgentIface['routes'] = [];\n for (const binding of result.manifest.channels) {\n if (binding.channel.kind !== ProviderRefKind.Bundle) continue;\n channels.set(binding.key, binding.channel.export);\n for (const route of result.bundle?.channelRoutes[binding.channel.export] ?? []) {\n routes.push({ stem: binding.key, method: route.method, path: route.path });\n }\n }\n return { manifest: result.manifest, bundle, channels, routes };\n};\n\nexport const startDevServer = async (args: DevServerArgsIface): Promise<DevServerIface> => {\n const { output } = args;\n let agent: LoadedAgentIface | null = null;\n let origin = '';\n\n const printRoutes = (): void => {\n if (agent == null) return;\n if (agent.routes.length === 0) {\n output.stdout('no custom channel routes (channels/*.ts) to serve');\n return;\n }\n for (const route of agent.routes) {\n output.stdout(` ${route.method} ${origin}/${route.stem}${route.path}`);\n }\n };\n\n const reload = async (): Promise<boolean> => {\n const next = await loadAgent({ dir: args.dir, output, fetch: args.fetch });\n if (next == null) {\n output.stderr(\n agent == null ? 'compile failed' : 'compile failed; still serving the last bundle',\n );\n return false;\n }\n agent = next;\n return true;\n };\n\n const handle = async (request: IncomingMessage, out: ServerResponse): Promise<void> => {\n const current = agent;\n const target = splitPath(new URL(request.url ?? '/', origin).pathname);\n const exportName = target == null ? null : (current?.channels.get(target.stem) ?? null);\n if (current?.bundle == null || target == null || exportName == null) {\n plain(out, 404, 'no custom channel route here');\n return;\n }\n const allowed = new Set(current.manifest.secrets);\n const stem = target.stem;\n const response = await current.bundle.runtime.handleChannelRoute({\n export: exportName,\n request: await toRequest(request, origin),\n path: target.path,\n secrets: {\n get: async (name) => {\n if (!allowed.has(name)) {\n output.stderr(`secrets.get(${JSON.stringify(name)}): not in the manifest's secrets`);\n return null;\n }\n return args.secrets[name] ?? null;\n },\n },\n receive: async (input: JsonValue) => {\n output.stdout(`receive (${stem}): ${JSON.stringify(input)}`);\n return { conversationId: 'local' };\n },\n });\n if (response == null) {\n plain(out, 404, `no ${request.method ?? 'GET'} ${target.path} route on channel ${stem}`);\n return;\n }\n await writeResponse(response, out);\n };\n\n const server = createServer((request, out) => {\n handle(request, out).catch((cause: unknown) => {\n output.stderr(`route failed: ${cause instanceof Error ? cause.message : String(cause)}`);\n if (!out.headersSent) plain(out, 500, 'route failed');\n else out.end();\n });\n });\n const channelSockets = attachDevChannelSockets({\n server,\n log: output.stderr,\n open: async (incoming, signal) => {\n const current = agent;\n const target = splitPath(new URL(incoming.url ?? '/', origin).pathname);\n const exportName = target == null ? null : current?.channels.get(target.stem);\n if (current?.bundle == null || target == null || exportName == null)\n return {\n ok: false,\n response: new Response('No custom channel socket route', { status: 404 }),\n };\n const bundle = current.bundle;\n const allowed = new Set(current.manifest.secrets);\n const request = new Request(await toRequest(incoming, origin), { signal });\n return openChannelSocket({\n signal,\n context: {\n request,\n secrets: {\n get: async (name) => (allowed.has(name) ? (args.secrets[name] ?? null) : null),\n },\n receive: async (input) => {\n output.stdout(`receive (${target.stem}): ${JSON.stringify(input)}`);\n return { conversationId: 'local' };\n },\n },\n handler: async (ctx) => {\n const response = await bundle.runtime.handleChannelSocket({\n export: exportName,\n path: target.path,\n ...ctx,\n });\n return response === null\n ? new Response('No custom channel socket route', { status: 404 })\n : response;\n },\n });\n },\n });\n const hostname = args.hostname ?? 'localhost';\n await new Promise<void>((done, fail) => {\n server.once('error', fail);\n server.listen(args.port, hostname, () => {\n server.off('error', fail);\n done();\n });\n });\n const port = listeningAddressSchema.safeParse(server.address()).data?.port ?? args.port;\n origin = `http://${hostname}:${port}`;\n await reload();\n output.stdout(`serving ${args.dir} at ${origin}`);\n printRoutes();\n\n return {\n url: origin,\n reload: async () => {\n const ok = await reload();\n if (ok) printRoutes();\n return ok;\n },\n close: async () => {\n await channelSockets.close();\n await new Promise<void>((done) => {\n server.closeAllConnections();\n server.close(() => done());\n });\n },\n };\n};\n\nconst RECOMPILE_DEBOUNCE_MS = 150;\n\nconst isBuildOutput = (path: string): boolean =>\n path.startsWith('.final') || path.split(/[\\\\/]/).includes('node_modules');\n\nexport const runDev = async (args: {\n dir: string;\n port: number;\n env: Record<string, string | undefined>;\n output: OutputIface;\n signal: AbortSignal;\n}): Promise<number> => {\n const secrets = parseLocalSecrets(args.env['AGENT_LOCAL_SECRETS_JSON']);\n if (secrets == null) {\n args.output.stderr('error: AGENT_LOCAL_SECRETS_JSON must be a JSON object of name \u2192 value');\n return 2;\n }\n let server: DevServerIface;\n try {\n server = await startDevServer({ dir: args.dir, port: args.port, secrets, output: args.output });\n } catch (cause) {\n args.output.stderr(`error: ${cause instanceof Error ? cause.message : String(cause)}`);\n return 1;\n }\n let timer: ReturnType<typeof setTimeout> | null = null;\n let watcher: FSWatcher | null = null;\n try {\n watcher = watch(args.dir, { recursive: true }, (_event, file) => {\n if (file != null && isBuildOutput(file)) return;\n if (timer != null) clearTimeout(timer);\n timer = setTimeout(() => {\n args.output.stdout('change detected; recompiling');\n void server.reload();\n }, RECOMPILE_DEBOUNCE_MS);\n });\n } catch (cause) {\n args.output.stderr(\n `not watching for changes: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n }\n await new Promise<void>((done) => {\n if (args.signal.aborted) done();\n else args.signal.addEventListener('abort', () => done(), { once: true });\n });\n if (timer != null) clearTimeout(timer);\n watcher?.close();\n await server.close();\n return 0;\n};\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,18 @@
1
+ export type ListFiles = (dir: string) => Promise<string[]>;
2
+ export declare const gitListFiles: ListFiles;
3
+ export interface LocalFilesIface {
4
+ files: Record<string, string>;
5
+ problems: string[];
6
+ }
7
+ export declare const readLocalFiles: (args: {
8
+ dir: string;
9
+ listFiles: ListFiles;
10
+ }) => Promise<LocalFilesIface>;
11
+ export interface FileChangeIface {
12
+ path: string;
13
+ content: string | null;
14
+ }
15
+ export declare const fileChanges: (args: {
16
+ local: Record<string, string>;
17
+ remote: Record<string, string>;
18
+ }) => FileChangeIface[];
@@ -0,0 +1,66 @@
1
+ import { execFile } from "node:child_process";
2
+ import { lstat, readFile, realpath } from "node:fs/promises";
3
+ import { isAbsolute, join, relative } from "node:path";
4
+ import { promisify } from "node:util";
5
+ const run = promisify(execFile);
6
+ const gitListFiles = async (dir) => {
7
+ try {
8
+ const { stdout } = await run(
9
+ "git",
10
+ ["ls-files", "-z", "--cached", "--others", "--exclude-standard", "--deduplicate"],
11
+ { cwd: dir, maxBuffer: 64 * 1024 * 1024 }
12
+ );
13
+ return stdout.split("\0").filter((path) => path.length > 0);
14
+ } catch (cause) {
15
+ throw new Error(
16
+ `${dir} is not inside a git checkout (${cause instanceof Error ? cause.message.trim() : String(cause)})`,
17
+ { cause }
18
+ );
19
+ }
20
+ };
21
+ const isBuildOutput = (path) => path === ".final/compile" || path.startsWith(".final/compile/");
22
+ const isMissing = (cause) => cause instanceof Error && "code" in cause && cause.code === "ENOENT";
23
+ const readLocalFiles = async (args) => {
24
+ const decoder = new TextDecoder("utf-8", { fatal: true });
25
+ const files = {};
26
+ const problems = [];
27
+ const root = await realpath(args.dir);
28
+ for (const path of (await args.listFiles(args.dir)).toSorted()) {
29
+ if (isBuildOutput(path)) continue;
30
+ let bytes;
31
+ try {
32
+ const localPath = join(root, ...path.split("/"));
33
+ const location = relative(root, await realpath(localPath));
34
+ if (isAbsolute(location) || location === ".." || location.startsWith("../") || (await lstat(localPath)).isSymbolicLink()) {
35
+ problems.push(`${path} is a symlink or resolves outside the agent directory`);
36
+ continue;
37
+ }
38
+ bytes = await readFile(localPath);
39
+ } catch (cause) {
40
+ if (isMissing(cause)) continue;
41
+ throw cause;
42
+ }
43
+ try {
44
+ files[path] = decoder.decode(bytes);
45
+ } catch {
46
+ problems.push(`${path} is not UTF-8 text; agent directories hold text files only`);
47
+ }
48
+ }
49
+ return { files, problems };
50
+ };
51
+ const fileChanges = (args) => {
52
+ const changes = [];
53
+ for (const [path, content] of Object.entries(args.local)) {
54
+ if (args.remote[path] !== content) changes.push({ path, content });
55
+ }
56
+ for (const path of Object.keys(args.remote)) {
57
+ if (!(path in args.local)) changes.push({ path, content: null });
58
+ }
59
+ return changes.toSorted((a, b) => a.path.localeCompare(b.path));
60
+ };
61
+ export {
62
+ fileChanges,
63
+ gitListFiles,
64
+ readLocalFiles
65
+ };
66
+ //# sourceMappingURL=files.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/files.ts"],
4
+ "sourcesContent": ["import { execFile } from 'node:child_process';\nimport { lstat, readFile, realpath } from 'node:fs/promises';\nimport { isAbsolute, join, relative } from 'node:path';\nimport { promisify } from 'node:util';\n\n// The files `final agents publish` commits: what git would commit from the\n// checkout (tracked plus untracked-but-not-ignored, so `.gitignore`d files\n// such as local env files never leave the machine), minus build output.\n\nexport type ListFiles = (dir: string) => Promise<string[]>;\n\nconst run = promisify(execFile);\n\n// Paths relative to `dir`, restricted to it.\nexport const gitListFiles: ListFiles = async (dir) => {\n try {\n const { stdout } = await run(\n 'git',\n ['ls-files', '-z', '--cached', '--others', '--exclude-standard', '--deduplicate'],\n { cwd: dir, maxBuffer: 64 * 1024 * 1024 },\n );\n return stdout.split('\\0').filter((path) => path.length > 0);\n } catch (cause) {\n throw new Error(\n `${dir} is not inside a git checkout (${cause instanceof Error ? cause.message.trim() : String(cause)})`,\n { cause },\n );\n }\n};\n\nconst isBuildOutput = (path: string): boolean =>\n path === '.final/compile' || path.startsWith('.final/compile/');\n\nconst isMissing = (cause: unknown): boolean =>\n cause instanceof Error && 'code' in cause && cause.code === 'ENOENT';\n\nexport interface LocalFilesIface {\n files: Record<string, string>;\n problems: string[];\n}\n\n// Text only: the definition API stores UTF-8 file contents.\nexport const readLocalFiles = async (args: {\n dir: string;\n listFiles: ListFiles;\n}): Promise<LocalFilesIface> => {\n const decoder = new TextDecoder('utf-8', { fatal: true });\n const files: Record<string, string> = {};\n const problems: string[] = [];\n const root = await realpath(args.dir);\n for (const path of (await args.listFiles(args.dir)).toSorted()) {\n if (isBuildOutput(path)) continue;\n let bytes: Buffer;\n try {\n const localPath = join(root, ...path.split('/'));\n const location = relative(root, await realpath(localPath));\n if (\n isAbsolute(location) ||\n location === '..' ||\n location.startsWith('../') ||\n (await lstat(localPath)).isSymbolicLink()\n ) {\n problems.push(`${path} is a symlink or resolves outside the agent directory`);\n continue;\n }\n bytes = await readFile(localPath);\n } catch (cause) {\n // Tracked but deleted in the working tree: not part of the commit.\n if (isMissing(cause)) continue;\n throw cause;\n }\n try {\n files[path] = decoder.decode(bytes);\n } catch {\n problems.push(`${path} is not UTF-8 text; agent directories hold text files only`);\n }\n }\n return { files, problems };\n};\n\nexport interface FileChangeIface {\n path: string;\n // Null deletes the file.\n content: string | null;\n}\n\nexport const fileChanges = (args: {\n local: Record<string, string>;\n remote: Record<string, string>;\n}): FileChangeIface[] => {\n const changes: FileChangeIface[] = [];\n for (const [path, content] of Object.entries(args.local)) {\n if (args.remote[path] !== content) changes.push({ path, content });\n }\n for (const path of Object.keys(args.remote)) {\n if (!(path in args.local)) changes.push({ path, content: null });\n }\n return changes.toSorted((a, b) => a.path.localeCompare(b.path));\n};\n"],
5
+ "mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,OAAO,UAAU,gBAAgB;AAC1C,SAAS,YAAY,MAAM,gBAAgB;AAC3C,SAAS,iBAAiB;AAQ1B,MAAM,MAAM,UAAU,QAAQ;AAGvB,MAAM,eAA0B,OAAO,QAAQ;AACpD,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM;AAAA,MACvB;AAAA,MACA,CAAC,YAAY,MAAM,YAAY,YAAY,sBAAsB,eAAe;AAAA,MAChF,EAAE,KAAK,KAAK,WAAW,KAAK,OAAO,KAAK;AAAA,IAC1C;AACA,WAAO,OAAO,MAAM,IAAI,EAAE,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AAAA,EAC5D,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,GAAG,GAAG,kCAAkC,iBAAiB,QAAQ,MAAM,QAAQ,KAAK,IAAI,OAAO,KAAK,CAAC;AAAA,MACrG,EAAE,MAAM;AAAA,IACV;AAAA,EACF;AACF;AAEA,MAAM,gBAAgB,CAAC,SACrB,SAAS,oBAAoB,KAAK,WAAW,iBAAiB;AAEhE,MAAM,YAAY,CAAC,UACjB,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS;AAQvD,MAAM,iBAAiB,OAAO,SAGL;AAC9B,QAAM,UAAU,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC;AACxD,QAAM,QAAgC,CAAC;AACvC,QAAM,WAAqB,CAAC;AAC5B,QAAM,OAAO,MAAM,SAAS,KAAK,GAAG;AACpC,aAAW,SAAS,MAAM,KAAK,UAAU,KAAK,GAAG,GAAG,SAAS,GAAG;AAC9D,QAAI,cAAc,IAAI,EAAG;AACzB,QAAI;AACJ,QAAI;AACF,YAAM,YAAY,KAAK,MAAM,GAAG,KAAK,MAAM,GAAG,CAAC;AAC/C,YAAM,WAAW,SAAS,MAAM,MAAM,SAAS,SAAS,CAAC;AACzD,UACE,WAAW,QAAQ,KACnB,aAAa,QACb,SAAS,WAAW,KAAK,MACxB,MAAM,MAAM,SAAS,GAAG,eAAe,GACxC;AACA,iBAAS,KAAK,GAAG,IAAI,uDAAuD;AAC5E;AAAA,MACF;AACA,cAAQ,MAAM,SAAS,SAAS;AAAA,IAClC,SAAS,OAAO;AAEd,UAAI,UAAU,KAAK,EAAG;AACtB,YAAM;AAAA,IACR;AACA,QAAI;AACF,YAAM,IAAI,IAAI,QAAQ,OAAO,KAAK;AAAA,IACpC,QAAQ;AACN,eAAS,KAAK,GAAG,IAAI,4DAA4D;AAAA,IACnF;AAAA,EACF;AACA,SAAO,EAAE,OAAO,SAAS;AAC3B;AAQO,MAAM,cAAc,CAAC,SAGH;AACvB,QAAM,UAA6B,CAAC;AACpC,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,KAAK,GAAG;AACxD,QAAI,KAAK,OAAO,IAAI,MAAM,QAAS,SAAQ,KAAK,EAAE,MAAM,QAAQ,CAAC;AAAA,EACnE;AACA,aAAW,QAAQ,OAAO,KAAK,KAAK,MAAM,GAAG;AAC3C,QAAI,EAAE,QAAQ,KAAK,OAAQ,SAAQ,KAAK,EAAE,MAAM,SAAS,KAAK,CAAC;AAAA,EACjE;AACA,SAAO,QAAQ,SAAS,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAChE;",
6
+ "names": []
7
+ }
@@ -0,0 +1,20 @@
1
+ import { type HarnessDescriptionContextIface } from '@finalai/agent-definition/compiler';
2
+ import { type HarnessDescriptionIface, type ProviderRef } from '@finalai/agent-provider';
3
+ import type { AgentClientIface } from "../agent-client/client.mjs";
4
+ import { type ProviderEntryIface } from "../agent-client/index.mjs";
5
+ import { type OutputIface } from "./output.mjs";
6
+ export declare const descriptionOf: (entry: ProviderEntryIface) => HarnessDescriptionIface | null;
7
+ export declare const createInstalledHarnessDescriptions: (args: {
8
+ client: AgentClientIface;
9
+ output: OutputIface;
10
+ }) => ((ref: ProviderRef) => Promise<HarnessDescriptionIface | null>);
11
+ export declare const describeBundleHarness: (args: {
12
+ exportName: string;
13
+ bundle: {
14
+ code: string;
15
+ };
16
+ }) => Promise<HarnessDescriptionIface | null>;
17
+ export declare const createHarnessDescriptions: (args: {
18
+ client: AgentClientIface | null;
19
+ output: OutputIface;
20
+ }) => ((ref: ProviderRef, context: HarnessDescriptionContextIface) => Promise<HarnessDescriptionIface | null>);
@@ -0,0 +1,70 @@
1
+ import {
2
+ loadBundleInLocalIsolate
3
+ } from "@finalai/agent-definition/compiler";
4
+ import {
5
+ formatProviderRef,
6
+ harnessDescriptionSchema,
7
+ jsonObjectSchema,
8
+ ProviderRefKind
9
+ } from "@finalai/agent-provider";
10
+ import { ProviderKind } from "../agent-client/index.mjs";
11
+ import { errorLines } from "./output.mjs";
12
+ const wireRefText = (entry) => `${String(entry.ref.kind)}:${entry.ref.specifier ?? entry.ref.export ?? ""}`;
13
+ const descriptionOf = (entry) => {
14
+ const capabilities = jsonObjectSchema.safeParse(entry.capabilities);
15
+ if (!capabilities.success || entry.configSchema == null) return null;
16
+ const parsed = harnessDescriptionSchema.safeParse({
17
+ ...capabilities.data,
18
+ configSchema: entry.configSchema
19
+ });
20
+ return parsed.success ? parsed.data : null;
21
+ };
22
+ const createInstalledHarnessDescriptions = (args) => {
23
+ return async (ref) => {
24
+ let providers;
25
+ try {
26
+ providers = await args.client.providers.list();
27
+ } catch (cause) {
28
+ for (const line of errorLines(cause)) args.output.stderr(`providers: ${line}`);
29
+ return null;
30
+ }
31
+ const wanted = formatProviderRef(ref);
32
+ const entry = providers.find(
33
+ (candidate) => candidate.kind === ProviderKind.Harness && wireRefText(candidate) === wanted
34
+ );
35
+ return entry == null ? null : descriptionOf(entry);
36
+ };
37
+ };
38
+ const describeBundleHarness = async (args) => {
39
+ const loaded = await loadBundleInLocalIsolate(args.bundle.code);
40
+ const described = await loaded.callExportMethod({
41
+ exportName: args.exportName,
42
+ method: "describe",
43
+ args: []
44
+ });
45
+ return harnessDescriptionSchema.safeParse(described).data ?? null;
46
+ };
47
+ const createHarnessDescriptions = (args) => {
48
+ const installed = args.client == null ? null : createInstalledHarnessDescriptions({ client: args.client, output: args.output });
49
+ return async (ref, context) => {
50
+ if (ref.kind === ProviderRefKind.Bundle) {
51
+ if (context.bundle == null) return null;
52
+ try {
53
+ return await describeBundleHarness({ exportName: ref.export, bundle: context.bundle });
54
+ } catch (cause) {
55
+ args.output.stderr(
56
+ `describe ${ref.export}: ${cause instanceof Error ? cause.message : String(cause)}`
57
+ );
58
+ return null;
59
+ }
60
+ }
61
+ return installed == null ? null : installed(ref);
62
+ };
63
+ };
64
+ export {
65
+ createHarnessDescriptions,
66
+ createInstalledHarnessDescriptions,
67
+ describeBundleHarness,
68
+ descriptionOf
69
+ };
70
+ //# sourceMappingURL=harness-descriptions.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/harness-descriptions.ts"],
4
+ "sourcesContent": ["import {\n loadBundleInLocalIsolate,\n type HarnessDescriptionContextIface,\n} from '@finalai/agent-definition/compiler';\nimport {\n formatProviderRef,\n harnessDescriptionSchema,\n jsonObjectSchema,\n ProviderRefKind,\n type HarnessDescriptionIface,\n type ProviderRef,\n} from '@finalai/agent-provider';\nimport type { AgentClientIface } from \"../agent-client/client.mjs\";\nimport { ProviderKind, type ProviderEntryIface } from \"../agent-client/index.mjs\";\nimport { errorLines, type OutputIface } from \"./output.mjs\";\n\n// The compatibility report checks against the harnesses installed on the\n// platform: `GET /v1/providers` carries each harness's description (its\n// config schema and capabilities).\n\nconst wireRefText = (entry: ProviderEntryIface): string =>\n `${String(entry.ref.kind)}:${entry.ref.specifier ?? entry.ref.export ?? ''}`;\n\nexport const descriptionOf = (entry: ProviderEntryIface): HarnessDescriptionIface | null => {\n const capabilities = jsonObjectSchema.safeParse(entry.capabilities);\n if (!capabilities.success || entry.configSchema == null) return null;\n const parsed = harnessDescriptionSchema.safeParse({\n ...capabilities.data,\n configSchema: entry.configSchema,\n });\n return parsed.success ? parsed.data : null;\n};\n\nexport const createInstalledHarnessDescriptions = (args: {\n client: AgentClientIface;\n output: OutputIface;\n}): ((ref: ProviderRef) => Promise<HarnessDescriptionIface | null>) => {\n return async (ref) => {\n let providers: ProviderEntryIface[];\n try {\n providers = await args.client.providers.list();\n } catch (cause) {\n for (const line of errorLines(cause)) args.output.stderr(`providers: ${line}`);\n return null;\n }\n const wanted = formatProviderRef(ref);\n const entry = providers.find(\n (candidate) => candidate.kind === ProviderKind.Harness && wireRefText(candidate) === wanted,\n );\n return entry == null ? null : descriptionOf(entry);\n };\n};\n\n// A harness declared in the bundle is described by running its\n// own describe in the local isolate, so the report needs no platform.\nexport const describeBundleHarness = async (args: {\n exportName: string;\n bundle: { code: string };\n}): Promise<HarnessDescriptionIface | null> => {\n const loaded = await loadBundleInLocalIsolate(args.bundle.code);\n const described = await loaded.callExportMethod({\n exportName: args.exportName,\n method: 'describe',\n args: [],\n });\n return harnessDescriptionSchema.safeParse(described).data ?? null;\n};\n\nexport const createHarnessDescriptions = (args: {\n client: AgentClientIface | null;\n output: OutputIface;\n}): ((\n ref: ProviderRef,\n context: HarnessDescriptionContextIface,\n) => Promise<HarnessDescriptionIface | null>) => {\n const installed =\n args.client == null\n ? null\n : createInstalledHarnessDescriptions({ client: args.client, output: args.output });\n return async (ref, context) => {\n if (ref.kind === ProviderRefKind.Bundle) {\n if (context.bundle == null) return null;\n try {\n return await describeBundleHarness({ exportName: ref.export, bundle: context.bundle });\n } catch (cause) {\n args.output.stderr(\n `describe ${ref.export}: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n return null;\n }\n }\n return installed == null ? null : installed(ref);\n };\n};\n"],
5
+ "mappings": "AAAA;AAAA,EACE;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAEP,SAAS,oBAA6C;AACtD,SAAS,kBAAoC;AAM7C,MAAM,cAAc,CAAC,UACnB,GAAG,OAAO,MAAM,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI,aAAa,MAAM,IAAI,UAAU,EAAE;AAErE,MAAM,gBAAgB,CAAC,UAA8D;AAC1F,QAAM,eAAe,iBAAiB,UAAU,MAAM,YAAY;AAClE,MAAI,CAAC,aAAa,WAAW,MAAM,gBAAgB,KAAM,QAAO;AAChE,QAAM,SAAS,yBAAyB,UAAU;AAAA,IAChD,GAAG,aAAa;AAAA,IAChB,cAAc,MAAM;AAAA,EACtB,CAAC;AACD,SAAO,OAAO,UAAU,OAAO,OAAO;AACxC;AAEO,MAAM,qCAAqC,CAAC,SAGoB;AACrE,SAAO,OAAO,QAAQ;AACpB,QAAI;AACJ,QAAI;AACF,kBAAY,MAAM,KAAK,OAAO,UAAU,KAAK;AAAA,IAC/C,SAAS,OAAO;AACd,iBAAW,QAAQ,WAAW,KAAK,EAAG,MAAK,OAAO,OAAO,cAAc,IAAI,EAAE;AAC7E,aAAO;AAAA,IACT;AACA,UAAM,SAAS,kBAAkB,GAAG;AACpC,UAAM,QAAQ,UAAU;AAAA,MACtB,CAAC,cAAc,UAAU,SAAS,aAAa,WAAW,YAAY,SAAS,MAAM;AAAA,IACvF;AACA,WAAO,SAAS,OAAO,OAAO,cAAc,KAAK;AAAA,EACnD;AACF;AAIO,MAAM,wBAAwB,OAAO,SAGG;AAC7C,QAAM,SAAS,MAAM,yBAAyB,KAAK,OAAO,IAAI;AAC9D,QAAM,YAAY,MAAM,OAAO,iBAAiB;AAAA,IAC9C,YAAY,KAAK;AAAA,IACjB,QAAQ;AAAA,IACR,MAAM,CAAC;AAAA,EACT,CAAC;AACD,SAAO,yBAAyB,UAAU,SAAS,EAAE,QAAQ;AAC/D;AAEO,MAAM,4BAA4B,CAAC,SAMO;AAC/C,QAAM,YACJ,KAAK,UAAU,OACX,OACA,mCAAmC,EAAE,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO,CAAC;AACrF,SAAO,OAAO,KAAK,YAAY;AAC7B,QAAI,IAAI,SAAS,gBAAgB,QAAQ;AACvC,UAAI,QAAQ,UAAU,KAAM,QAAO;AACnC,UAAI;AACF,eAAO,MAAM,sBAAsB,EAAE,YAAY,IAAI,QAAQ,QAAQ,QAAQ,OAAO,CAAC;AAAA,MACvF,SAAS,OAAO;AACd,aAAK,OAAO;AAAA,UACV,YAAY,IAAI,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QACnF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO,aAAa,OAAO,OAAO,UAAU,GAAG;AAAA,EACjD;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import 'zod/compile';
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import "zod/compile";
3
+ import { runAgentsCommand } from "./cli.mjs";
4
+ const stop = new AbortController();
5
+ for (const signal of ["SIGINT", "SIGTERM"]) process.once(signal, () => stop.abort());
6
+ process.exit(
7
+ await runAgentsCommand({
8
+ argv: process.argv.slice(2),
9
+ env: process.env,
10
+ cwd: process.cwd(),
11
+ signal: stop.signal,
12
+ output: {
13
+ stdout: (line) => process.stdout.write(`${line}
14
+ `),
15
+ stderr: (line) => process.stderr.write(`${line}
16
+ `)
17
+ }
18
+ })
19
+ );
20
+ //# sourceMappingURL=main.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/main.ts"],
4
+ "sourcesContent": ["#!/usr/bin/env node\nimport 'zod/compile';\nimport { runAgentsCommand } from \"./cli.mjs\";\n\n// `final-agents build|dev|publish|conformance`: `final agents \u2026` until a general `final` CLI exists.\n\nconst stop = new AbortController();\nfor (const signal of ['SIGINT', 'SIGTERM'] as const) process.once(signal, () => stop.abort());\n\nprocess.exit(\n await runAgentsCommand({\n argv: process.argv.slice(2),\n env: process.env,\n cwd: process.cwd(),\n signal: stop.signal,\n output: {\n stdout: (line) => process.stdout.write(`${line}\\n`),\n stderr: (line) => process.stderr.write(`${line}\\n`),\n },\n }),\n);\n"],
5
+ "mappings": ";AACA,OAAO;AACP,SAAS,wBAAwB;AAIjC,MAAM,OAAO,IAAI,gBAAgB;AACjC,WAAW,UAAU,CAAC,UAAU,SAAS,EAAY,SAAQ,KAAK,QAAQ,MAAM,KAAK,MAAM,CAAC;AAE5F,QAAQ;AAAA,EACN,MAAM,iBAAiB;AAAA,IACrB,MAAM,QAAQ,KAAK,MAAM,CAAC;AAAA,IAC1B,KAAK,QAAQ;AAAA,IACb,KAAK,QAAQ,IAAI;AAAA,IACjB,QAAQ,KAAK;AAAA,IACb,QAAQ;AAAA,MACN,QAAQ,CAAC,SAAS,QAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,MAClD,QAAQ,CAAC,SAAS,QAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,IACpD;AAAA,EACF,CAAC;AACH;",
6
+ "names": []
7
+ }
@@ -0,0 +1,14 @@
1
+ import type { CompatibilityReportIface } from '@finalai/agent-definition/compatibility';
2
+ import type { DiagnosticIface } from '@finalai/agent-definition/compiler';
3
+ import { type AgentManifestIface } from '@finalai/agent-provider';
4
+ import { type PublishResultIface } from "../agent-client/index.mjs";
5
+ export interface OutputIface {
6
+ stdout: (line: string) => void;
7
+ stderr: (line: string) => void;
8
+ }
9
+ export declare const manifestSummaryLines: (manifest: AgentManifestIface) => string[];
10
+ export declare const hookLines: (manifest: AgentManifestIface) => string[];
11
+ export declare const reportLines: (report: CompatibilityReportIface) => string[];
12
+ export declare const diagnosticLine: (item: DiagnosticIface) => string;
13
+ export declare const errorLines: (cause: unknown) => string[];
14
+ export declare const publishResultLines: (result: PublishResultIface) => string[];