@apo-ai/sdk 0.2.2 → 0.3.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.
@@ -1,5 +1,4 @@
1
- import { A as AgentTaskTraceContext } from '../../tracing-DtbhYQV6.js';
2
- import '../../types-C-nrDEVf.js';
1
+ import { A as AgentTaskTraceContext } from '../../tracing-BE53Q8Ru.js';
3
2
 
4
3
  /**
5
4
  * Vercel AI SDK tracing integration for apo.
@@ -1,5 +1,4 @@
1
- import { A as AgentTaskTraceContext } from '../../tracing-DtbhYQV6.js';
2
- import '../../types-C-nrDEVf.js';
1
+ import { A as AgentTaskTraceContext } from '../../tracing-BE53Q8Ru.js';
3
2
 
4
3
  /**
5
4
  * Anthropic JS SDK tracing integration for apo.
@@ -1,5 +1,4 @@
1
- import { A as AgentTaskTraceContext } from '../../tracing-DtbhYQV6.js';
2
- import '../../types-C-nrDEVf.js';
1
+ import { A as AgentTaskTraceContext } from '../../tracing-BE53Q8Ru.js';
3
2
 
4
3
  /**
5
4
  * OpenAI JS SDK tracing integration for apo.
@@ -1,8 +1,7 @@
1
- import { A as AgentTaskTraceContext, a as AgentTaskTraceOptions } from '../tracing-DtbhYQV6.js';
1
+ import { A as AgentTaskTraceContext, a as AgentTaskTraceOptions } from '../tracing-BE53Q8Ru.js';
2
2
  export { CreateApoTracerOptions, createApoTracer } from './integrations/ai-sdk.js';
3
3
  export { CreateApoOpenAIOptions, createApoOpenAI } from './integrations/openai.js';
4
4
  export { CreateApoAnthropicOptions, createApoAnthropic } from './integrations/anthropic.js';
5
- import '../types-C-nrDEVf.js';
6
5
 
7
6
  type TaskDefinition<TAdapterName extends string = string, TDeliverable extends string = string> = {
8
7
  id: string;
@@ -1053,6 +1052,85 @@ type RunTaskOptions = {
1053
1052
  };
1054
1053
  declare function runTask(taskDir: string, options?: RunTaskOptions): Promise<TaskRunResult>;
1055
1054
 
1055
+ /**
1056
+ * Issue #159: replay Phase 2 of a completed Run against its stored
1057
+ * Deliverables — without re-running the agent.
1058
+ *
1059
+ * The backend serves what replay reads (run detail, Deliverable bodies, the
1060
+ * pinned Task Definition source, the canonical trace projection) and stores
1061
+ * what replay produces (a judgment record — submitted by the CLI, not here).
1062
+ * The eval source itself is executed HERE, never in the backend: the
1063
+ * definition revision's contract is that the backend stores source as
1064
+ * private data and never executes it.
1065
+ *
1066
+ * Rules this module enforces on itself:
1067
+ * - whole-run replay: the full registered check set runs every sample;
1068
+ * - the Run must be terminal (passed/failed) and every Deliverable ready —
1069
+ * a missing Deliverable must surface as a refusal, not a low score;
1070
+ * - scoring defaults to the Run's pinned definition revision; an explicit
1071
+ * different revision is allowed but reported as unpinned so it can never
1072
+ * be misread as "the same eval, better judge".
1073
+ */
1074
+
1075
+ /** Backend coordinates for every read replay performs. */
1076
+ interface RejudgeEndpoints {
1077
+ /** Backend base URL, e.g. ``"http://localhost:8000"``. */
1078
+ backendUrl: string;
1079
+ /** Project API key (Authorization: Bearer …). Never recorded on judgments. */
1080
+ authToken: string;
1081
+ }
1082
+ interface RejudgeOptions {
1083
+ /** Judge config for ``t.judge`` calls; the API key stays client-side. */
1084
+ judge?: JudgeConfig;
1085
+ /** Judge the same Deliverables N times for a per-criterion stability measure. */
1086
+ samples?: number;
1087
+ /** Score against this revision instead of the Run's pinned one. */
1088
+ definitionRevisionId?: string;
1089
+ /**
1090
+ * Local checkout of the task directory. The stored revision pins only the
1091
+ * eval file, so relative imports and `files/` fixtures resolve from here.
1092
+ */
1093
+ taskDir?: string;
1094
+ /** Max wait for the canonical trace projection (default 30s). */
1095
+ projectionDeadlineMs?: number;
1096
+ /** Progress sink for human-facing operators (CLI prints to stderr). */
1097
+ onProgress?: (message: string) => void;
1098
+ }
1099
+ /** Per-check pass counts across samples — "fails 2 of 5", not "failed". */
1100
+ interface RejudgeCheckStability {
1101
+ check_id: string;
1102
+ passes: number;
1103
+ samples: number;
1104
+ }
1105
+ interface RejudgeOutcome {
1106
+ runId: string;
1107
+ taskId: string;
1108
+ /** Revision the checks were actually scored against. */
1109
+ definitionRevisionId: string;
1110
+ /** False when an explicit --definition-revision moved the target. */
1111
+ definitionRevisionIsPinned: boolean;
1112
+ /** Resolved judge config actually used (model + base URL, never the key). */
1113
+ judge: {
1114
+ model: string;
1115
+ baseURL?: string;
1116
+ } | null;
1117
+ samples: number;
1118
+ /** Full check results from the primary (first) sample. */
1119
+ checks: EvaluationItemResult[];
1120
+ pass: boolean;
1121
+ /** Only meaningful with samples > 1; ordered like the primary sample. */
1122
+ stability: RejudgeCheckStability[];
1123
+ /** False when the trace projection was unreadable — trajectory assertions were unsupported. */
1124
+ traceSnapshotAvailable: boolean;
1125
+ /** The local task dir replay ran against, or null for an isolated scaffold. */
1126
+ taskDirUsed: string | null;
1127
+ }
1128
+ /** A deliberate, operator-facing replay failure (refusals, bad state). */
1129
+ declare class RejudgeError extends Error {
1130
+ constructor(message: string);
1131
+ }
1132
+ declare function rejudgeTaskRun(runId: string, endpoints: RejudgeEndpoints, options?: RejudgeOptions): Promise<RejudgeOutcome>;
1133
+
1056
1134
  type AgentTaskCliOptions = {
1057
1135
  task?: string;
1058
1136
  dir?: string;
@@ -1325,4 +1403,4 @@ declare function canonicalManifestJson(manifest: TaskRevisionManifestV1): string
1325
1403
  /** SHA-256 (lowercase hex) of the canonical manifest JSON's UTF-8 bytes. */
1326
1404
  declare function contentSha256(manifest: TaskRevisionManifestV1): string;
1327
1405
 
1328
- export { type AISDKResult, type AdapterDefinition, type AdapterRuntimeState, type AdapterSession, type AgentTaskCliOptions, type AgentTaskRunConfiguration, AgentTaskRunError, type AgentTaskRunSummary, type AgentTaskRuntime, AgentTaskTraceContext, AgentTaskTraceOptions, type AgentTurnResult, type AnthropicMessage, type ApoRunContext, ApoSpanProcessor, type ArtifactUploadConfig, type CheckContext, type CheckGroup, type CleanupContext, type CollectDeliverablesContext, type CollectedDeliverables, type DeliverableDefinition, type DeliverableSummary, type DeliverableValidationResult, type DescribeRegistration, type FileArtifact, type FileArtifactOptions, type FileEntry, type Flow, type FlowEvent, FlowView, type InitializeContext, type JudgeConfig, type LoadedTask, type ManifestFile, type ManifestFileInput, type Matcher, type ModeClass, type NameMatcher, type OpenAIMessage, type PreparedTaskResult, type RegisterApoTracingOptions, type RunTaskOptions, type StartSessionContext, TEST_METHOD_NAMES, type TaskConfig, type TaskDefinition, type TaskEvaluationResult, TaskFiles, type TaskRevisionManifestV1, type TaskRunResult, type TaskScope, type TaskTranscript, type TaskTranscriptTurn, type TestContext, type TestRegistration, type ToolCallOptions, type ToolCallStatus, type TurnContext, type TurnFn, type TurnRecord, type TypedAdapterDefinition, type ValueMatcher, buildManifest, canonicalManifestJson, contentSha256, defineAdapter, defineTask, describe, discoverAgentTaskDirs, equals, fileArtifact, filePaths, fromAISDK, fromAnthropicMessages, fromOpenAIMessages, getActiveApoRun, getTaskTurn, includes, isFileArtifact, loadTask, loadTaskRuntime, matchValue, matches, normalizeManifestPath, parseAgentTaskCliArgs, persistFileArtifacts, registerApoTracing, resetApoTracing, resetFlowChecks, resetTaskRegistry, resetTaskTurn, resolveTurn, runAgentTaskCli, runTask, runTaskDir, satisfies, sha256Hex, similarity, task, defineCheck as test, turn, withApoRun, withApoRunSync };
1406
+ export { type AISDKResult, type AdapterDefinition, type AdapterRuntimeState, type AdapterSession, type AgentTaskCliOptions, type AgentTaskRunConfiguration, AgentTaskRunError, type AgentTaskRunSummary, type AgentTaskRuntime, AgentTaskTraceContext, AgentTaskTraceOptions, type AgentTurnResult, type AnthropicMessage, type ApoRunContext, ApoSpanProcessor, type ArtifactUploadConfig, type CheckContext, type CheckGroup, type CleanupContext, type CollectDeliverablesContext, type CollectedDeliverables, type DeliverableDefinition, type DeliverableSummary, type DeliverableValidationResult, type DescribeRegistration, type FileArtifact, type FileArtifactOptions, type FileEntry, type Flow, type FlowEvent, FlowView, type InitializeContext, type JudgeConfig, type LoadedTask, type ManifestFile, type ManifestFileInput, type Matcher, type ModeClass, type NameMatcher, type OpenAIMessage, type PreparedTaskResult, type RegisterApoTracingOptions, type RejudgeCheckStability, type RejudgeEndpoints, RejudgeError, type RejudgeOptions, type RejudgeOutcome, type RunTaskOptions, type StartSessionContext, TEST_METHOD_NAMES, type TaskConfig, type TaskDefinition, type TaskEvaluationResult, TaskFiles, type TaskRevisionManifestV1, type TaskRunResult, type TaskScope, type TaskTranscript, type TaskTranscriptTurn, type TestContext, type TestRegistration, type ToolCallOptions, type ToolCallStatus, type TurnContext, type TurnFn, type TurnRecord, type TypedAdapterDefinition, type ValueMatcher, buildManifest, canonicalManifestJson, contentSha256, defineAdapter, defineTask, describe, discoverAgentTaskDirs, equals, fileArtifact, filePaths, fromAISDK, fromAnthropicMessages, fromOpenAIMessages, getActiveApoRun, getTaskTurn, includes, isFileArtifact, loadTask, loadTaskRuntime, matchValue, matches, normalizeManifestPath, parseAgentTaskCliArgs, persistFileArtifacts, registerApoTracing, rejudgeTaskRun, resetApoTracing, resetFlowChecks, resetTaskRegistry, resetTaskTurn, resolveTurn, runAgentTaskCli, runTask, runTaskDir, satisfies, sha256Hex, similarity, task, defineCheck as test, turn, withApoRun, withApoRunSync };
@@ -919,7 +919,7 @@ function attachAdapter(taskDefinition, adapter) {
919
919
  }
920
920
 
921
921
  // src/agent-task/task/loadTask.ts
922
- import { copyFileSync as copyFileSync2, readdirSync, statSync, existsSync as existsSync2, unlinkSync as unlinkSync2 } from "fs";
922
+ import { copyFileSync as copyFileSync2, readdirSync, statSync, existsSync as existsSync2, unlinkSync as unlinkSync2, writeFileSync } from "fs";
923
923
  import { join, resolve, basename as basename2 } from "path";
924
924
  import { pathToFileURL as pathToFileURL2 } from "url";
925
925
 
@@ -966,6 +966,48 @@ async function loadTask(taskDir) {
966
966
  evalFileName: basename2(taskFilePath)
967
967
  };
968
968
  }
969
+ async function loadEvalSource(fileName, content, opts = {}) {
970
+ const dir = opts.siblingDir ?? opts.isolatedDir;
971
+ if (!dir) {
972
+ throw new Error("loadEvalSource requires a siblingDir or isolatedDir to materialize next to");
973
+ }
974
+ const tempPath = join(
975
+ dir,
976
+ `${fileName}.rejudge-${Date.now()}-${Math.random().toString(36).slice(2)}.ts`
977
+ );
978
+ writeFileSync(tempPath, content);
979
+ try {
980
+ const { task: task2, adapter, inlineChecks, moduleUrl } = await loadTaskDefinition(tempPath);
981
+ validateTaskDefinition(task2, dir);
982
+ if (!inlineChecks && !existsSync2(join(dir, "checks.ts"))) {
983
+ throw new Error(
984
+ `The pinned eval did not register checks: legacy two-file tasks need their checks module, which the stored definition revision does not include`
985
+ );
986
+ }
987
+ return {
988
+ task: task2,
989
+ adapter,
990
+ taskDir: dir,
991
+ files: loadFilesDirectory(dir),
992
+ checksPath: resolveChecksPath(task2, dir),
993
+ inlineChecks,
994
+ moduleUrl,
995
+ evalFileName: fileName
996
+ };
997
+ } catch (error) {
998
+ const message = error instanceof Error ? error.message : String(error);
999
+ if (!opts.siblingDir && /Failed to load task definition/.test(message)) {
1000
+ throw new Error(
1001
+ `Replay needs the task directory: the pinned eval imports sibling files that are not part of the stored definition revision. Point the command at a checkout of the task (--task-dir) and retry. Underlying error: ${message}`
1002
+ );
1003
+ }
1004
+ throw error;
1005
+ } finally {
1006
+ if (existsSync2(tempPath)) {
1007
+ unlinkSync2(tempPath);
1008
+ }
1009
+ }
1010
+ }
969
1011
  async function loadTaskDefinition(taskFilePath) {
970
1012
  const tempModulePath = `${taskFilePath}.${Date.now()}-${Math.random().toString(36).slice(2)}.ts`;
971
1013
  try {
@@ -2315,12 +2357,247 @@ function buildTraceRunOptions(loaded, tracing) {
2315
2357
  };
2316
2358
  }
2317
2359
 
2360
+ // src/agent-task/run/rejudge.ts
2361
+ import { mkdtempSync, rmSync, writeFileSync as writeFileSync2 } from "fs";
2362
+ import { tmpdir } from "os";
2363
+ import { basename as basename4, dirname, join as join2 } from "path";
2364
+ import { fileURLToPath } from "url";
2365
+ var RejudgeError = class extends Error {
2366
+ constructor(message) {
2367
+ super(message);
2368
+ this.name = "RejudgeError";
2369
+ }
2370
+ };
2371
+ var TERMINAL_VERDICT_STATUSES = /* @__PURE__ */ new Set(["passed", "failed"]);
2372
+ var MAX_SAMPLES = 50;
2373
+ async function rejudgeTaskRun(runId, endpoints, options = {}) {
2374
+ const api = createApiClient(endpoints);
2375
+ const progress = options.onProgress ?? (() => {
2376
+ });
2377
+ const detail = await api.get(`/v1/agent-task-runs/${runId}`);
2378
+ if (!TERMINAL_VERDICT_STATUSES.has(detail.status)) {
2379
+ throw new RejudgeError(
2380
+ `Run ${runId} is '${detail.status}', not a completed run with a verdict \u2014 there is nothing to replay against yet`
2381
+ );
2382
+ }
2383
+ const manifest = await api.get(
2384
+ `/v1/agent-task-runs/${runId}/deliverables`
2385
+ );
2386
+ const items = manifest.items ?? [];
2387
+ const notReady = items.filter((item) => item.status !== "ready");
2388
+ if (notReady.length > 0) {
2389
+ const names = notReady.map((item) => `${item.name} (${item.status})`).join(", ");
2390
+ throw new RejudgeError(
2391
+ `Refusing to replay run ${runId}: deliverables are not ready: ${names}. A missing deliverable must not render as a low score \u2014 re-run the agent instead.`
2392
+ );
2393
+ }
2394
+ const requestedRevision = options.definitionRevisionId ?? detail.task_definition?.id ?? null;
2395
+ if (!requestedRevision) {
2396
+ throw new RejudgeError(
2397
+ `Run ${runId} has no pinned Task Definition Revision \u2014 its checks cannot be replayed`
2398
+ );
2399
+ }
2400
+ const sourceQuery = options.definitionRevisionId && options.definitionRevisionId !== detail.task_definition?.id ? `?revision=${encodeURIComponent(options.definitionRevisionId)}` : "";
2401
+ progress(`fetching definition source (${requestedRevision})`);
2402
+ const source = await api.get(
2403
+ `/v1/agent-task-runs/${runId}/definition-source${sourceQuery}`
2404
+ );
2405
+ const revisionId = source.task_definition_revision_id;
2406
+ const revisionIsPinned = revisionId === (detail.task_definition?.id ?? null);
2407
+ const evalFile = source.files[0];
2408
+ if (!evalFile) {
2409
+ throw new RejudgeError(`Definition revision ${revisionId} carries no source files`);
2410
+ }
2411
+ progress("fetching stored deliverables");
2412
+ const artifactDir = mkdtempSync(join2(tmpdir(), "apo-rejudge-artifacts-"));
2413
+ let scaffoldDir = null;
2414
+ try {
2415
+ const taskDir = options.taskDir ?? null;
2416
+ scaffoldDir = taskDir ? null : isolatedScaffoldDir();
2417
+ const deliverables = await fetchDeliverables(api, runId, items, artifactDir);
2418
+ progress("reading canonical trace projection");
2419
+ const snapshotResult = await readCanonicalSnapshot2(
2420
+ endpoints,
2421
+ runId,
2422
+ options.projectionDeadlineMs
2423
+ );
2424
+ if (!snapshotResult.available) {
2425
+ progress(
2426
+ "trace projection unavailable \u2014 trajectory assertions (t.calledTool, \u2026) will be recorded as unsupported rather than replayed"
2427
+ );
2428
+ }
2429
+ const snapshot = snapshotResult.snapshot;
2430
+ const loaded = await loadEvalSource(evalFile.path, evalFile.content, {
2431
+ siblingDir: taskDir,
2432
+ isolatedDir: scaffoldDir
2433
+ });
2434
+ progress(`loaded eval ${evalFile.path} from revision ${revisionId}`);
2435
+ const missingDeliverables = loaded.task.deliverables.filter(
2436
+ (name) => !Object.prototype.hasOwnProperty.call(deliverables, name)
2437
+ );
2438
+ if (missingDeliverables.length > 0) {
2439
+ throw new RejudgeError(
2440
+ `Refusing to replay run ${runId}: stored deliverables are incomplete; missing ${missingDeliverables.join(", ")}. Re-run the agent instead.`
2441
+ );
2442
+ }
2443
+ const samples = Math.max(1, Math.min(options.samples ?? 1, MAX_SAMPLES));
2444
+ const validation = validateDeliverables(
2445
+ loaded.task,
2446
+ deliverables,
2447
+ loaded.adapter.deliverables
2448
+ );
2449
+ const proxied = proxyBrokenDeliverables(deliverables, validation.brokenDeliverables);
2450
+ const passCounts = /* @__PURE__ */ new Map();
2451
+ let primary = [];
2452
+ for (let sample = 0; sample < samples; sample++) {
2453
+ if (samples > 1) progress(`judging sample ${sample + 1}/${samples}`);
2454
+ const results = await runChecksOnce(loaded, proxied, snapshot, options.judge);
2455
+ if (sample === 0) primary = results;
2456
+ for (const result of results) {
2457
+ passCounts.set(result.id, (passCounts.get(result.id) ?? 0) + (result.pass ? 1 : 0));
2458
+ }
2459
+ }
2460
+ const stability = primary.map((result) => ({
2461
+ check_id: result.id,
2462
+ passes: passCounts.get(result.id) ?? 0,
2463
+ samples
2464
+ }));
2465
+ const aggregate = aggregateResult(primary);
2466
+ return {
2467
+ runId,
2468
+ taskId: detail.task_id,
2469
+ definitionRevisionId: revisionId,
2470
+ definitionRevisionIsPinned: revisionIsPinned,
2471
+ judge: options.judge ? {
2472
+ model: options.judge.model,
2473
+ baseURL: options.judge.baseURL ?? process.env.OPENROUTER_BASE_URL
2474
+ } : null,
2475
+ samples,
2476
+ checks: aggregate.checks,
2477
+ pass: aggregate.pass,
2478
+ stability,
2479
+ traceSnapshotAvailable: snapshotResult.available,
2480
+ taskDirUsed: taskDir
2481
+ };
2482
+ } finally {
2483
+ rmSync(artifactDir, { recursive: true, force: true });
2484
+ if (scaffoldDir) rmSync(scaffoldDir, { recursive: true, force: true });
2485
+ }
2486
+ }
2487
+ async function runChecksOnce(loaded, deliverables, snapshot, judgeConfig) {
2488
+ if (loaded.inlineChecks) {
2489
+ return runTraceChecks({
2490
+ snapshot,
2491
+ deliverables,
2492
+ files: loaded.files,
2493
+ task: loaded.task,
2494
+ judgeConfig,
2495
+ moduleUrl: loaded.moduleUrl,
2496
+ displayFile: loaded.evalFileName
2497
+ });
2498
+ }
2499
+ return loadAndRunFlowChecks(
2500
+ loaded.checksPath,
2501
+ {
2502
+ snapshot,
2503
+ deliverables,
2504
+ files: loaded.files,
2505
+ task: loaded.task,
2506
+ judgeConfig
2507
+ },
2508
+ {}
2509
+ );
2510
+ }
2511
+ async function fetchDeliverables(api, runId, items, artifactDir) {
2512
+ const deliverables = {};
2513
+ for (const [index, item] of items.entries()) {
2514
+ if (item.kind === "artifact") {
2515
+ const bytes = await api.getBytes(`/v1/agent-task-runs/${runId}/deliverables/${item.id}`);
2516
+ const displayFilename = item.display_filename || item.name;
2517
+ const safeFilename = basename4(displayFilename) || "artifact";
2518
+ const path = join2(artifactDir, `artifact-${index}-${safeFilename}`);
2519
+ writeFileSync2(path, bytes);
2520
+ deliverables[item.name] = Object.freeze({
2521
+ kind: "apo.file-artifact",
2522
+ path,
2523
+ mediaType: item.media_type ?? "application/octet-stream",
2524
+ displayFilename
2525
+ });
2526
+ } else {
2527
+ deliverables[item.name] = await api.getJson(
2528
+ `/v1/agent-task-runs/${runId}/deliverables/${item.id}`
2529
+ );
2530
+ }
2531
+ }
2532
+ return deliverables;
2533
+ }
2534
+ async function readCanonicalSnapshot2(endpoints, runId, deadlineMs) {
2535
+ try {
2536
+ const snapshot = await readTaskRunProjection({
2537
+ endpoint: endpoints.backendUrl,
2538
+ authToken: endpoints.authToken,
2539
+ taskRunId: runId,
2540
+ deadlineMs: deadlineMs ?? 15e3
2541
+ });
2542
+ return { available: true, snapshot };
2543
+ } catch {
2544
+ return { available: false, snapshot: degenerateSnapshot(runId) };
2545
+ }
2546
+ }
2547
+ function degenerateSnapshot(runId) {
2548
+ return {
2549
+ schemaVersion: 1,
2550
+ projectionVersion: 1,
2551
+ source: "local",
2552
+ trace: { traceId: `rejudge-${runId}`, complete: true },
2553
+ capabilities: {
2554
+ messages: "unavailable",
2555
+ tools: "unavailable",
2556
+ errors: "unavailable",
2557
+ timing: "unavailable",
2558
+ skills: "unavailable",
2559
+ subagents: "unavailable"
2560
+ },
2561
+ observations: []
2562
+ };
2563
+ }
2564
+ function isolatedScaffoldDir() {
2565
+ const here = dirname(fileURLToPath(import.meta.url));
2566
+ return mkdtempSync(join2(here, ".rejudge-scaffold-"));
2567
+ }
2568
+ function createApiClient(endpoints) {
2569
+ const base = endpoints.backendUrl.replace(/\/$/, "");
2570
+ const headers = { Authorization: `Bearer ${endpoints.authToken}` };
2571
+ async function request(path) {
2572
+ const response = await fetch(`${base}${path}`, { headers });
2573
+ if (!response.ok) {
2574
+ const body = await response.text().catch(() => "");
2575
+ throw new RejudgeError(
2576
+ `${path} failed (${response.status}): ${body.slice(0, 200) || response.statusText}`
2577
+ );
2578
+ }
2579
+ return response;
2580
+ }
2581
+ return {
2582
+ async get(path) {
2583
+ return await request(path).then((r) => r.json());
2584
+ },
2585
+ async getJson(path) {
2586
+ return request(path).then((r) => r.json());
2587
+ },
2588
+ async getBytes(path) {
2589
+ const buffer = await request(path).then((r) => r.arrayBuffer());
2590
+ return Buffer.from(new Uint8Array(buffer));
2591
+ }
2592
+ };
2593
+ }
2594
+
2318
2595
  // src/agent-task/cli.ts
2319
2596
  import { relative, resolve as resolve3 } from "path";
2320
2597
 
2321
2598
  // src/agent-task/discovery.ts
2322
2599
  import { existsSync as existsSync3, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
2323
- import { join as join2, resolve as resolve2 } from "path";
2600
+ import { join as join3, resolve as resolve2 } from "path";
2324
2601
  function discoverAgentTaskDirs(rootDir) {
2325
2602
  const absoluteRoot = resolve2(rootDir);
2326
2603
  if (!existsSync3(absoluteRoot) || !statSync3(absoluteRoot).isDirectory()) {
@@ -2336,7 +2613,7 @@ function walkForTaskDirs(currentDir, discovered) {
2336
2613
  return;
2337
2614
  }
2338
2615
  for (const entry of readdirSync2(currentDir)) {
2339
- const absolutePath = join2(currentDir, entry);
2616
+ const absolutePath = join3(currentDir, entry);
2340
2617
  if (!statSync3(absolutePath).isDirectory()) {
2341
2618
  continue;
2342
2619
  }
@@ -2998,6 +3275,7 @@ export {
2998
3275
  AgentTaskRunError,
2999
3276
  ApoSpanProcessor,
3000
3277
  FlowView,
3278
+ RejudgeError,
3001
3279
  TEST_METHOD_NAMES,
3002
3280
  TaskFiles,
3003
3281
  buildManifest,
@@ -3028,6 +3306,7 @@ export {
3028
3306
  parseAgentTaskCliArgs,
3029
3307
  persistFileArtifacts,
3030
3308
  registerApoTracing,
3309
+ rejudgeTaskRun,
3031
3310
  resetApoTracing,
3032
3311
  resetFlowChecks,
3033
3312
  resetTaskRegistry,