{"_id":"@aether-agent/evals","_rev":"7-d13d328c7caddc3e35fe612646a605ac","name":"@aether-agent/evals","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@aether-agent/evals","version":"0.1.0","_id":"@aether-agent/evals@0.1.0","maintainers":[{"name":"jcarver989","email":"jcarver989@gmail.com"}],"homepage":"https://github.com/contextbridge/aether#readme","bugs":{"url":"https://github.com/contextbridge/aether/issues"},"dist":{"shasum":"93543dc72be3b5133be31476e18467a8b9034ddb","tarball":"https://registry.npmjs.org/@aether-agent/evals/-/evals-0.1.0.tgz","fileCount":63,"integrity":"sha512-9F2msWiqb4o1deOImTM6fkfJMDsFKfjFPwHVTNJN6OfUbUdlZM6HklcZLnZbZuQusH4gqERsCcoYcOIHzq+9Mw==","signatures":[{"sig":"MEUCIQD4E2XLxnpYfsw00L11VMk3wDkVsrTA+zcnf7wsDqNT3QIgIrql8o9rCVGL/kY0PB+JJP9dh3/RyB56qOKzJufbhJ0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105062},"type":"module","_from":"file:aether-agent-evals-0.1.0.tgz","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","compile":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"jcarver989","email":"jcarver989@gmail.com"},"_resolved":"/tmp/5539aa2f45c0a2ce333a073fe7008d61/aether-agent-evals-0.1.0.tgz","_integrity":"sha512-9F2msWiqb4o1deOImTM6fkfJMDsFKfjFPwHVTNJN6OfUbUdlZM6HklcZLnZbZuQusH4gqERsCcoYcOIHzq+9Mw==","repository":{"url":"git+https://github.com/contextbridge/aether.git","type":"git","directory":"packages/aether-evals"},"_npmVersion":"11.12.1","description":"Evaluation harness for the Aether agent SDK","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^4.4.3","testcontainers":"^12.0.3","@aether-agent/sdk":"^0.3.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^25.9.3","@types/dockerode":"^3.3.31"},"_npmOperationalInternal":{"tmp":"tmp/evals_0.1.0_1782144608494_0.19029329497807934","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aether-agent/evals","version":"0.2.0","_id":"@aether-agent/evals@0.2.0","maintainers":[{"name":"jcarver989","email":"jcarver989@gmail.com"}],"homepage":"https://github.com/contextbridge/aether#readme","bugs":{"url":"https://github.com/contextbridge/aether/issues"},"dist":{"shasum":"08ec49f95b63001cba04d5daa16ff573ca044a5a","tarball":"https://registry.npmjs.org/@aether-agent/evals/-/evals-0.2.0.tgz","fileCount":63,"integrity":"sha512-nDdasT2R1Wo8uWowIm6xoSBtvg9IKiFvJrVT6STH2R/ZdQhRd7JOq/7tDjATpvnPUz0JnS0wqLChsYelO9/KGQ==","signatures":[{"sig":"MEQCIEBkCrNDEEibbGNG7d8u6WvByauLuQrBLyiDTL2VQH5lAiB0fFdz5vC/dQ+6T2Jlc0lSxsSG8XRVA35rI8j0rGmTzg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aether-agent%2fevals@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":114138},"type":"module","_from":"file:aether-agent-evals-0.2.0.tgz","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","compile":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8ec2a7cd-d447-4cc0-a295-a3f8dbec5ec1"}},"_resolved":"/tmp/880599bf077bbca2ce1bfa6e410c6ec6/aether-agent-evals-0.2.0.tgz","_integrity":"sha512-nDdasT2R1Wo8uWowIm6xoSBtvg9IKiFvJrVT6STH2R/ZdQhRd7JOq/7tDjATpvnPUz0JnS0wqLChsYelO9/KGQ==","repository":{"url":"git+https://github.com/contextbridge/aether.git","type":"git","directory":"packages/aether-evals"},"_npmVersion":"11.12.1","description":"Evaluation harness for the Aether agent SDK","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^4.4.3","testcontainers":"^12.0.3","@aether-agent/sdk":"^0.3.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^25.9.3","@types/dockerode":"^3.3.31"},"_npmOperationalInternal":{"tmp":"tmp/evals_0.2.0_1782171357934_0.29880784753187206","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aether-agent/evals","version":"0.3.0","_id":"@aether-agent/evals@0.3.0","maintainers":[{"name":"jcarver989","email":"jcarver989@gmail.com"}],"homepage":"https://github.com/contextbridge/aether#readme","bugs":{"url":"https://github.com/contextbridge/aether/issues"},"dist":{"shasum":"bc7aa6430a8505c06beaf16a074648960c9cbfcb","tarball":"https://registry.npmjs.org/@aether-agent/evals/-/evals-0.3.0.tgz","fileCount":63,"integrity":"sha512-XUx3OPuC1+JdiqhjD1HizLcuqG4ZGxwoIKmPq3GQjgrsUpPQw29N6uBLYfdPlkUkH1RPSUDUxE6cohU4K+gefA==","signatures":[{"sig":"MEYCIQDHlgLqyoCfIGlOoPYhOMyPjz8OwsrIZNm9hzJiordUEwIhALCiAKm3azDk6rHwJSOo47JA3qrXeWWN3nxTFKB2twV4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aether-agent%2fevals@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":116402},"type":"module","_from":"file:aether-agent-evals-0.3.0.tgz","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","compile":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8ec2a7cd-d447-4cc0-a295-a3f8dbec5ec1"}},"_resolved":"/tmp/529a2a48401db554a0873001488ebf7d/aether-agent-evals-0.3.0.tgz","_integrity":"sha512-XUx3OPuC1+JdiqhjD1HizLcuqG4ZGxwoIKmPq3GQjgrsUpPQw29N6uBLYfdPlkUkH1RPSUDUxE6cohU4K+gefA==","repository":{"url":"git+https://github.com/contextbridge/aether.git","type":"git","directory":"packages/aether-evals"},"_npmVersion":"11.12.1","description":"Evaluation harness for the Aether agent SDK","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^4.4.3","testcontainers":"^12.0.3","@aether-agent/sdk":"^0.4.1"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^25.9.3","@types/dockerode":"^3.3.31"},"_npmOperationalInternal":{"tmp":"tmp/evals_0.3.0_1784670909766_0.5902905097523914","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@aether-agent/evals","version":"0.3.1","_id":"@aether-agent/evals@0.3.1","maintainers":[{"name":"jcarver989","email":"jcarver989@gmail.com"}],"homepage":"https://github.com/contextbridge/aether#readme","bugs":{"url":"https://github.com/contextbridge/aether/issues"},"dist":{"shasum":"a87379e51baf753b408ad322fdb32aaa2efd0a7a","tarball":"https://registry.npmjs.org/@aether-agent/evals/-/evals-0.3.1.tgz","fileCount":63,"integrity":"sha512-RfXT6mVChhIJ8XhiAyLMyiHYWj1pGZ8O23/ssNa+wTBsITnW1ZVj53iXosN4jbenE6FCwyWuYNsRBUbQ+66myQ==","signatures":[{"sig":"MEQCIDQexgEsSUEXFyA7VyiEvHJPOB97XJKus2fZscWWPg1rAiAMDka25vZDx59tlbzBw6E5MHckmotNjqhz6bqqKgxOtg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aether-agent%2fevals@0.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":116097},"type":"module","_from":"file:aether-agent-evals-0.3.1.tgz","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","compile":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8ec2a7cd-d447-4cc0-a295-a3f8dbec5ec1"}},"_resolved":"/tmp/10259396a130303e7f936b56c8b646d9/aether-agent-evals-0.3.1.tgz","_integrity":"sha512-RfXT6mVChhIJ8XhiAyLMyiHYWj1pGZ8O23/ssNa+wTBsITnW1ZVj53iXosN4jbenE6FCwyWuYNsRBUbQ+66myQ==","repository":{"url":"git+https://github.com/contextbridge/aether.git","type":"git","directory":"packages/aether-evals"},"_npmVersion":"11.12.1","description":"Evaluation harness for the Aether agent SDK","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^4.4.3","testcontainers":"^12.0.3","@aether-agent/sdk":"^0.4.1"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^26.1.1","@types/dockerode":"^4.0.1"},"_npmOperationalInternal":{"tmp":"tmp/evals_0.3.1_1785332494274_0.13310081644942762","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@aether-agent/evals","version":"0.3.2","_id":"@aether-agent/evals@0.3.2","maintainers":[{"name":"jcarver989","email":"jcarver989@gmail.com"}],"homepage":"https://github.com/contextbridge/aether#readme","bugs":{"url":"https://github.com/contextbridge/aether/issues"},"dist":{"shasum":"1ca6bd69d62920c112208e23ab9e24694d574c00","tarball":"https://registry.npmjs.org/@aether-agent/evals/-/evals-0.3.2.tgz","fileCount":63,"integrity":"sha512-VRSY4e9sZn/nV7lI9xG7m8nEiN0C8HNf/+pSmyCLuqRuO8HuZmfYJosLZhntHuNXqwUX+9wzVHGi1jYc5ttE1Q==","signatures":[{"sig":"MEUCIQDei/JaxoynqRcsqmu/2f4HKqnPnLHTQLXdLwEqZYBOqgIgCsqUOBMKmm8BNWuT/FiHZBZCpSzZ0hxG98z6ERl4m9w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDEz9qg/YS3FWDlImmQvLrIhZ/M4lB2TaZhBClmKUKP7AIgKjY9WKKQwfEn8Rv/d0mLjwj56uJxmN+CjnmMA9l5uz8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aether-agent%2fevals@0.3.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":115972},"type":"module","_from":"file:aether-agent-evals-0.3.2.tgz","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","compile":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8ec2a7cd-d447-4cc0-a295-a3f8dbec5ec1"}},"_resolved":"/tmp/161cd548fef44fdc2c100d8dcc355b6d/aether-agent-evals-0.3.2.tgz","_integrity":"sha512-VRSY4e9sZn/nV7lI9xG7m8nEiN0C8HNf/+pSmyCLuqRuO8HuZmfYJosLZhntHuNXqwUX+9wzVHGi1jYc5ttE1Q==","repository":{"url":"git+https://github.com/contextbridge/aether.git","type":"git","directory":"packages/aether-evals"},"_npmVersion":"11.12.1","description":"Evaluation harness for the Aether agent SDK","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^4.4.3","testcontainers":"^12.1.0","@aether-agent/sdk":"^0.6.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.11","typescript":"^6.0.3","@types/node":"^26.4.0","@types/dockerode":"^4.0.1"},"_npmOperationalInternal":{"tmp":"tmp/evals_0.3.2_1788966658214_0.3732255689770809","host":"s3://npm-registry-packages-npm-production"}},"0.3.3":{"name":"@aether-agent/evals","version":"0.3.3","_id":"@aether-agent/evals@0.3.3","maintainers":[{"name":"jcarver989","email":"jcarver989@gmail.com"}],"homepage":"https://github.com/contextbridge/aether#readme","bugs":{"url":"https://github.com/contextbridge/aether/issues"},"dist":{"shasum":"59262d1a43996ce83bdf0b6c2310da212490e6de","tarball":"https://registry.npmjs.org/@aether-agent/evals/-/evals-0.3.3.tgz","fileCount":63,"integrity":"sha512-duMQe+d5CnytEiS+Owyvj8tA9W7o2Gfzyzhs1LwzCHbADuOgLpO0R+hGMm/XHEw1gkxFLAf4vzxrZXVdLTaqSA==","signatures":[{"sig":"MEYCIQDCRvUdWG/2z8Vd+2LUH9z6cFnZV4y67tVgBffbac2KCgIhAIZX7CLNFNFrjJHCs/eXk3dZqG4h66DM5nLHuEjPmH+n","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIACgvznofhn7GXVMaKppIGFoVTvSp3lNDLfpByBOZ4OrAiEA6HKCbQAjHulfYxx/JlWbZQHclvQIwn5GrCksRULpHdk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aether-agent%2fevals@0.3.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":116081},"type":"module","_from":"file:aether-agent-evals-0.3.3.tgz","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","compile":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8ec2a7cd-d447-4cc0-a295-a3f8dbec5ec1"}},"_resolved":"/tmp/5d050b525bb6073d5a6293d29eb338ad/aether-agent-evals-0.3.3.tgz","_integrity":"sha512-duMQe+d5CnytEiS+Owyvj8tA9W7o2Gfzyzhs1LwzCHbADuOgLpO0R+hGMm/XHEw1gkxFLAf4vzxrZXVdLTaqSA==","repository":{"url":"git+https://github.com/contextbridge/aether.git","type":"git","directory":"packages/aether-evals"},"_npmVersion":"11.12.1","description":"Evaluation harness for the Aether agent SDK","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^4.4.3","testcontainers":"^12.1.0","@aether-agent/sdk":"^0.6.1"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.11","typescript":"^6.0.3","@types/node":"^26.4.0","@types/dockerode":"^4.0.1"},"_npmOperationalInternal":{"tmp":"tmp/evals_0.3.3_1789166132694_0.7375346352496237","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"_id":"@aether-agent/evals@0.4.0","bugs":{"url":"https://github.com/contextbridge/aether/issues"},"dist":{"shasum":"d01c0b1e445e8e749cad51dc5180638fe961cae1","tarball":"https://registry.npmjs.org/@aether-agent/evals/-/evals-0.4.0.tgz","fileCount":63,"integrity":"sha512-hWfF/cVccvbo10C0esv1Tj1sKCMXpP+joGhe3JHLAzjtbfc7dcjjZawlnwxCDynnjKZz5lpOpdywqcUcNOjqmw==","signatures":[{"sig":"MEQCIAyp4lE+KYwqoJsc2r27bOnywiCQdewGLLqKllIyKqvQAiByEosO8TW6EEilM7EUg8EarGNEsBuOs5m7IkPzFZJUcQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIG9hlxEDknMxgonPDgWvvxZVKb6fSZPleBcygMhYJpMTAiAbb1WpRtUfjD+R+e+HyK8tuF9sRoj977SJLa+zVwRU5A=="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aether-agent%2fevals@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":116081},"name":"@aether-agent/evals","type":"module","_from":"file:aether-agent-evals-0.4.0.tgz","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","compile":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit"},"version":"0.4.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8ec2a7cd-d447-4cc0-a295-a3f8dbec5ec1"}},"homepage":"https://github.com/contextbridge/aether#readme","_resolved":"/tmp/e92b5046a037cc9a0bcb094440aedad0/aether-agent-evals-0.4.0.tgz","_integrity":"sha512-hWfF/cVccvbo10C0esv1Tj1sKCMXpP+joGhe3JHLAzjtbfc7dcjjZawlnwxCDynnjKZz5lpOpdywqcUcNOjqmw==","repository":{"url":"git+https://github.com/contextbridge/aether.git","type":"git","directory":"packages/aether-evals"},"_npmVersion":"11.12.1","description":"Evaluation harness for the Aether agent SDK","directories":{},"maintainers":[{"name":"jcarver989","email":"jcarver989@gmail.com"}],"_nodeVersion":"24.15.0","dependencies":{"zod":"^4.4.3","testcontainers":"^12.1.0","@aether-agent/sdk":"^0.7.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.11","typescript":"^6.0.3","@types/node":"^26.4.0","@types/dockerode":"^4.0.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/evals_0.4.0_1789601337441_0.00741754617542556"}}},"time":{"created":"2026-06-22T16:10:08.290Z","modified":"2026-09-16T23:28:57.859Z","0.1.0":"2026-06-22T16:10:08.624Z","0.2.0":"2026-06-22T23:35:58.064Z","0.3.0":"2026-07-21T21:55:09.953Z","0.3.1":"2026-07-29T13:41:34.438Z","0.3.2":"2026-09-09T15:10:58.294Z","0.3.3":"2026-09-11T22:35:32.780Z","0.4.0":"2026-09-16T23:28:57.533Z"},"bugs":{"url":"https://github.com/contextbridge/aether/issues"},"homepage":"https://github.com/contextbridge/aether#readme","repository":{"url":"git+https://github.com/contextbridge/aether.git","type":"git","directory":"packages/aether-evals"},"description":"Evaluation harness for the Aether agent SDK","maintainers":[{"name":"jcarver989","email":"jcarver989@gmail.com"}],"readme":"<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n- [@aether-agent/evals](#aether-agentevals)\n  - [Install](#install)\n  - [Writing evals with vitest](#writing-evals-with-vitest)\n    - [Grading a run with an LLM judge](#grading-a-run-with-an-llm-judge)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n# @aether-agent/evals\n\nThis package facilitates writing evals for Aether agents. \n\n## Install\n\n```sh\nnpm install --save-dev @aether-agent/evals\n```\n\n## Writing evals with vitest\n\n`@aether-agent/evals` runs a single Dockerized eval per test:\n\n```ts\nimport { test, expect } from \"vitest\";\nimport {\n  Transcript,\n  DockerAgent,\n  Container,\n  Image,\n  Task,\n  Workspace,\n} from \"@aether-agent/evals\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\ntest(\"agent edits notes.txt\", async () => {\n  await using workspace = await Workspace.fromFiles({ \"notes.txt\": \"alpha\\nalpha\\n\" });\n  const task = new Task(\n    \"Change the first line of notes.txt from alpha to beta\"\n  );\n  \n  await using container = await Container.builder(\n    Image.parse(\"aether-sandbox:latest\")\n  ).start(workspace);\n  \n  const agent = new DockerAgent({\n    container,\n    command: [\"node\", \"/app/eval-agent.js\"]\n  });\n\n  const trace = await Transcript.fromStream(agent.run(task));\n  expect(trace.events.at(-1)).toMatchObject({\n    category: \"turn\",\n    event: { type: \"ended\" },\n  });\n  \n  // Assert against the retained workspace and the recorded tool calls.\n  expect(await readFile(join(workspace.path, \"notes.txt\"), \"utf8\")).toBe(\n    \"beta\\nalpha\\n\",\n  );\n  \n  const tests = await container.exec({ command: [\"pnpm\", \"test\"] });\n  expect(tests.exitCode).toBe(0);\n  \n  // Workspace is removed when `workspace` goes out of scope; run container exec assertions first.\n});\n```\n\n### Grading a run with an LLM judge\n\n```ts\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { test, expect } from \"vitest\";\nimport {\n  Transcript,\n  DockerAgent,\n  Container,\n  Image,\n  generate,\n  judge,\n  Task,\n  Workspace,\n} from \"@aether-agent/evals\";\n\ntest(\"agent makes a maintainer-quality edit\", async () => {\n  await using workspace = await Workspace.fromFiles({ \"notes.txt\": \"alpha\\nalpha\\n\" });\n  const task = new Task(\n    \"Change the first line of notes.txt from alpha to beta\",\n  );\n  \n  await using container = await Container.builder(\n    Image.parse(\"aether-sandbox:latest\"),\n  ).start(workspace);\n  \n  const agent = new DockerAgent({\n    container,\n    command: [\"node\", \"/app/eval-agent.js\"],\n  });\n  \n  const trace = await Transcript.fromStream(agent.run(task));\n  const grader = judge({\n    instructions: \"Grade strictly using only the provided transcript and files.\",\n    task: \"Change the first line of notes.txt from alpha to beta\",\n    context: {\n      transcript: trace.events,\n      files: {\n        \"notes.txt\": await readFile(join(workspace.path, \"notes.txt\"), \"utf8\"),\n      },\n    },\n    criteria: [\n      {\n        id: \"correct-edit\",\n        description: \"The final notes.txt content is exactly 'beta\\\\nalpha\\\\n'.\",\n        blocking: true,\n        threshold: 1,\n        weight: 3,\n      },\n      {\n        id: \"minimal-change\",\n        description: \"No unrelated files or lines were changed.\",\n        blocking: true,\n        threshold: 0.8,\n        weight: 2,\n      },\n    ],\n  });\n\n  const response = await generate(grader.prompt, {\n    model: \"anthropic:claude-sonnet-4-5\", // or set AETHER_LLM_MODEL\n    temperature: 0,\n    schema: grader.schema,\n  });\n  \n  const summary = grader.summarize(response);\n  expect(summary.passed, summary.reason).toBe(true);\n});\n```\n","readmeFilename":"README.md"}