@agentfield/sdk 0.1.143-rc.3 → 0.1.143-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,15 +1,16 @@
1
- import fs2, { promises, readFileSync } from 'fs';
2
- import * as path5 from 'path';
3
- import path5__default, { resolve, dirname } from 'path';
1
+ import http2 from 'http';
2
+ import https2 from 'https';
3
+ import crypto2, { randomUUID, createHash } from 'crypto';
4
+ import fs, { promises, readFileSync } from 'fs';
5
+ import os2, { constants } from 'os';
6
+ import * as path from 'path';
7
+ import path__default, { resolve, dirname } from 'path';
4
8
  import { spawn } from 'child_process';
5
- import os, { constants } from 'os';
9
+ import { performance } from 'perf_hooks';
6
10
  import { createRequire } from 'module';
7
11
  import express from 'express';
8
12
  import rateLimit from 'express-rate-limit';
9
- import crypto2, { randomUUID, createHash } from 'crypto';
10
13
  import axios5, { isAxiosError } from 'axios';
11
- import http from 'http';
12
- import https from 'https';
13
14
  import { AsyncLocalStorage } from 'async_hooks';
14
15
  import { tool, jsonSchema, generateText, stepCountIs, streamText, embed, embedMany, generateObject } from 'ai';
15
16
  import { createOpenAI } from '@ai-sdk/openai';
@@ -149,6 +150,184 @@ var init_openrouterAttribution = __esm({
149
150
  DEFAULT_OPENROUTER_CATEGORIES = "cli-agent,programming-app";
150
151
  }
151
152
  });
153
+ function requestResponse(url) {
154
+ if (url.protocol !== "https:" && url.protocol !== "http:") {
155
+ throw new Error(`Unsupported CodeAF download protocol: ${url.protocol}`);
156
+ }
157
+ return new Promise((resolve3, reject) => {
158
+ const request = (url.protocol === "https:" ? https2 : http2).get(url, resolve3);
159
+ request.on("error", reject);
160
+ request.setTimeout(3e4, () => request.destroy(new Error("CodeAF download timed out")));
161
+ });
162
+ }
163
+ async function codeafDownloadResponse(url, redirects = 0) {
164
+ const response = await requestResponse(url);
165
+ if ([301, 302, 303, 307, 308].includes(response.statusCode ?? 0) && response.headers.location) {
166
+ response.resume();
167
+ if (redirects >= 5) throw new Error("Too many CodeAF download redirects");
168
+ return codeafDownloadResponse(new URL(response.headers.location, url), redirects + 1);
169
+ }
170
+ if (response.statusCode !== 200) {
171
+ response.resume();
172
+ throw new Error(`CodeAF download failed: HTTP ${response.statusCode}`);
173
+ }
174
+ return response;
175
+ }
176
+ var init_codeafDownload = __esm({
177
+ "src/harness/codeafDownload.ts"() {
178
+ }
179
+ });
180
+
181
+ // src/harness/codeafRelease.ts
182
+ var CODEAF_VERSION, CODEAF_BASE_URL, CODEAF_MAX_DOWNLOAD_BYTES, CODEAF_SHA256;
183
+ var init_codeafRelease = __esm({
184
+ "src/harness/codeafRelease.ts"() {
185
+ CODEAF_VERSION = "v0.8.2";
186
+ CODEAF_BASE_URL = `https://github.com/Agent-Field/CodeAF/releases/download/${CODEAF_VERSION}`;
187
+ CODEAF_MAX_DOWNLOAD_BYTES = 128 * 1024 * 1024;
188
+ CODEAF_SHA256 = Object.freeze({
189
+ "codeaf-darwin-amd64": "a476f1ce44b21f8016583a65c49b21497d10713bcd72c33478b3bd12e52446d7",
190
+ "codeaf-darwin-arm64": "e61adac060bf2345c08a3e23ae83239871c3050eadac046879f5f3176270c4f1",
191
+ "codeaf-linux-amd64": "681d9813f2517addc86fb644d313e3f7cf0ab60be708c8e8b13d77fb16a6798c",
192
+ "codeaf-linux-arm64": "c6375d58d198d9e1a84880d8b4324ee6c067a0e5e351af115ca5506b1ffa1c78",
193
+ "codeaf-windows-amd64.exe": "ff80f6f0c89c209fc809e960c70a1eb3518ccfc06775d587d5a187edd5d5222d",
194
+ "codeaf-windows-arm64.exe": "bfc0b386e5248e7e6756f097b372f72e4e955ee1e19e9216ccafee47064b2b80"
195
+ });
196
+ }
197
+ });
198
+ function agentfieldHome(env = process.env) {
199
+ return env.AGENTFIELD_HOME || path__default.join(os2.homedir(), ".agentfield");
200
+ }
201
+ function codeafStateHome(env) {
202
+ const preferred = path__default.join(agentfieldHome(env), "codeaf");
203
+ try {
204
+ fs.mkdirSync(preferred, { recursive: true });
205
+ } catch {
206
+ }
207
+ return preferred;
208
+ }
209
+ function codeafManagedPaths(env = process.env) {
210
+ const name = process.platform === "win32" ? "codeaf.exe" : "codeaf";
211
+ return [
212
+ path__default.join(agentfieldHome(env), "bin", name)
213
+ ];
214
+ }
215
+ function versionMarker(binary) {
216
+ return path__default.join(path__default.dirname(binary), ".codeaf.version");
217
+ }
218
+ function isCodeafInstalled(binary) {
219
+ try {
220
+ if (!fs.statSync(binary).isFile()) {
221
+ return false;
222
+ }
223
+ fs.accessSync(binary, process.platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
224
+ return fs.readFileSync(versionMarker(binary), "utf8").trim() === CODEAF_VERSION;
225
+ } catch {
226
+ return false;
227
+ }
228
+ }
229
+ function findManagedCodeaf(env = process.env) {
230
+ return codeafManagedPaths(env).find(isCodeafInstalled);
231
+ }
232
+ function isTruthy(value) {
233
+ return /^(1|true|yes|on)$/i.test(value?.trim() ?? "");
234
+ }
235
+ function skipCodeafInstall(env = process.env) {
236
+ return isTruthy(env.AGENTFIELD_SKIP_CODEAF) || isTruthy(env.AGENTFIELD_SKIP_AFORGE);
237
+ }
238
+ function codeafAsset(platform = process.platform, arch = process.arch) {
239
+ const releaseOS = platform === "win32" ? "windows" : platform;
240
+ const releaseArch = arch === "x64" ? "amd64" : arch;
241
+ const asset = `codeaf-${releaseOS}-${releaseArch}${platform === "win32" ? ".exe" : ""}`;
242
+ return Object.hasOwn(CODEAF_SHA256, asset) ? asset : void 0;
243
+ }
244
+ async function download(url, file, expectedHash) {
245
+ const response = await codeafDownloadResponse(url);
246
+ try {
247
+ if (Number(response.headers["content-length"]) > CODEAF_MAX_DOWNLOAD_BYTES) {
248
+ throw new Error("CodeAF download exceeds the 128 MiB size limit");
249
+ }
250
+ const hash = createHash("sha256");
251
+ let size = 0;
252
+ for await (const chunk of response) {
253
+ const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
254
+ size += data.length;
255
+ if (size > CODEAF_MAX_DOWNLOAD_BYTES) {
256
+ throw new Error("CodeAF download exceeds the 128 MiB size limit");
257
+ }
258
+ hash.update(data);
259
+ await file.writeFile(data);
260
+ }
261
+ if (hash.digest("hex") !== expectedHash) {
262
+ throw new Error("CodeAF download SHA-256 mismatch");
263
+ }
264
+ } finally {
265
+ response.destroy();
266
+ }
267
+ }
268
+ async function installCodeaf() {
269
+ const asset = codeafAsset();
270
+ if (!asset) {
271
+ throw new Error(`CodeAF is not installable on ${process.platform}/${process.arch}`);
272
+ }
273
+ if (process.env.HTTPS_PROXY || process.env.https_proxy) {
274
+ throw new Error("CodeAF download skipped: HTTPS_PROXY is set and the TypeScript SDK does not use proxies; run `af codeaf ensure`");
275
+ }
276
+ const [binary] = codeafManagedPaths();
277
+ const temporary = path__default.join(path__default.dirname(binary), `.codeaf-${randomUUID()}.tmp`);
278
+ let file;
279
+ try {
280
+ await fs.promises.mkdir(path__default.dirname(binary), { recursive: true });
281
+ file = await fs.promises.open(temporary, "wx", 384);
282
+ } catch (error) {
283
+ throw new Error(`cannot install CodeAF into ${path__default.dirname(binary)}: ${error instanceof Error ? error.message : String(error)}`);
284
+ }
285
+ console.info(`downloading CodeAF ${CODEAF_VERSION} (~70 MB) to ${binary}`);
286
+ try {
287
+ const base = (process.env.AGENTFIELD_CODEAF_BASE_URL || CODEAF_BASE_URL).replace(/\/+$/, "");
288
+ await download(new URL(`${base}/${asset}`), file, CODEAF_SHA256[asset]);
289
+ await file.chmod(493);
290
+ await file.close();
291
+ try {
292
+ await fs.promises.rename(temporary, binary);
293
+ } catch (error) {
294
+ if (process.platform === "win32" && isCodeafInstalled(binary)) {
295
+ return binary;
296
+ }
297
+ throw error;
298
+ }
299
+ await fs.promises.writeFile(versionMarker(binary), `${CODEAF_VERSION}
300
+ `);
301
+ return binary;
302
+ } finally {
303
+ await file.close().catch(() => void 0);
304
+ await fs.promises.rm(temporary, { force: true });
305
+ }
306
+ }
307
+ async function ensureCodeafInstalled() {
308
+ const installed = findManagedCodeaf();
309
+ if (installed) {
310
+ return installed;
311
+ }
312
+ if (skipCodeafInstall()) {
313
+ return void 0;
314
+ }
315
+ if (installation) return installation;
316
+ if (Date.now() < nextInstallAttempt) return void 0;
317
+ nextInstallAttempt = Date.now() + 6e4;
318
+ installation = installCodeaf().finally(() => {
319
+ installation = void 0;
320
+ });
321
+ return installation;
322
+ }
323
+ var installation, nextInstallAttempt;
324
+ var init_codeafInstall = __esm({
325
+ "src/harness/codeafInstall.ts"() {
326
+ init_codeafDownload();
327
+ init_codeafRelease();
328
+ nextInstallAttempt = 0;
329
+ }
330
+ });
152
331
 
153
332
  // src/harness/availability.ts
154
333
  var availability_exports = {};
@@ -161,7 +340,7 @@ __export(availability_exports, {
161
340
  providerUnavailable: () => providerUnavailable
162
341
  });
163
342
  function executableExtensions(binary, env) {
164
- if (process.platform !== "win32" || path5__default.extname(binary)) {
343
+ if (process.platform !== "win32" || path__default.extname(binary)) {
165
344
  return [""];
166
345
  }
167
346
  const pathExt = env.PATHEXT ?? env.PathExt ?? ".COM;.EXE;.BAT;.CMD";
@@ -169,10 +348,10 @@ function executableExtensions(binary, env) {
169
348
  }
170
349
  function isExecutableFile(candidate) {
171
350
  try {
172
- if (!fs2.statSync(candidate).isFile()) {
351
+ if (!fs.statSync(candidate).isFile()) {
173
352
  return false;
174
353
  }
175
- fs2.accessSync(candidate, process.platform === "win32" ? fs2.constants.F_OK : fs2.constants.X_OK);
354
+ fs.accessSync(candidate, process.platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
176
355
  return true;
177
356
  } catch {
178
357
  return false;
@@ -180,20 +359,20 @@ function isExecutableFile(candidate) {
180
359
  }
181
360
  function findExecutable(binary, env = process.env) {
182
361
  const extensions = executableExtensions(binary, env);
183
- const hasPath = path5__default.isAbsolute(binary) || binary.includes("/") || binary.includes("\\");
184
- const directories = hasPath ? [""] : (env.PATH ?? env.Path ?? env.path ?? "").split(path5__default.delimiter).filter(Boolean);
362
+ const hasPath = path__default.isAbsolute(binary) || binary.includes("/") || binary.includes("\\");
363
+ const directories = hasPath ? [""] : (env.PATH ?? env.Path ?? env.path ?? "").split(path__default.delimiter).filter(Boolean);
185
364
  for (const directory of directories) {
186
365
  for (const extension of extensions) {
187
- const candidate = `${hasPath ? binary : path5__default.join(directory, binary)}${extension}`;
366
+ const candidate = `${hasPath ? binary : path__default.join(directory, binary)}${extension}`;
188
367
  if (isExecutableFile(candidate)) {
189
- return path5__default.resolve(candidate);
368
+ return path__default.resolve(candidate);
190
369
  }
191
370
  }
192
371
  }
193
372
  return void 0;
194
373
  }
195
- function ensureCliAvailable(provider, binary, resolveBinary = findExecutable, env = process.env) {
196
- const resolved = resolveBinary(binary, env);
374
+ function ensureCliAvailable(provider, binary, resolveBinary2 = findExecutable, env = process.env) {
375
+ const resolved = resolveBinary2(binary, env);
197
376
  if (resolved) {
198
377
  return resolved;
199
378
  }
@@ -207,7 +386,7 @@ function providerUnavailable(provider, binary) {
207
386
  });
208
387
  }
209
388
  function isWindowsBatchFile(command) {
210
- return process.platform === "win32" && WINDOWS_BATCH_EXTENSIONS.has(path5__default.extname(command).toLowerCase());
389
+ return process.platform === "win32" && WINDOWS_BATCH_EXTENSIONS.has(path__default.extname(command).toLowerCase());
211
390
  }
212
391
  function batchProbeInvocation(command) {
213
392
  const env = { ...process.env };
@@ -285,7 +464,7 @@ async function harnessDoctor(providers, options = {}) {
285
464
  );
286
465
  }
287
466
  const env = options.env ?? process.env;
288
- const resolveBinary = options.resolveBinary ?? findExecutable;
467
+ const resolveBinary2 = options.resolveBinary ?? findExecutable;
289
468
  const versionProbe = options.versionProbe ?? defaultVersionProbe;
290
469
  const wrapperProbe = options.wrapperProbe ?? defaultWrapperProbe;
291
470
  const reports = [];
@@ -308,15 +487,23 @@ async function harnessDoctor(providers, options = {}) {
308
487
  continue;
309
488
  }
310
489
  const binaryName = spec.binary;
311
- const binary = resolveBinary(binaryName, env) ?? null;
490
+ const legacyPin = provider === "aforge" ? env.AFORGE_BIN?.trim() : void 0;
491
+ const lookupCodeaf = provider === "codeaf" || provider === "aforge" && !legacyPin;
492
+ const override = lookupCodeaf ? env.CODEAF_BIN?.trim() : void 0;
493
+ const codeaf = lookupCodeaf ? override ? resolveBinary2(override, env) : findManagedCodeaf(env) ?? resolveBinary2("codeaf", env) : void 0;
494
+ const codeafAlias = provider === "aforge" && !!codeaf;
495
+ const binary = provider === "codeaf" || override ? codeaf ?? null : legacyPin ? resolveBinary2(legacyPin, env) ?? null : codeaf ?? resolveBinary2(binaryName, env) ?? null;
312
496
  const issues = [];
313
497
  let version = null;
314
498
  if (binary === null) {
315
499
  issues.push("binary_not_found");
316
500
  } else {
317
501
  try {
318
- const output = (await versionProbe([binary, ...spec.versionArgs])).trim();
502
+ const output = (await versionProbe([binary, ...codeafAlias ? ["version"] : spec.versionArgs])).trim();
319
503
  version = output ? output.split(/\r?\n/, 1)[0] : "unknown";
504
+ if (provider === "codeaf") {
505
+ version = version.match(/^codeaf\s+(v\S+)/)?.[1] ?? version;
506
+ }
320
507
  } catch {
321
508
  issues.push("version_probe_failed");
322
509
  }
@@ -338,7 +525,14 @@ async function harnessDoctor(providers, options = {}) {
338
525
  var PROVIDER_SPECS, SUPPORTED_PROVIDER_NAMES, HarnessProviderUnavailable, WINDOWS_BATCH_EXTENSIONS, BATCH_PROBE_ENV_PREFIX;
339
526
  var init_availability = __esm({
340
527
  "src/harness/availability.ts"() {
528
+ init_codeafInstall();
341
529
  PROVIDER_SPECS = {
530
+ codeaf: {
531
+ binary: "codeaf",
532
+ versionArgs: ["version"],
533
+ installCommand: "af codeaf ensure",
534
+ authEnvVars: ["OPENROUTER_API_KEY"]
535
+ },
342
536
  aforge: {
343
537
  binary: "aforge",
344
538
  versionArgs: ["version"],
@@ -495,6 +689,7 @@ async function runCli(cmd, options) {
495
689
  stdio: [hasInput ? "pipe" : "ignore", "pipe", "pipe"]
496
690
  });
497
691
  if (hasInput) {
692
+ proc.stdin?.on("error", () => void 0);
498
693
  proc.stdin?.end(options.inputText);
499
694
  }
500
695
  let stdout = "";
@@ -565,9 +760,9 @@ async function runCli(cmd, options) {
565
760
  });
566
761
  });
567
762
  }
568
- function parseJsonl(text2) {
763
+ function parseJsonl(text3) {
569
764
  const events = [];
570
- for (const line of text2.split("\n")) {
765
+ for (const line of text3.split("\n")) {
571
766
  const trimmed = line.trim();
572
767
  if (!trimmed) {
573
768
  continue;
@@ -766,16 +961,22 @@ var init_aforge = __esm({
766
961
  };
767
962
  aforgeSemaphore = new Semaphore(resolveMaxConcurrent());
768
963
  AforgeProvider = class {
769
- bin;
770
- constructor(bin = "aforge") {
964
+ constructor(bin = "aforge", deadline) {
965
+ this.deadline = deadline;
771
966
  this.bin = bin === "aforge" ? process.env.AFORGE_BIN?.trim() || bin : bin;
772
967
  }
968
+ deadline;
969
+ bin;
773
970
  async execute(prompt, options) {
774
971
  return aforgeSemaphore.use(() => this.executeImpl(prompt, options));
775
972
  }
776
973
  async executeImpl(prompt, options) {
777
974
  const root = resolveRoot(options) ?? ".";
778
- const outerTimeout = timeoutSeconds();
975
+ const remaining = this.deadline === void 0 ? void 0 : this.deadline - performance.now();
976
+ if (remaining !== void 0 && remaining <= 0) {
977
+ return createRawResult({ isError: true, failureType: "timeout", errorMessage: "CodeAF fallback timed out" });
978
+ }
979
+ const outerTimeout = remaining === void 0 ? timeoutSeconds() : remaining / 1e3;
779
980
  const command = (process.env.AGENTFIELD_AFORGE_COMMAND ?? "exec").trim().toLowerCase();
780
981
  if (command !== "do" && command !== "exec") {
781
982
  return createRawResult({
@@ -793,7 +994,7 @@ var init_aforge = __esm({
793
994
  "-w",
794
995
  root,
795
996
  "--timeout",
796
- String(innerTimeout(outerTimeout))
997
+ String(Math.max(1, Math.floor(innerTimeout(outerTimeout))))
797
998
  ] : [
798
999
  this.bin,
799
1000
  "do",
@@ -802,7 +1003,7 @@ var init_aforge = __esm({
802
1003
  "-w",
803
1004
  root,
804
1005
  "--timeout",
805
- String(innerTimeout(outerTimeout))
1006
+ String(Math.max(1, Math.floor(innerTimeout(outerTimeout))))
806
1007
  ];
807
1008
  if (command === "exec" && typeof options.maxTurns === "number" && Number.isFinite(options.maxTurns) && options.maxTurns > 0) {
808
1009
  cmd.push("--turns", String(Math.trunc(options.maxTurns)));
@@ -895,6 +1096,329 @@ var init_aforge = __esm({
895
1096
  }
896
1097
  });
897
1098
 
1099
+ // src/harness/providers/codeaf.ts
1100
+ var codeaf_exports = {};
1101
+ __export(codeaf_exports, {
1102
+ CODEAF_DEFAULT_MODEL: () => CODEAF_DEFAULT_MODEL,
1103
+ CodeafProvider: () => CodeafProvider,
1104
+ resolveCodeafMaxConcurrent: () => resolveCodeafMaxConcurrent
1105
+ });
1106
+ function resolveCodeafMaxConcurrent() {
1107
+ const value = process.env.CODEAF_MAX_CONCURRENT ?? process.env.AFORGE_MAX_CONCURRENT;
1108
+ const parsed = Number(value);
1109
+ return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : 8;
1110
+ }
1111
+ async function resolveAutomaticBinary() {
1112
+ const managed = findManagedCodeaf();
1113
+ if (managed) {
1114
+ return { provider: "codeaf", binary: managed };
1115
+ }
1116
+ try {
1117
+ const installed = await ensureCodeafInstalled();
1118
+ if (installed) {
1119
+ return { provider: "codeaf", binary: installed };
1120
+ }
1121
+ } catch (error) {
1122
+ downloadError = error instanceof Error ? error.message : String(error);
1123
+ }
1124
+ const onPath = findExecutable("codeaf");
1125
+ if (onPath) {
1126
+ return { provider: "codeaf", binary: onPath };
1127
+ }
1128
+ const legacyName = process.platform === "win32" ? "aforge.exe" : "aforge";
1129
+ const legacy = findExecutable(path__default.join(agentfieldHome(), "bin", legacyName)) ?? findExecutable("aforge");
1130
+ if (legacy) {
1131
+ console.warn(`CodeAF is not installed; falling back to the legacy aforge binary at ${legacy}. Run \`af codeaf ensure\`.`);
1132
+ return { provider: "aforge", binary: legacy };
1133
+ }
1134
+ const unavailable = providerUnavailable("codeaf", "codeaf");
1135
+ unavailable.message += ` (or set CODEAF_BIN)${downloadError ? `. Download failed: ${downloadError}` : ""}`;
1136
+ throw unavailable;
1137
+ }
1138
+ function resolveBinary(explicit) {
1139
+ const override = explicit?.trim() || process.env.CODEAF_BIN?.trim();
1140
+ if (override) {
1141
+ return Promise.resolve({ provider: "codeaf", binary: override });
1142
+ }
1143
+ resolution ??= resolveAutomaticBinary().catch((error) => {
1144
+ resolution = void 0;
1145
+ throw error;
1146
+ });
1147
+ return resolution;
1148
+ }
1149
+ async function withinDeadline(operation, deadline, message) {
1150
+ let timer;
1151
+ try {
1152
+ return await Promise.race([
1153
+ operation,
1154
+ new Promise((_, reject) => {
1155
+ timer = setTimeout(() => reject(new Error(message)), Math.max(0, deadline - performance.now()));
1156
+ })
1157
+ ]);
1158
+ } finally {
1159
+ clearTimeout(timer);
1160
+ }
1161
+ }
1162
+ function parseEnvelope2(stdout) {
1163
+ const parse = (text3) => {
1164
+ try {
1165
+ const value = JSON.parse(text3);
1166
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && "ok" in value && "stop" in value) {
1167
+ return value;
1168
+ }
1169
+ } catch {
1170
+ }
1171
+ return void 0;
1172
+ };
1173
+ const whole = parse(stdout.trim());
1174
+ if (whole) {
1175
+ return whole;
1176
+ }
1177
+ const lines = stdout.split("\n");
1178
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
1179
+ const envelope = parse(lines[index].trim());
1180
+ if (envelope) {
1181
+ return envelope;
1182
+ }
1183
+ }
1184
+ return void 0;
1185
+ }
1186
+ function numeric2(value) {
1187
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1188
+ }
1189
+ function text2(value) {
1190
+ return typeof value === "string" ? value.trim() : "";
1191
+ }
1192
+ function failure(envelope, exitCode, stdout) {
1193
+ if (exitCode < 0) return "crash";
1194
+ if (!envelope) return exitCode === 0 && !stdout.trim() ? "no_output" : "crash";
1195
+ const stop = text2(envelope.stop);
1196
+ const answer = text2(envelope.answer);
1197
+ if (stop === "deadline") return "timeout";
1198
+ if (stop === "done") return envelope.ok === true ? "none" : "crash";
1199
+ if (stop === "unchecked") return answer ? "none" : "crash";
1200
+ if (stop === "budget" || stop === "turn-cap") return answer ? "none" : "no_output";
1201
+ if (["question", "incomplete", "error", "price"].includes(stop)) return "crash";
1202
+ return exitCode === 0 && answer ? "none" : "crash";
1203
+ }
1204
+ function errorMessage(exitCode, envelope, stderr) {
1205
+ const stop = text2(envelope?.stop);
1206
+ const detail = text2(envelope?.error) || text2(envelope?.answer) || stderr.trim().replace(ANSI_PATTERN2, "").slice(-1e3);
1207
+ let message = `codeaf exit code ${exitCode} (stop=${stop}): ${detail.slice(0, 1e3)}`;
1208
+ if (stop === "question" && text2(envelope?.blocked_on)) {
1209
+ message += `. blocked_on: ${text2(envelope?.blocked_on).slice(0, 1e3)}`;
1210
+ }
1211
+ return message;
1212
+ }
1213
+ function childEnvironment(options, variant) {
1214
+ const overlay = {};
1215
+ if (typeof options.env === "object" && options.env !== null && !Array.isArray(options.env)) {
1216
+ for (const [key, value] of Object.entries(options.env)) {
1217
+ if (typeof value === "string") overlay[key] = value;
1218
+ }
1219
+ }
1220
+ const inherited = { ...process.env, ...overlay };
1221
+ const env = { CODEAF_MODELS: void 0, AFORGE_MODELS: void 0 };
1222
+ if (inherited.CODEAF_HOME === void 0) {
1223
+ env.CODEAF_HOME = codeafStateHome(inherited);
1224
+ }
1225
+ if (inherited.CODEAF_NO_UPDATE_CHECK === void 0) env.CODEAF_NO_UPDATE_CHECK = "1";
1226
+ if (inherited.CODEAF_TELEMETRY === void 0 && (isTruthy(inherited.CI) || isTruthy(inherited.DO_NOT_TRACK) || /^(0|false|no|off)$/i.test(inherited.AGENTFIELD_TELEMETRY_ENABLED?.trim() ?? ""))) {
1227
+ env.CODEAF_TELEMETRY = "off";
1228
+ }
1229
+ const normalized = variant?.trim().toLowerCase();
1230
+ if (normalized && REASONING_VARIANTS2.has(normalized)) env.CODEAF_EXEC_REASONING = normalized;
1231
+ return { ...env, ...overlay };
1232
+ }
1233
+ var CODEAF_DEFAULT_MODEL, REASONING_VARIANTS2, ANSI_PATTERN2, Semaphore2, codeafSemaphore, resolution, downloadError, aliasLogged, invalidCommandLogged, CodeafProvider;
1234
+ var init_codeaf = __esm({
1235
+ "src/harness/providers/codeaf.ts"() {
1236
+ init_base();
1237
+ init_aforge();
1238
+ init_types();
1239
+ init_cli();
1240
+ init_availability();
1241
+ init_codeafInstall();
1242
+ init_modelVariant();
1243
+ CODEAF_DEFAULT_MODEL = "~deepseek/deepseek-v4-flash-latest";
1244
+ REASONING_VARIANTS2 = /* @__PURE__ */ new Set(["off", "low", "medium", "high"]);
1245
+ ANSI_PATTERN2 = /\x1B\[[0-?]*[ -/]*[@-~]/g;
1246
+ Semaphore2 = class {
1247
+ constructor(limit) {
1248
+ this.limit = limit;
1249
+ }
1250
+ limit;
1251
+ active = 0;
1252
+ waiters = [];
1253
+ async use(operation) {
1254
+ if (this.active >= this.limit) {
1255
+ await new Promise((resolve3) => this.waiters.push(resolve3));
1256
+ } else {
1257
+ this.active += 1;
1258
+ }
1259
+ try {
1260
+ return await operation();
1261
+ } finally {
1262
+ const next = this.waiters.shift();
1263
+ if (next) {
1264
+ next();
1265
+ } else {
1266
+ this.active -= 1;
1267
+ }
1268
+ }
1269
+ }
1270
+ };
1271
+ codeafSemaphore = new Semaphore2(resolveCodeafMaxConcurrent());
1272
+ aliasLogged = false;
1273
+ invalidCommandLogged = false;
1274
+ CodeafProvider = class {
1275
+ constructor(bin, alias = false) {
1276
+ this.bin = bin;
1277
+ this.alias = alias;
1278
+ }
1279
+ bin;
1280
+ alias;
1281
+ async execute(prompt, options) {
1282
+ const legacyPin = this.alias ? process.env.AFORGE_BIN?.trim() : void 0;
1283
+ if (legacyPin) {
1284
+ return { ...await new AforgeProvider(legacyPin).execute(prompt, options), provider: "aforge" };
1285
+ }
1286
+ const started = performance.now();
1287
+ const parsedTimeout = Number.parseInt(process.env.AGENTFIELD_HARNESS_TIMEOUT_SECONDS ?? "", 10);
1288
+ const timeout = Number.isFinite(parsedTimeout) && parsedTimeout > 0 ? parsedTimeout : 1800;
1289
+ const deadline = started + timeout * 1e3;
1290
+ let resolved;
1291
+ try {
1292
+ resolved = await withinDeadline(resolveBinary(this.bin), deadline, "Timed out while provisioning CodeAF");
1293
+ } catch (error) {
1294
+ if (!(error instanceof Error) || !error.message.includes("Timed out while provisioning")) throw error;
1295
+ return createRawResult({
1296
+ provider: "codeaf",
1297
+ isError: true,
1298
+ failureType: "timeout",
1299
+ errorMessage: error.message,
1300
+ metrics: createMetrics({ durationApiMs: performance.now() - started })
1301
+ });
1302
+ }
1303
+ if (resolved.provider === "aforge") {
1304
+ try {
1305
+ return { ...await withinDeadline(
1306
+ new AforgeProvider(resolved.binary, deadline).execute(prompt, options),
1307
+ deadline,
1308
+ "CodeAF fallback timed out"
1309
+ ), provider: "aforge" };
1310
+ } catch (error) {
1311
+ if (!(error instanceof Error) || !error.message.includes("timed out")) throw error;
1312
+ return createRawResult({ provider: "aforge", isError: true, failureType: "timeout", errorMessage: error.message });
1313
+ }
1314
+ }
1315
+ if (this.alias && !aliasLogged) {
1316
+ aliasLogged = true;
1317
+ console.info("provider 'aforge' now runs CodeAF; set AFORGE_BIN to pin the legacy binary");
1318
+ }
1319
+ try {
1320
+ return await withinDeadline(
1321
+ codeafSemaphore.use(() => this.executeImpl(resolved.binary, prompt, options, deadline)),
1322
+ deadline,
1323
+ "CodeAF timed out"
1324
+ );
1325
+ } catch (error) {
1326
+ if (!(error instanceof Error) || !error.message.includes("timed out")) throw error;
1327
+ return createRawResult({ provider: "codeaf", isError: true, failureType: "timeout", errorMessage: error.message });
1328
+ }
1329
+ }
1330
+ async executeImpl(binary, prompt, options, deadline) {
1331
+ if (performance.now() >= deadline) {
1332
+ return createRawResult({ provider: "codeaf", isError: true, failureType: "timeout", errorMessage: "CodeAF timed out" });
1333
+ }
1334
+ const root = resolveRoot(options) ?? ".";
1335
+ const outerTimeout = Math.max(0, deadline - performance.now());
1336
+ const requestedCommand = process.env.AGENTFIELD_CODEAF_COMMAND?.trim().toLowerCase() || process.env.AGENTFIELD_AFORGE_COMMAND?.trim().toLowerCase() || "exec";
1337
+ const command = requestedCommand === "do" ? "do" : "exec";
1338
+ if (!["exec", "do"].includes(requestedCommand) && !invalidCommandLogged) {
1339
+ invalidCommandLogged = true;
1340
+ console.warn(`Invalid AGENTFIELD_CODEAF_COMMAND ${JSON.stringify(requestedCommand)}; using exec`);
1341
+ }
1342
+ const { model, variant } = resolveModelAndVariant(options);
1343
+ const overlay = typeof options.env === "object" && options.env !== null ? options.env : {};
1344
+ const environment = { ...process.env, ...overlay };
1345
+ const effectiveModel = (model || environment.CODEAF_MODEL?.trim() || environment.AFORGE_MODEL?.trim() || CODEAF_DEFAULT_MODEL).replace(/^openrouter\//, "");
1346
+ const systemPrompt = text2(options.systemPrompt ?? options.system_prompt);
1347
+ const cmd = [binary, command, "--json", "--dir", root];
1348
+ if (command === "do") cmd.push("--yes-spend");
1349
+ cmd.push("--model", effectiveModel);
1350
+ if (command === "do") cmd.push("--plan-model", effectiveModel, "--check-model", effectiveModel);
1351
+ cmd.push("--timeout", `${Number(Math.max(1, outerTimeout / 1e3 - 5).toFixed(3))}s`);
1352
+ if (command === "exec") {
1353
+ if (typeof options.maxTurns === "number" && Number.isFinite(options.maxTurns) && options.maxTurns > 0) {
1354
+ cmd.push("--max-turns", String(Math.trunc(options.maxTurns)));
1355
+ }
1356
+ if (systemPrompt) cmd.push("--system", systemPrompt);
1357
+ } else {
1358
+ cmd.push("-");
1359
+ }
1360
+ const startApi = Date.now();
1361
+ try {
1362
+ const env = childEnvironment(options, variant);
1363
+ const remaining = deadline - performance.now();
1364
+ if (remaining <= 0) throw new Error("CodeAF timed out");
1365
+ const { stdout, stderr, exitCode } = await runCli(markProviderCommand("codeaf", cmd), {
1366
+ env,
1367
+ cwd: void 0,
1368
+ timeout: remaining,
1369
+ idleSeconds: 0,
1370
+ inputText: command === "do" && systemPrompt ? `${systemPrompt}
1371
+
1372
+ Task:
1373
+ ${prompt}` : prompt
1374
+ });
1375
+ const envelope = parseEnvelope2(stdout);
1376
+ const failureType = failure(envelope, exitCode, stdout);
1377
+ const stop = text2(envelope?.stop);
1378
+ if (failureType === "none" && ["unchecked", "budget", "turn-cap"].includes(stop)) {
1379
+ console.warn(`CodeAF returned ${stop === "unchecked" ? "an unchecked answer" : `a partial answer (${stop})`}`);
1380
+ }
1381
+ const tokens = typeof envelope?.tokens === "object" && envelope.tokens !== null && !Array.isArray(envelope.tokens) ? envelope.tokens : {};
1382
+ const inputTokens = Math.trunc(numeric2(tokens.in) ?? 0);
1383
+ const outputTokens = Math.trunc(numeric2(tokens.out) ?? 0);
1384
+ return createRawResult({
1385
+ provider: "codeaf",
1386
+ result: failureType === "none" ? text2(envelope?.answer) || void 0 : void 0,
1387
+ messages: envelope ? [envelope] : [],
1388
+ metrics: createMetrics({
1389
+ durationApiMs: Date.now() - startApi,
1390
+ numTurns: Math.trunc(numeric2(envelope?.steps) ?? 0),
1391
+ totalCostUsd: numeric2(envelope?.spend_usd),
1392
+ inputTokens,
1393
+ outputTokens,
1394
+ totalTokens: inputTokens + outputTokens,
1395
+ cacheReadTokens: 0,
1396
+ cacheCreationTokens: 0,
1397
+ model: text2(envelope?.model) || effectiveModel,
1398
+ usage: tokens
1399
+ }),
1400
+ isError: failureType !== "none",
1401
+ errorMessage: failureType !== "none" ? errorMessage(exitCode, envelope, stderr) : void 0,
1402
+ failureType,
1403
+ returnCode: exitCode
1404
+ });
1405
+ } catch (error) {
1406
+ if (error instanceof HarnessProviderUnavailable) throw error;
1407
+ const message = error instanceof Error ? error.message : String(error);
1408
+ if (message.includes("ENOENT")) throw providerUnavailable("codeaf", binary);
1409
+ return createRawResult({
1410
+ provider: "codeaf",
1411
+ isError: true,
1412
+ errorMessage: message,
1413
+ failureType: /timed out|deadline exceeded|no progress/i.test(message) ? "timeout" : "crash",
1414
+ metrics: createMetrics({ durationApiMs: Date.now() - startApi, model: effectiveModel })
1415
+ });
1416
+ }
1417
+ }
1418
+ };
1419
+ }
1420
+ });
1421
+
898
1422
  // src/harness/providers/claude.ts
899
1423
  var claude_exports = {};
900
1424
  __export(claude_exports, {
@@ -1357,7 +1881,7 @@ function extractOpenCodeError(stderr) {
1357
1881
  }
1358
1882
  return stderr.slice(0, 1e3);
1359
1883
  }
1360
- var ANSI_PATTERN2, STDERR_ERROR_PATTERNS, openCodeConfigSchema, openCodeAgentName, openCodeDefaultSteps, openCodeInlineSystemPromptEnv, openCodeStepsEnv, agentFieldWorkerInstruction, trueEnvValues, OpenCodeProvider;
1884
+ var ANSI_PATTERN3, STDERR_ERROR_PATTERNS, openCodeConfigSchema, openCodeAgentName, openCodeDefaultSteps, openCodeInlineSystemPromptEnv, openCodeStepsEnv, agentFieldWorkerInstruction, trueEnvValues, OpenCodeProvider;
1361
1885
  var init_opencode = __esm({
1362
1886
  "src/harness/providers/opencode.ts"() {
1363
1887
  init_base();
@@ -1366,7 +1890,7 @@ var init_opencode = __esm({
1366
1890
  init_availability();
1367
1891
  init_modelVariant();
1368
1892
  init_openrouterAttribution();
1369
- ANSI_PATTERN2 = /\x1B\[[0-?]*[ -/]*[@-~]/g;
1893
+ ANSI_PATTERN3 = /\x1B\[[0-?]*[ -/]*[@-~]/g;
1370
1894
  STDERR_ERROR_PATTERNS = [
1371
1895
  /^Error:/m,
1372
1896
  /\bModel not found\b/,
@@ -1429,18 +1953,18 @@ var init_opencode = __esm({
1429
1953
  try {
1430
1954
  const { stdout, stderr, exitCode } = await runCli(markProviderCommand("opencode", cmd), { env });
1431
1955
  const resultText = stdout.trim() || void 0;
1432
- const cleanStderr = stderr.trim().replace(ANSI_PATTERN2, "");
1956
+ const cleanStderr = stderr.trim().replace(ANSI_PATTERN3, "");
1433
1957
  let isError = false;
1434
- let errorMessage;
1958
+ let errorMessage2;
1435
1959
  if (exitCode < 0) {
1436
1960
  isError = true;
1437
- errorMessage = cleanStderr ? `Process killed by signal ${-exitCode}. stderr: ${cleanStderr.slice(0, 500)}` : `Process killed by signal ${-exitCode}.`;
1961
+ errorMessage2 = cleanStderr ? `Process killed by signal ${-exitCode}. stderr: ${cleanStderr.slice(0, 500)}` : `Process killed by signal ${-exitCode}.`;
1438
1962
  } else if (exitCode !== 0 && !resultText) {
1439
1963
  isError = true;
1440
- errorMessage = cleanStderr ? extractOpenCodeError(cleanStderr) : `Process exited with code ${exitCode} and produced no output.`;
1964
+ errorMessage2 = cleanStderr ? extractOpenCodeError(cleanStderr) : `Process exited with code ${exitCode} and produced no output.`;
1441
1965
  } else if (!resultText && cleanStderr && STDERR_ERROR_PATTERNS.some((pattern) => pattern.test(cleanStderr))) {
1442
1966
  isError = true;
1443
- errorMessage = extractOpenCodeError(cleanStderr);
1967
+ errorMessage2 = extractOpenCodeError(cleanStderr);
1444
1968
  }
1445
1969
  return createRawResult({
1446
1970
  result: resultText,
@@ -1452,7 +1976,7 @@ var init_opencode = __esm({
1452
1976
  model: modelValue
1453
1977
  }),
1454
1978
  isError,
1455
- errorMessage,
1979
+ errorMessage: errorMessage2,
1456
1980
  failureType: isError ? "crash" : "none"
1457
1981
  });
1458
1982
  } catch (err) {
@@ -1506,8 +2030,8 @@ function textContent(message) {
1506
2030
  if (!Array.isArray(message.content)) {
1507
2031
  return void 0;
1508
2032
  }
1509
- const text2 = message.content.filter((part) => typeof part === "object" && part !== null).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
1510
- return text2 || void 0;
2033
+ const text3 = message.content.filter((part) => typeof part === "object" && part !== null).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
2034
+ return text3 || void 0;
1511
2035
  }
1512
2036
  function parsePiEvents(events, configuredModel) {
1513
2037
  let result;
@@ -1578,7 +2102,7 @@ function parsePiEvents(events, configuredModel) {
1578
2102
  })
1579
2103
  };
1580
2104
  }
1581
- var READ_ONLY_TOOLS, ANSI_PATTERN3, PiFamilyProvider, PiProvider, OMPProvider;
2105
+ var READ_ONLY_TOOLS, ANSI_PATTERN4, PiFamilyProvider, PiProvider, OMPProvider;
1582
2106
  var init_pi = __esm({
1583
2107
  "src/harness/providers/pi.ts"() {
1584
2108
  init_base();
@@ -1587,7 +2111,7 @@ var init_pi = __esm({
1587
2111
  init_availability();
1588
2112
  init_modelVariant();
1589
2113
  READ_ONLY_TOOLS = /* @__PURE__ */ new Set(["read", "grep", "find", "glob", "ls", "lsp"]);
1590
- ANSI_PATTERN3 = /\x1B\[[0-?]*[ -/]*[@-~]/g;
2114
+ ANSI_PATTERN4 = /\x1B\[[0-?]*[ -/]*[@-~]/g;
1591
2115
  PiFamilyProvider = class {
1592
2116
  constructor(flavor, bin) {
1593
2117
  this.flavor = flavor;
@@ -1646,20 +2170,20 @@ var init_pi = __esm({
1646
2170
  const events = parseJsonl(stdout);
1647
2171
  const parsed = parsePiEvents(events, model);
1648
2172
  parsed.metrics.durationApiMs = Date.now() - startApi;
1649
- const cleanStderr = stderr.trim().replace(ANSI_PATTERN3, "").slice(0, 1e3);
1650
- let errorMessage;
2173
+ const cleanStderr = stderr.trim().replace(ANSI_PATTERN4, "").slice(0, 1e3);
2174
+ let errorMessage2;
1651
2175
  let failureType;
1652
2176
  if (exitCode < 0) {
1653
- errorMessage = `Process killed by signal ${-exitCode}.`;
2177
+ errorMessage2 = `Process killed by signal ${-exitCode}.`;
1654
2178
  failureType = "crash";
1655
2179
  } else if (exitCode !== 0) {
1656
- errorMessage = cleanStderr || parsed.providerError || `Process exited with code ${exitCode}.`;
2180
+ errorMessage2 = cleanStderr || parsed.providerError || `Process exited with code ${exitCode}.`;
1657
2181
  failureType = "crash";
1658
2182
  } else if (parsed.providerError) {
1659
- errorMessage = parsed.providerError;
2183
+ errorMessage2 = parsed.providerError;
1660
2184
  failureType = "api_error";
1661
2185
  } else if (!parsed.result) {
1662
- errorMessage = cleanStderr || `${this.flavor} exited successfully without an assistant response.`;
2186
+ errorMessage2 = cleanStderr || `${this.flavor} exited successfully without an assistant response.`;
1663
2187
  failureType = "no_output";
1664
2188
  } else {
1665
2189
  failureType = "none";
@@ -1669,7 +2193,7 @@ var init_pi = __esm({
1669
2193
  messages: events,
1670
2194
  metrics: parsed.metrics,
1671
2195
  isError: failureType !== "none",
1672
- errorMessage,
2196
+ errorMessage: errorMessage2,
1673
2197
  failureType,
1674
2198
  returnCode: exitCode
1675
2199
  });
@@ -1713,16 +2237,30 @@ function resolveProviderName(explicit) {
1713
2237
  const envName = process.env[HARNESS_PROVIDER_ENV_VAR]?.trim();
1714
2238
  return envName || DEFAULT_HARNESS_PROVIDER;
1715
2239
  }
2240
+ function resolveExecutionProvider(config) {
2241
+ if (!config.provider?.trim() && !process.env[HARNESS_PROVIDER_ENV_VAR]?.trim() && (config.aforgeBin !== void 0 || process.env.AFORGE_BIN?.trim())) {
2242
+ if (!legacyPinLogged) {
2243
+ legacyPinLogged = true;
2244
+ console.info('Legacy aforge pin in effect; unset it or select provider "codeaf" to use CodeAF');
2245
+ }
2246
+ return "aforge";
2247
+ }
2248
+ return resolveProviderName(config.provider);
2249
+ }
1716
2250
  async function buildProvider(config) {
1717
- const provider = resolveProviderName(config.provider);
2251
+ const provider = resolveExecutionProvider(config);
1718
2252
  if (!SUPPORTED_PROVIDERS.has(provider)) {
1719
2253
  throw new Error(
1720
2254
  `Unknown harness provider: "${provider}". Supported: ${[...SUPPORTED_PROVIDERS].sort().join(", ")}`
1721
2255
  );
1722
2256
  }
1723
- if (provider === "aforge") {
2257
+ if (provider === "aforge" && (config.aforgeBin !== void 0 || process.env.AFORGE_BIN?.trim())) {
1724
2258
  const { AforgeProvider: AforgeProvider2 } = await Promise.resolve().then(() => (init_aforge(), aforge_exports));
1725
- return new AforgeProvider2(config.aforgeBin ?? "aforge");
2259
+ return new AforgeProvider2(config.aforgeBin);
2260
+ }
2261
+ if (provider === "codeaf" || provider === "aforge") {
2262
+ const { CodeafProvider: CodeafProvider2 } = await Promise.resolve().then(() => (init_codeaf(), codeaf_exports));
2263
+ return new CodeafProvider2(config.codeafBin, provider === "aforge");
1726
2264
  }
1727
2265
  if (provider === "claude-code") {
1728
2266
  const { ClaudeCodeProvider: ClaudeCodeProvider2 } = await Promise.resolve().then(() => (init_claude(), claude_exports));
@@ -1750,13 +2288,14 @@ async function buildProvider(config) {
1750
2288
  }
1751
2289
  throw new Error(`Provider "${provider}" is not yet implemented.`);
1752
2290
  }
1753
- var SUPPORTED_PROVIDERS, DEFAULT_HARNESS_PROVIDER, HARNESS_PROVIDER_ENV_VAR;
2291
+ var SUPPORTED_PROVIDERS, DEFAULT_HARNESS_PROVIDER, HARNESS_PROVIDER_ENV_VAR, legacyPinLogged;
1754
2292
  var init_factory = __esm({
1755
2293
  "src/harness/providers/factory.ts"() {
1756
2294
  init_availability();
1757
2295
  SUPPORTED_PROVIDERS = new Set(SUPPORTED_PROVIDER_NAMES);
1758
- DEFAULT_HARNESS_PROVIDER = "aforge";
2296
+ DEFAULT_HARNESS_PROVIDER = "codeaf";
1759
2297
  HARNESS_PROVIDER_ENV_VAR = "AGENTFIELD_HARNESS_PROVIDER";
2298
+ legacyPinLogged = false;
1760
2299
  }
1761
2300
  });
1762
2301
  function isRecord3(value) {
@@ -1774,7 +2313,7 @@ function getZod4Converter() {
1774
2313
  }
1775
2314
  const requires = [];
1776
2315
  try {
1777
- requires.push(createRequire(path5__default.join(process.cwd(), "package.json")));
2316
+ requires.push(createRequire(path__default.join(process.cwd(), "package.json")));
1778
2317
  } catch {
1779
2318
  }
1780
2319
  requires.push(createRequire(import.meta.url));
@@ -1829,17 +2368,17 @@ function hasJsonSchema(value) {
1829
2368
  function hasParse(value) {
1830
2369
  return isRecord4(value) && typeof value.parse === "function";
1831
2370
  }
1832
- function estimateTokens(text2) {
1833
- return Math.floor(text2.length / 4);
2371
+ function estimateTokens(text3) {
2372
+ return Math.floor(text3.length / 4);
1834
2373
  }
1835
2374
  function writeSchemaFile(schemaJson, cwd) {
1836
2375
  const filePath = getSchemaPath(cwd);
1837
- fs2.mkdirSync(path5__default.dirname(filePath), { recursive: true });
1838
- const fd = fs2.openSync(filePath, "w", 384);
2376
+ fs.mkdirSync(path__default.dirname(filePath), { recursive: true });
2377
+ const fd = fs.openSync(filePath, "w", 384);
1839
2378
  try {
1840
- fs2.writeFileSync(fd, schemaJson, "utf8");
2379
+ fs.writeFileSync(fd, schemaJson, "utf8");
1841
2380
  } finally {
1842
- fs2.closeSync(fd);
2381
+ fs.closeSync(fd);
1843
2382
  }
1844
2383
  return filePath;
1845
2384
  }
@@ -1850,10 +2389,10 @@ function validateAgainstSchema(data, schema) {
1850
2389
  return data;
1851
2390
  }
1852
2391
  function getOutputPath(cwd) {
1853
- return path5__default.join(cwd, OUTPUT_FILENAME);
2392
+ return path__default.join(cwd, OUTPUT_FILENAME);
1854
2393
  }
1855
2394
  function getSchemaPath(cwd) {
1856
- return path5__default.join(cwd, SCHEMA_FILENAME);
2395
+ return path__default.join(cwd, SCHEMA_FILENAME);
1857
2396
  }
1858
2397
  function schemaToJsonSchema(schema) {
1859
2398
  if (isZod4Schema(schema)) {
@@ -1902,28 +2441,28 @@ ${schemaJson}
1902
2441
  Do not include any text outside the JSON in that file. Do not wrap in markdown fences.`;
1903
2442
  }
1904
2443
  function cosmeticRepair(raw) {
1905
- let text2 = raw.trim();
1906
- const fenceMatch = text2.match(/^```(?:json)?\s*\n([\s\S]*?)```\s*$/);
2444
+ let text3 = raw.trim();
2445
+ const fenceMatch = text3.match(/^```(?:json)?\s*\n([\s\S]*?)```\s*$/);
1907
2446
  if (fenceMatch) {
1908
- text2 = fenceMatch[1].trim();
2447
+ text3 = fenceMatch[1].trim();
1909
2448
  }
1910
- if (text2.length > 0 && text2[0] !== "{" && text2[0] !== "[") {
1911
- const firstJsonCharIndex = [...text2].findIndex((char) => char === "{" || char === "[");
2449
+ if (text3.length > 0 && text3[0] !== "{" && text3[0] !== "[") {
2450
+ const firstJsonCharIndex = [...text3].findIndex((char) => char === "{" || char === "[");
1912
2451
  if (firstJsonCharIndex >= 0) {
1913
- text2 = text2.slice(firstJsonCharIndex);
2452
+ text3 = text3.slice(firstJsonCharIndex);
1914
2453
  }
1915
2454
  }
1916
- text2 = text2.replace(/,\s*([}\]])/g, "$1");
1917
- const openBraces = (text2.match(/{/g)?.length ?? 0) - (text2.match(/}/g)?.length ?? 0);
1918
- const openBrackets = (text2.match(/\[/g)?.length ?? 0) - (text2.match(/\]/g)?.length ?? 0);
2455
+ text3 = text3.replace(/,\s*([}\]])/g, "$1");
2456
+ const openBraces = (text3.match(/{/g)?.length ?? 0) - (text3.match(/}/g)?.length ?? 0);
2457
+ const openBrackets = (text3.match(/\[/g)?.length ?? 0) - (text3.match(/\]/g)?.length ?? 0);
1919
2458
  if (openBraces > 0 || openBrackets > 0) {
1920
- text2 += "]".repeat(openBrackets) + "}".repeat(openBraces);
2459
+ text3 += "]".repeat(openBrackets) + "}".repeat(openBraces);
1921
2460
  }
1922
- return text2;
2461
+ return text3;
1923
2462
  }
1924
2463
  function readAndParse(filePath) {
1925
2464
  try {
1926
- const content = fs2.readFileSync(filePath, "utf8");
2465
+ const content = fs.readFileSync(filePath, "utf8");
1927
2466
  if (content.trim().length === 0) {
1928
2467
  return null;
1929
2468
  }
@@ -1934,7 +2473,7 @@ function readAndParse(filePath) {
1934
2473
  }
1935
2474
  function readRepairAndParse(filePath) {
1936
2475
  try {
1937
- const content = fs2.readFileSync(filePath, "utf8");
2476
+ const content = fs.readFileSync(filePath, "utf8");
1938
2477
  if (content.trim().length === 0) {
1939
2478
  return null;
1940
2479
  }
@@ -1964,7 +2503,7 @@ function parseAndValidate(filePath, schema) {
1964
2503
  function cleanupTempFiles(cwd) {
1965
2504
  for (const filename of [OUTPUT_FILENAME, SCHEMA_FILENAME]) {
1966
2505
  try {
1967
- fs2.unlinkSync(path5__default.join(cwd, filename));
2506
+ fs.unlinkSync(path__default.join(cwd, filename));
1968
2507
  } catch {
1969
2508
  }
1970
2509
  }
@@ -1986,7 +2525,7 @@ __export(runner_exports, {
1986
2525
  });
1987
2526
  function tokenMetrics(raw) {
1988
2527
  const { inputTokens, outputTokens, cacheReadTokens, cacheCreationTokens, totalTokens, model } = raw.metrics;
1989
- return { inputTokens, outputTokens, cacheReadTokens, cacheCreationTokens, totalTokens, model };
2528
+ return { inputTokens, outputTokens, cacheReadTokens, cacheCreationTokens, totalTokens, model, provider: raw.provider };
1990
2529
  }
1991
2530
  var TRANSIENT_PATTERNS, HarnessRunner;
1992
2531
  var init_runner = __esm({
@@ -2019,18 +2558,19 @@ var init_runner = __esm({
2019
2558
  async run(prompt, options = {}) {
2020
2559
  const { schema, ...rest } = options;
2021
2560
  const resolved = this.resolveOptions(this.config, rest);
2022
- resolved.provider = resolveProviderName(resolved.provider);
2561
+ resolved.provider = resolveExecutionProvider(resolved);
2023
2562
  const provider = await this.buildProvider(resolved.provider, resolved);
2024
2563
  const outputRoot = resolveRoot(resolved) ?? ".";
2025
2564
  let outputDir;
2026
2565
  if (schema !== void 0) {
2027
- fs2.mkdirSync(outputRoot, { recursive: true });
2028
- outputDir = fs2.mkdtempSync(path5__default.join(outputRoot, ".agentfield-out-"));
2566
+ fs.mkdirSync(outputRoot, { recursive: true });
2567
+ outputDir = fs.mkdtempSync(path__default.join(outputRoot, ".agentfield-out-"));
2029
2568
  }
2030
2569
  const effectivePrompt = schema === void 0 ? prompt : `${prompt}${buildPromptSuffix(schema, outputDir)}`;
2031
2570
  const startTime = Date.now();
2032
2571
  try {
2033
2572
  const raw = await this.executeWithRetry(provider, effectivePrompt, resolved);
2573
+ raw.provider ??= resolved.provider;
2034
2574
  if (schema !== void 0) {
2035
2575
  return this.handleSchemaOutput(raw, schema, outputDir, startTime);
2036
2576
  }
@@ -2050,7 +2590,7 @@ var init_runner = __esm({
2050
2590
  } finally {
2051
2591
  if (schema !== void 0) {
2052
2592
  cleanupTempFiles(outputDir);
2053
- fs2.rmSync(outputDir, { recursive: true, force: true });
2593
+ fs.rmSync(outputDir, { recursive: true, force: true });
2054
2594
  }
2055
2595
  }
2056
2596
  }
@@ -2073,6 +2613,7 @@ var init_runner = __esm({
2073
2613
  "env",
2074
2614
  "cwd",
2075
2615
  "projectDir",
2616
+ "codeafBin",
2076
2617
  "aforgeBin",
2077
2618
  "codexBin",
2078
2619
  "geminiBin",
@@ -2477,13 +3018,13 @@ function installApprovalWebhookRoute(app, manager, logger) {
2477
3018
  }
2478
3019
  );
2479
3020
  }
2480
- var httpAgent = new http.Agent({
3021
+ var httpAgent = new http2.Agent({
2481
3022
  keepAlive: true,
2482
3023
  maxSockets: 10,
2483
3024
  maxTotalSockets: 50,
2484
3025
  maxFreeSockets: 5
2485
3026
  });
2486
- var httpsAgent = new https.Agent({
3027
+ var httpsAgent = new https2.Agent({
2487
3028
  keepAlive: true,
2488
3029
  maxSockets: 10,
2489
3030
  maxTotalSockets: 50,
@@ -2968,6 +3509,29 @@ function recordAiSdkUsage(params) {
2968
3509
  }
2969
3510
  }
2970
3511
 
3512
+ // src/ai/PromptTemplates.ts
3513
+ var DEFAULT_TOOL_CALL_LIMIT_REACHED = "Tool call limit reached. Please provide a final response.";
3514
+ var defaultToolErrorFormatter = (toolName, error) => ({
3515
+ error,
3516
+ tool: toolName
3517
+ });
3518
+ var defaultToolResultFormatter = (_toolName, result) => result;
3519
+ function resolvePromptTemplates(overrides) {
3520
+ const limit = overrides?.toolCallLimitReached;
3521
+ return {
3522
+ toolSystemPrompt: overrides?.toolSystemPrompt,
3523
+ toolCallLimitReached: limit && limit.length > 0 ? limit : DEFAULT_TOOL_CALL_LIMIT_REACHED,
3524
+ toolErrorFormatter: overrides?.toolErrorFormatter ?? defaultToolErrorFormatter,
3525
+ toolResultFormatter: overrides?.toolResultFormatter ?? defaultToolResultFormatter
3526
+ };
3527
+ }
3528
+ var TRACE_SOURCE_USER = "user";
3529
+ var TRACE_SOURCE_ASSISTANT = "assistant";
3530
+ var TRACE_SOURCE_TOOL_SYSTEM_PROMPT = "sdk.tool_system_prompt";
3531
+ var TRACE_SOURCE_TOOL_RESULT = "sdk.tool_result";
3532
+ var TRACE_SOURCE_TOOL_ERROR = "sdk.tool_error";
3533
+ var TRACE_SOURCE_TOOL_LIMIT = "sdk.tool_limit";
3534
+
2971
3535
  // src/ai/ToolCalling.ts
2972
3536
  var DEFAULT_MAX_TURNS = 10;
2973
3537
  var DEFAULT_MAX_TOOL_CALLS = 25;
@@ -3095,7 +3659,8 @@ function isToolCallConfig(obj) {
3095
3659
  "healthStatus",
3096
3660
  "fallbackBroadening",
3097
3661
  "maxCandidateTools",
3098
- "maxHydratedTools"
3662
+ "maxHydratedTools",
3663
+ "promptTemplates"
3099
3664
  ];
3100
3665
  return typeof obj === "object" && !Array.isArray(obj) && keys.some((k) => k in obj);
3101
3666
  }
@@ -3138,7 +3703,7 @@ async function buildToolConfig(toolsParam, agent) {
3138
3703
  `Invalid tools parameter: expected "discover", ToolCallConfig, DiscoveryResult, capability array, or tool map, got ${typeof toolsParam}`
3139
3704
  );
3140
3705
  }
3141
- function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurrentTurn) {
3706
+ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurrentTurn, templates, toolMessageSources) {
3142
3707
  let totalCalls = 0;
3143
3708
  const observableTools = {};
3144
3709
  for (const [name, t] of Object.entries(toolMap)) {
@@ -3146,9 +3711,13 @@ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurr
3146
3711
  observableTools[name] = tool({
3147
3712
  description: originalTool.description ?? "",
3148
3713
  inputSchema: originalTool.inputSchema,
3149
- execute: async (args) => {
3714
+ execute: async (args, opts) => {
3150
3715
  totalCalls++;
3151
3716
  trace.totalToolCalls = totalCalls;
3717
+ const toolCallId = opts?.toolCallId;
3718
+ const recordSource = (source) => {
3719
+ if (toolCallId) toolMessageSources.set(toolCallId, source);
3720
+ };
3152
3721
  if (totalCalls > maxToolCalls) {
3153
3722
  const record2 = {
3154
3723
  toolName: name,
@@ -3158,7 +3727,9 @@ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurr
3158
3727
  turn: getCurrentTurn()
3159
3728
  };
3160
3729
  trace.calls.push(record2);
3161
- return { error: "Tool call limit reached. Please provide a final response." };
3730
+ recordSource(TRACE_SOURCE_TOOL_LIMIT);
3731
+ const limitContent = { error: templates.toolCallLimitReached };
3732
+ return limitContent;
3162
3733
  }
3163
3734
  const record = {
3164
3735
  toolName: name,
@@ -3174,12 +3745,17 @@ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurr
3174
3745
  record.result = result;
3175
3746
  record.latencyMs = Date.now() - start;
3176
3747
  trace.calls.push(record);
3177
- return result;
3748
+ recordSource(TRACE_SOURCE_TOOL_RESULT);
3749
+ const resultContent = templates.toolResultFormatter(name, result);
3750
+ return resultContent;
3178
3751
  } catch (err) {
3179
- record.error = err.message ?? String(err);
3752
+ const message = err.message ?? String(err);
3753
+ record.error = message;
3180
3754
  record.latencyMs = Date.now() - start;
3181
3755
  trace.calls.push(record);
3182
- return { error: record.error, tool: name };
3756
+ recordSource(TRACE_SOURCE_TOOL_ERROR);
3757
+ const errorContent = templates.toolErrorFormatter(name, message);
3758
+ return errorContent;
3183
3759
  }
3184
3760
  }
3185
3761
  });
@@ -3189,6 +3765,10 @@ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurr
3189
3765
  async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydration, buildModel, options = {}, modelChoice) {
3190
3766
  const maxTurns = config.maxTurns ?? DEFAULT_MAX_TURNS;
3191
3767
  const maxToolCalls = config.maxToolCalls ?? DEFAULT_MAX_TOOL_CALLS;
3768
+ const templates = resolvePromptTemplates(config.promptTemplates);
3769
+ const effectiveSystem = templates.toolSystemPrompt ? options.system ? `${options.system}
3770
+
3771
+ ${templates.toolSystemPrompt}` : templates.toolSystemPrompt : options.system;
3192
3772
  const usageModel = modelChoice?.modelName ?? options.model;
3193
3773
  const recordLoopUsage = (result2) => {
3194
3774
  if (usageModel) {
@@ -3200,6 +3780,16 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
3200
3780
  totalTurns: 0,
3201
3781
  totalToolCalls: 0
3202
3782
  };
3783
+ if (effectiveSystem) {
3784
+ (trace.messages ??= []).push({
3785
+ message: { role: "system", content: effectiveSystem },
3786
+ source: templates.toolSystemPrompt ? TRACE_SOURCE_TOOL_SYSTEM_PROMPT : TRACE_SOURCE_USER
3787
+ });
3788
+ }
3789
+ (trace.messages ??= []).push({
3790
+ message: { role: "user", content: prompt },
3791
+ source: TRACE_SOURCE_USER
3792
+ });
3203
3793
  let activeTools = toolMap;
3204
3794
  if (needsLazyHydration) {
3205
3795
  const selectionTools = {};
@@ -3214,7 +3804,7 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
3214
3804
  const selectionResult = await generateText({
3215
3805
  model: buildModel(),
3216
3806
  prompt,
3217
- system: options.system,
3807
+ system: effectiveSystem,
3218
3808
  temperature: options.temperature,
3219
3809
  maxOutputTokens: options.maxTokens,
3220
3810
  tools: selectionTools,
@@ -3229,6 +3819,7 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
3229
3819
  }
3230
3820
  }
3231
3821
  if (selectedNames.size > 0) {
3822
+ appendResponseMessages(trace, selectionResult);
3232
3823
  const hydratedTools = await hydrateSelectedTools(
3233
3824
  agent,
3234
3825
  config,
@@ -3240,22 +3831,26 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
3240
3831
  } else {
3241
3832
  trace.totalTurns = selectionResult.steps.length;
3242
3833
  trace.finalResponse = selectionResult.text;
3834
+ appendResponseMessages(trace, selectionResult);
3243
3835
  return { text: selectionResult.text, trace };
3244
3836
  }
3245
3837
  }
3246
3838
  let currentTurn = 0;
3839
+ const toolMessageSources = /* @__PURE__ */ new Map();
3247
3840
  const { tools: observableTools } = wrapToolsWithObservability(
3248
3841
  activeTools,
3249
3842
  agent,
3250
3843
  trace,
3251
3844
  maxToolCalls,
3252
- () => currentTurn
3845
+ () => currentTurn,
3846
+ templates,
3847
+ toolMessageSources
3253
3848
  );
3254
3849
  const model = buildModel();
3255
3850
  const result = await generateText({
3256
3851
  model,
3257
3852
  prompt,
3258
- system: options.system,
3853
+ system: effectiveSystem,
3259
3854
  temperature: options.temperature,
3260
3855
  maxOutputTokens: options.maxTokens,
3261
3856
  tools: observableTools,
@@ -3268,8 +3863,53 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
3268
3863
  recordLoopUsage(result);
3269
3864
  trace.finalResponse = result.text;
3270
3865
  trace.totalTurns = result.steps.length;
3866
+ appendResponseMessages(trace, result, toolMessageSources);
3271
3867
  return { text: result.text, trace };
3272
3868
  }
3869
+ function appendResponseMessages(trace, result, toolMessageSources) {
3870
+ const responseMessages = result.response?.messages;
3871
+ if (!Array.isArray(responseMessages)) {
3872
+ return;
3873
+ }
3874
+ for (const message of responseMessages) {
3875
+ const role = message?.role;
3876
+ let source;
3877
+ if (role === "assistant") {
3878
+ source = TRACE_SOURCE_ASSISTANT;
3879
+ } else if (role === "tool") {
3880
+ source = toolSourceForMessage(message, toolMessageSources);
3881
+ } else if (role === "system") {
3882
+ source = TRACE_SOURCE_TOOL_SYSTEM_PROMPT;
3883
+ } else {
3884
+ source = TRACE_SOURCE_USER;
3885
+ }
3886
+ (trace.messages ??= []).push({ message, source });
3887
+ }
3888
+ }
3889
+ function toolSourceForMessage(message, toolMessageSources) {
3890
+ const parts = Array.isArray(message?.content) ? message.content : [];
3891
+ let sawNativeError = false;
3892
+ let fallback = TRACE_SOURCE_TOOL_RESULT;
3893
+ for (const part of parts) {
3894
+ const id = part?.toolCallId;
3895
+ if (id && toolMessageSources?.has(id)) {
3896
+ const recorded = toolMessageSources.get(id);
3897
+ if (recorded !== TRACE_SOURCE_TOOL_RESULT) {
3898
+ return recorded;
3899
+ }
3900
+ fallback = recorded;
3901
+ continue;
3902
+ }
3903
+ const outputType = part?.output?.type ?? part?.type;
3904
+ if (typeof outputType === "string" && outputType.startsWith("error")) {
3905
+ sawNativeError = true;
3906
+ }
3907
+ }
3908
+ if (sawNativeError) {
3909
+ return TRACE_SOURCE_TOOL_ERROR;
3910
+ }
3911
+ return fallback;
3912
+ }
3273
3913
 
3274
3914
  // src/context/ReasonerContext.ts
3275
3915
  var ReasonerContext = class {
@@ -3360,7 +4000,9 @@ var ReasonerContext = class {
3360
4000
  const mergedConfig = {
3361
4001
  ...config,
3362
4002
  maxTurns: options.maxTurns ?? config.maxTurns ?? 10,
3363
- maxToolCalls: options.maxToolCalls ?? config.maxToolCalls ?? 25
4003
+ maxToolCalls: options.maxToolCalls ?? config.maxToolCalls ?? 25,
4004
+ // Carry the agent's prompt-template overrides into the loop (issue #229).
4005
+ promptTemplates: this.aiClient.promptTemplates ?? config.promptTemplates
3364
4006
  };
3365
4007
  const modelChoice = typeof this.aiClient.resolveModelChoice === "function" ? this.aiClient.resolveModelChoice(options) : void 0;
3366
4008
  return executeToolCallLoop(
@@ -3538,7 +4180,7 @@ var StatelessRateLimiter = class {
3538
4180
  this._containerSeed = this._getContainerSeed();
3539
4181
  }
3540
4182
  _getContainerSeed() {
3541
- const identifier = `${os.hostname()}-${process.pid}`;
4183
+ const identifier = `${os2.hostname()}-${process.pid}`;
3542
4184
  const hash = crypto2.createHash("md5").update(identifier).digest("hex");
3543
4185
  return parseInt(hash.slice(0, 8), 16);
3544
4186
  }
@@ -3761,8 +4403,8 @@ var VIDEO_MIME_TYPES = {
3761
4403
  var Text = class {
3762
4404
  type = "text";
3763
4405
  text;
3764
- constructor(text2) {
3765
- this.text = text2;
4406
+ constructor(text3) {
4407
+ this.text = text3;
3766
4408
  }
3767
4409
  };
3768
4410
  var Image = class _Image {
@@ -4027,8 +4669,8 @@ async function fileFromBase64(base64Data, mimeType) {
4027
4669
  }
4028
4670
 
4029
4671
  // src/ai/AIClient.ts
4030
- function repairJsonText(text2) {
4031
- let cleaned = text2.trim();
4672
+ function repairJsonText(text3) {
4673
+ let cleaned = text3.trim();
4032
4674
  const codeBlockMatch = cleaned.match(/```(?:json)?\s*([\s\S]*?)```/);
4033
4675
  if (codeBlockMatch) {
4034
4676
  cleaned = codeBlockMatch[1].trim();
@@ -4060,6 +4702,10 @@ var AIClient = class {
4060
4702
  ...config
4061
4703
  };
4062
4704
  }
4705
+ /** Prompt-template overrides configured on this agent, if any (issue #229). */
4706
+ get promptTemplates() {
4707
+ return this.config.promptTemplates;
4708
+ }
4063
4709
  async generate(prompt, options = {}) {
4064
4710
  const { provider, modelName, routingProvider: routingProvider2 } = this.resolveModelChoice(options);
4065
4711
  const model = this.buildModel(options);
@@ -4074,7 +4720,7 @@ var AIClient = class {
4074
4720
  temperature: options.temperature ?? this.config.temperature,
4075
4721
  maxOutputTokens: options.maxTokens ?? this.config.maxTokens,
4076
4722
  schema,
4077
- experimental_repairText: async ({ text: text2 }) => repairJsonText(text2)
4723
+ experimental_repairText: async ({ text: text3 }) => repairJsonText(text3)
4078
4724
  });
4079
4725
  const response2 = await this.withRateLimitRetry(call2);
4080
4726
  recordAiSdkUsage({ source: response2, model: modelName, provider, routingProvider: routingProvider2 });
@@ -4107,7 +4753,7 @@ var AIClient = class {
4107
4753
  return (async function* () {
4108
4754
  let completed = false;
4109
4755
  try {
4110
- for await (const text2 of streamResult.textStream) yield text2;
4756
+ for await (const text3 of streamResult.textStream) yield text3;
4111
4757
  try {
4112
4758
  const usage = await streamResult.totalUsage;
4113
4759
  if (usage) recordAiSdkUsage({ source: { totalUsage: usage }, model: modelName, provider, routingProvider: routingProvider2, tracker });
@@ -4933,11 +5579,11 @@ var AgentFieldClient = class {
4933
5579
  return snapshot.result?.result ?? snapshot.result;
4934
5580
  }
4935
5581
  const detail = snapshot.error || snapshot.statusReason || status;
4936
- const failure = Object.assign(
5582
+ const failure2 = Object.assign(
4937
5583
  new Error(`execution ${executionId} ${status}: ${detail}`),
4938
5584
  { status: 0, responseData: snapshot.errorDetails ?? snapshot.error }
4939
5585
  );
4940
- throw failure;
5586
+ throw failure2;
4941
5587
  }
4942
5588
  if (opts.timeoutMs != null && activeElapsed() >= opts.timeoutMs) {
4943
5589
  throw new Error(`waitForExecutionResult(${executionId}) timed out`);
@@ -5602,11 +6248,11 @@ var MemoryInterface = class _MemoryInterface {
5602
6248
  metadata: this.metadata
5603
6249
  });
5604
6250
  }
5605
- async embedText(text2, options) {
6251
+ async embedText(text3, options) {
5606
6252
  if (!this.aiClient) {
5607
6253
  throw new Error("AI client not configured for embeddings");
5608
6254
  }
5609
- return this.aiClient.embed(text2, options);
6255
+ return this.aiClient.embed(text3, options);
5610
6256
  }
5611
6257
  async embedTexts(texts, options) {
5612
6258
  if (!this.aiClient) {
@@ -5614,8 +6260,8 @@ var MemoryInterface = class _MemoryInterface {
5614
6260
  }
5615
6261
  return this.aiClient.embedMany(texts, options);
5616
6262
  }
5617
- async embedAndSet(key, text2, metadata, scope = this.defaultScope, scopeId = this.defaultScopeId, embeddingOptions) {
5618
- const embedding = await this.embedText(text2, embeddingOptions);
6263
+ async embedAndSet(key, text3, metadata, scope = this.defaultScope, scopeId = this.defaultScopeId, embeddingOptions) {
6264
+ const embedding = await this.embedText(text3, embeddingOptions);
5619
6265
  await this.setVector(key, embedding, metadata, scope, scopeId);
5620
6266
  return embedding;
5621
6267
  }
@@ -6613,9 +7259,9 @@ function buildSessionDefinition(name, options) {
6613
7259
  var DEFAULT_SHUTDOWN_TIMEOUT_MS = 3e4;
6614
7260
  function parseShutdownTimeout(value, warn = console.warn) {
6615
7261
  if (!value?.trim()) return DEFAULT_SHUTDOWN_TIMEOUT_MS;
6616
- const text2 = value.trim();
6617
- if (/^\d+$/.test(text2)) return Number(text2) * 1e3;
6618
- const match = text2.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)$/);
7262
+ const text3 = value.trim();
7263
+ if (/^\d+$/.test(text3)) return Number(text3) * 1e3;
7264
+ const match = text3.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)$/);
6619
7265
  if (match) {
6620
7266
  const factors = { ms: 1, s: 1e3, m: 6e4, h: 36e5 };
6621
7267
  return Number(match[1]) * factors[match[2]];
@@ -6896,7 +7542,7 @@ var Agent = class {
6896
7542
  if (!inputTokens && !outputTokens && !cacheRead && !cacheCreation && !reportedTotal && cost === null) {
6897
7543
  return;
6898
7544
  }
6899
- const providerName = resolveProviderName(options?.provider ?? this.config.harnessConfig?.provider);
7545
+ const providerName = result.provider ?? resolveProviderName(options?.provider ?? this.config.harnessConfig?.provider);
6900
7546
  const harnessName = providerName ? String(providerName).replace(/-/g, "_") : null;
6901
7547
  const rawModelName = String(
6902
7548
  result.model ?? options?.model ?? this.config.harnessConfig?.model ?? providerName ?? "harness"
@@ -7488,22 +8134,22 @@ var Agent = class {
7488
8134
  },
7489
8135
  message: { error: "rate_limit_exceeded", message: "Too many authentication attempts. Try again later." },
7490
8136
  skip: (req) => {
7491
- const path6 = req.path;
7492
- if (!path6.startsWith("/reasoners/") && !path6.startsWith("/skills/") && !path6.startsWith("/execute") && !path6.startsWith("/api/v1/reasoners/") && !path6.startsWith("/api/v1/skills/")) {
8137
+ const path8 = req.path;
8138
+ if (!path8.startsWith("/reasoners/") && !path8.startsWith("/skills/") && !path8.startsWith("/execute") && !path8.startsWith("/api/v1/reasoners/") && !path8.startsWith("/api/v1/skills/")) {
7493
8139
  return true;
7494
8140
  }
7495
- const parts = path6.replace(/^\/+/, "").split("/");
8141
+ const parts = path8.replace(/^\/+/, "").split("/");
7496
8142
  const funcName = parts[parts.length - 1] ?? "";
7497
8143
  return realtimeFunctions.has(funcName);
7498
8144
  }
7499
8145
  });
7500
8146
  this.app.use(authRateLimiter);
7501
8147
  this.app.use(async (req, res, next) => {
7502
- const path6 = req.path;
7503
- if (!path6.startsWith("/reasoners/") && !path6.startsWith("/skills/") && !path6.startsWith("/execute") && !path6.startsWith("/api/v1/reasoners/") && !path6.startsWith("/api/v1/skills/")) {
8148
+ const path8 = req.path;
8149
+ if (!path8.startsWith("/reasoners/") && !path8.startsWith("/skills/") && !path8.startsWith("/execute") && !path8.startsWith("/api/v1/reasoners/") && !path8.startsWith("/api/v1/skills/")) {
7504
8150
  return next();
7505
8151
  }
7506
- const parts = path6.replace(/^\/+/, "").split("/");
8152
+ const parts = path8.replace(/^\/+/, "").split("/");
7507
8153
  const funcName = parts[parts.length - 1] ?? "";
7508
8154
  if (realtimeFunctions.has(funcName)) {
7509
8155
  return next();
@@ -7717,9 +8363,9 @@ var Agent = class {
7717
8363
  return handler(req, res);
7718
8364
  }
7719
8365
  async handleServerlessEvent(event) {
7720
- const path6 = event?.path ?? event?.rawPath ?? "";
8366
+ const path8 = event?.path ?? event?.rawPath ?? "";
7721
8367
  const action = event?.action ?? "";
7722
- if (path6 === "/discover" || action === "discover") {
8368
+ if (path8 === "/discover" || action === "discover") {
7723
8369
  return {
7724
8370
  statusCode: 200,
7725
8371
  headers: { "content-type": "application/json" },
@@ -7728,7 +8374,7 @@ var Agent = class {
7728
8374
  }
7729
8375
  const body = this.normalizeEventBody(event);
7730
8376
  const invocation = this.extractInvocationDetails({
7731
- path: path6,
8377
+ path: path8,
7732
8378
  query: event?.queryStringParameters,
7733
8379
  body,
7734
8380
  reasoner: event?.reasoner,
@@ -7807,9 +8453,9 @@ var Agent = class {
7807
8453
  const input = this.normalizeInputPayload(params.body);
7808
8454
  return { name: name ?? void 0, targetType: typeValue, input };
7809
8455
  }
7810
- parsePathTarget(path6) {
7811
- if (!path6) return {};
7812
- const normalized = path6.split("?")[0];
8456
+ parsePathTarget(path8) {
8457
+ if (!path8) return {};
8458
+ const normalized = path8.split("?")[0];
7813
8459
  const reasonerMatch = normalized.match(/\/reasoners\/([^/]+)/);
7814
8460
  if (reasonerMatch?.[1]) {
7815
8461
  return { name: reasonerMatch[1], targetType: "reasoner" };
@@ -8549,8 +9195,8 @@ var MultimodalResponse = class {
8549
9195
  _rawResponse;
8550
9196
  _costUsd;
8551
9197
  _usage;
8552
- constructor(text2 = "", audio = null, images = [], files = [], rawResponse = null, costUsd = null, usage = {}) {
8553
- this._text = text2;
9198
+ constructor(text3 = "", audio = null, images = [], files = [], rawResponse = null, costUsd = null, usage = {}) {
9199
+ this._text = text3;
8554
9200
  this._audio = audio;
8555
9201
  this._images = images;
8556
9202
  this._files = files;
@@ -8703,7 +9349,7 @@ var MultimodalResponse = class {
8703
9349
  */
8704
9350
  async saveImage(image, imagePath) {
8705
9351
  const bytes = await this.getImageBytes(image);
8706
- await promises.mkdir(path5.dirname(imagePath), { recursive: true });
9352
+ await promises.mkdir(path.dirname(imagePath), { recursive: true });
8707
9353
  await promises.writeFile(imagePath, bytes);
8708
9354
  }
8709
9355
  /**
@@ -8711,7 +9357,7 @@ var MultimodalResponse = class {
8711
9357
  */
8712
9358
  async saveAudio(audio, audioPath) {
8713
9359
  const bytes = await this.getAudioBytes(audio);
8714
- await promises.mkdir(path5.dirname(audioPath), { recursive: true });
9360
+ await promises.mkdir(path.dirname(audioPath), { recursive: true });
8715
9361
  await promises.writeFile(audioPath, bytes);
8716
9362
  }
8717
9363
  /**
@@ -8719,7 +9365,7 @@ var MultimodalResponse = class {
8719
9365
  */
8720
9366
  async saveFile(file, filePath) {
8721
9367
  const bytes = await this.getFileBytes(file);
8722
- await promises.mkdir(path5.dirname(filePath), { recursive: true });
9368
+ await promises.mkdir(path.dirname(filePath), { recursive: true });
8723
9369
  await promises.writeFile(filePath, bytes);
8724
9370
  }
8725
9371
  /**
@@ -8730,7 +9376,7 @@ var MultimodalResponse = class {
8730
9376
  const savedFiles = {};
8731
9377
  await promises.mkdir(outputDir, { recursive: true });
8732
9378
  if (this._audio) {
8733
- const audioPath = path5.join(outputDir, `${prefix}_audio.${this._audio.format}`);
9379
+ const audioPath = path.join(outputDir, `${prefix}_audio.${this._audio.format}`);
8734
9380
  await this.saveAudio(this._audio, audioPath);
8735
9381
  savedFiles["audio"] = audioPath;
8736
9382
  }
@@ -8738,22 +9384,22 @@ var MultimodalResponse = class {
8738
9384
  const image = this._images[i];
8739
9385
  let ext = "png";
8740
9386
  if (image.url) {
8741
- const urlExt = path5.extname(image.url).slice(1);
9387
+ const urlExt = path.extname(image.url).slice(1);
8742
9388
  if (urlExt) ext = urlExt;
8743
9389
  }
8744
- const imagePath = path5.join(outputDir, `${prefix}_image_${i}.${ext}`);
9390
+ const imagePath = path.join(outputDir, `${prefix}_image_${i}.${ext}`);
8745
9391
  await this.saveImage(image, imagePath);
8746
9392
  savedFiles[`image_${i}`] = imagePath;
8747
9393
  }
8748
9394
  for (let i = 0; i < this._files.length; i++) {
8749
9395
  const file = this._files[i];
8750
9396
  const filename = file.filename || `${prefix}_file_${i}`;
8751
- const filePath = path5.join(outputDir, filename);
9397
+ const filePath = path.join(outputDir, filename);
8752
9398
  await this.saveFile(file, filePath);
8753
9399
  savedFiles[`file_${i}`] = filePath;
8754
9400
  }
8755
9401
  if (this._text) {
8756
- const textPath = path5.join(outputDir, `${prefix}_text.txt`);
9402
+ const textPath = path.join(outputDir, `${prefix}_text.txt`);
8757
9403
  await promises.writeFile(textPath, this._text, "utf-8");
8758
9404
  savedFiles["text"] = textPath;
8759
9405
  }
@@ -8782,7 +9428,7 @@ var MultimodalResponse = class {
8782
9428
  };
8783
9429
  }
8784
9430
  };
8785
- function createMultimodalResponse(rawResponse, text2 = "") {
9431
+ function createMultimodalResponse(rawResponse, text3 = "") {
8786
9432
  let audio = null;
8787
9433
  let images = [];
8788
9434
  let files = [];
@@ -8798,7 +9444,7 @@ function createMultimodalResponse(rawResponse, text2 = "") {
8798
9444
  if (extractedFiles.length > 0) {
8799
9445
  files = extractedFiles;
8800
9446
  }
8801
- return new MultimodalResponse(text2, audio, images, files, rawResponse);
9447
+ return new MultimodalResponse(text3, audio, images, files, rawResponse);
8802
9448
  }
8803
9449
  function extractImages(data) {
8804
9450
  const images = [];
@@ -9462,12 +10108,12 @@ var OpenRouterMediaProvider = class {
9462
10108
  * Call OpenRouter's OpenAI-compatible TTS endpoint (`POST /audio/speech`).
9463
10109
  * Returns raw bytes for the requested format; wraps PCM → WAV when needed.
9464
10110
  */
9465
- async generateAudioViaSpeechEndpoint(model, text2, voice, requestedFormat, request) {
10111
+ async generateAudioViaSpeechEndpoint(model, text3, voice, requestedFormat, request) {
9466
10112
  const wireFormat = requestedFormat === "wav" || requestedFormat === "pcm" || requestedFormat === "pcm16" ? "pcm" : requestedFormat;
9467
10113
  const endpoint = `${this.baseUrl}/audio/speech`;
9468
10114
  const body = {
9469
10115
  model,
9470
- input: text2,
10116
+ input: text3,
9471
10117
  voice,
9472
10118
  response_format: wireFormat
9473
10119
  };
@@ -9487,7 +10133,7 @@ var OpenRouterMediaProvider = class {
9487
10133
  model,
9488
10134
  mime_type: res.headers.get("content-type") ?? ""
9489
10135
  });
9490
- resp.text = text2;
10136
+ resp.text = text3;
9491
10137
  resp.audio = {
9492
10138
  data: bytesToBase64(finalBytes),
9493
10139
  format: requestedFormat
@@ -9530,6 +10176,8 @@ init_availability();
9530
10176
  init_modelVariant();
9531
10177
  init_factory();
9532
10178
  init_runner();
10179
+ init_aforge();
10180
+ init_codeaf();
9533
10181
  async function simulateTrigger(handler, options) {
9534
10182
  const body = options.body ?? {};
9535
10183
  const triggerContext = {
@@ -9579,6 +10227,6 @@ function loadFixture(source) {
9579
10227
  );
9580
10228
  }
9581
10229
 
9582
- export { ACTIVE_STATUSES, AIClient, Agent, AgentRouter, ApprovalClient, ApprovalResult, Audio, CANONICAL_STATUSES, CostTracker, DEFAULT_HARNESS_PROVIDER, DIDAuthenticator, DidClient, DidInterface, DidManager, ExecutionContext, ExecutionLogger, ExecutionStatus, File, HARNESS_PROVIDER_ENV_VAR, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, HarnessProviderUnavailable, HarnessRunner, Image, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, MODEL_VARIANT_SEP, MediaProviderError, MediaRouter, MemoryClient, MemoryClientBase, MemoryEventClient, MemoryInterface, MultimodalResponse, OpenRouterMediaProvider, PauseClock, PauseManager, PayloadEncryptionError, RateLimitError, RealtimeSession, ReasonerContext, SUPPORTED_PROVIDERS, SUPPORTED_PROVIDER_NAMES, SUPPORTED_SESSION_TRANSPORTS, SessionTransportError, SkillContext, StatelessRateLimiter, TERMINAL_STATUSES, Text, USAGE_ENVELOPE_KEY, Video, WorkflowReporter, applyTriggerTransform, attachUsageToSyncResult, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, audioMediaType, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, deriveProvider, encryptForDid, encryptToJwk, ensureCliAvailable, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, findExecutable, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, guessUrlMimeType, harnessDoctor, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, normalizeTurnDetection, resolveModelAndVariant, resolveProviderName, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, splitModelVariant, text, triggerToPayload, unwrapEnvelope, usageSummaryOrNull, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
10230
+ export { ACTIVE_STATUSES, AIClient, AforgeProvider, Agent, AgentRouter, ApprovalClient, ApprovalResult, Audio, CANONICAL_STATUSES, CODEAF_DEFAULT_MODEL, CodeafProvider, CostTracker, DEFAULT_HARNESS_PROVIDER, DEFAULT_TOOL_CALL_LIMIT_REACHED, DIDAuthenticator, DidClient, DidInterface, DidManager, ExecutionContext, ExecutionLogger, ExecutionStatus, File, HARNESS_PROVIDER_ENV_VAR, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, HarnessProviderUnavailable, HarnessRunner, Image, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, MODEL_VARIANT_SEP, MediaProviderError, MediaRouter, MemoryClient, MemoryClientBase, MemoryEventClient, MemoryInterface, MultimodalResponse, OpenRouterMediaProvider, PauseClock, PauseManager, PayloadEncryptionError, RateLimitError, RealtimeSession, ReasonerContext, SUPPORTED_PROVIDERS, SUPPORTED_PROVIDER_NAMES, SUPPORTED_SESSION_TRANSPORTS, SessionTransportError, SkillContext, StatelessRateLimiter, TERMINAL_STATUSES, TRACE_SOURCE_ASSISTANT, TRACE_SOURCE_TOOL_ERROR, TRACE_SOURCE_TOOL_LIMIT, TRACE_SOURCE_TOOL_RESULT, TRACE_SOURCE_TOOL_SYSTEM_PROMPT, TRACE_SOURCE_USER, Text, USAGE_ENVELOPE_KEY, Video, WorkflowReporter, applyTriggerTransform, attachUsageToSyncResult, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, audioMediaType, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, defaultToolErrorFormatter, defaultToolResultFormatter, deriveProvider, encryptForDid, encryptToJwk, ensureCliAvailable, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, findExecutable, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, guessUrlMimeType, harnessDoctor, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, normalizeTurnDetection, resolveModelAndVariant, resolvePromptTemplates, resolveProviderName, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, splitModelVariant, text, triggerToPayload, unwrapEnvelope, usageSummaryOrNull, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
9583
10231
  //# sourceMappingURL=index.js.map
9584
10232
  //# sourceMappingURL=index.js.map