diff --git a/experiments/agent-changes/Dockerfile b/experiments/agent-changes/Dockerfile new file mode 100644 index 000000000..730ec49d6 --- /dev/null +++ b/experiments/agent-changes/Dockerfile @@ -0,0 +1,47 @@ +# Container image for the think example. Identical wiring to +# examples/container — we pull a computerd binary out of the public +# GHCR image, drop it into a slim debian, and run it as PID 1. +# The :VERSION tag is rewritten by the changesets Version Packages PR +# through .github/changeset-version.mjs. +# +# computerd mounts a FUSE filesystem at MOUNT_POINT so exec'd commands +# (git, npm, vitest, …) see the same files the Workspace RPC +# surface reads and writes. + + +FROM ghcr.io/cloudflare/computer-computerd-linux-x64:0.4.1 AS computerd + +FROM debian:stable-slim + +# We install Node 22 (LTS) from NodeSource so the agent has +# `node`, `npm`, and `npx` on $PATH for the typical "clone the +# repo, npm install, npm test" loop. curl + gnupg are pulled in +# just for the NodeSource key dance and stay in the image; they +# come in handy for ad-hoc agent commands too. The cost is ~120 MB +# of layer over the base; acceptable for an example whose whole +# point is running real build/test workflows. +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + fuse3 libfuse2t64 ca-certificates curl gnupg git \ + && mkdir -p /etc/apt/keyrings \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \ + | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" \ + > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y --no-install-recommends nodejs \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=computerd /usr/local/bin/computerd /usr/local/bin/computerd + +ENV PORT=8080 +ENV MOUNT_POINT=/workspace +# FUSE_MOUNT=auto probes /dev/fuse at startup and uses the real +# kernel FUSE backend when available (Cloudflare Containers in +# production) or transparently falls back to the userspace shim +# (wrangler dev, sandboxes without CAP_SYS_ADMIN). Same image works +# in both environments. +ENV FUSE_MOUNT=auto +EXPOSE 8080 + +ENTRYPOINT ["/usr/local/bin/computerd"] diff --git a/experiments/agent-changes/package.json b/experiments/agent-changes/package.json index 55173f6d7..ddb319f71 100644 --- a/experiments/agent-changes/package.json +++ b/experiments/agent-changes/package.json @@ -11,7 +11,8 @@ "build:types": "wrangler types" }, "dependencies": { - "@cloudflare/computer": "0.4.1" + "@cloudflare/computer": "0.4.1", + "@earendil-works/pi-ai": "0.99.2" }, "devDependencies": { "@cloudflare/workers-types": "5.20261009.1", diff --git a/experiments/agent-changes/pnpm-lock.yaml b/experiments/agent-changes/pnpm-lock.yaml index 20987beb5..8a602d29d 100644 --- a/experiments/agent-changes/pnpm-lock.yaml +++ b/experiments/agent-changes/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@cloudflare/computer': specifier: 0.4.1 version: 0.4.1(@cloudflare/workers-types@5.20261009.1)(supports-color@10.2.2) + '@earendil-works/pi-ai': + specifier: 0.99.2 + version: 0.99.2(@aws-sdk/credential-provider-node@3.972.84)(@smithy/signature-v4@5.7.4)(supports-color@10.2.2)(undici@7.29.1)(ws@8.21.0) devDependencies: '@cloudflare/workers-types': specifier: 5.20261009.1 @@ -30,6 +33,99 @@ importers: packages: + '@anthropic-ai/sdk@0.124.0': + resolution: {integrity: sha512-cN5O8i9UVxHeOQAzj/XjshWXG8KiibJDw9OGpH2Z/eR3n/RBxdoLxDJOcfqAJWvjaMDFfHTBADU04hWRJVkDyA==} + hasBin: true + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + + '@aws-sdk/client-bedrock-runtime@3.1127.0': + resolution: {integrity: sha512-IDl/lrPb90aH+pZFHGNDmgH9nAUQj5PlZH1sJ3w7RikctyjHSnY3oNjZhrLoaBoQn/rNK0zsP6OHEqEhj2tdLA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/core@3.978.1': + resolution: {integrity: sha512-LbY9aGsEiznDWmUc30Nwv3aIX/+dbwTx8KfS0yOC3NPYMO+O91e6jkT1azf34FwjOndq8/Q+RcVVZz5xnerwdg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-env@3.972.72': + resolution: {integrity: sha512-xTKO/FWJPozTIXbozVnVGoNBhaGba8TBcx+KyUjRVeOlXE+dUc7GTR1cLvu0uTdIdmemzaFbqqCshXeZA1fZew==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-http@3.972.74': + resolution: {integrity: sha512-u91E/hT8f4d1xy0Jl7VG4nVKJ3lxbrZkoBTeSVoJdWBiSEUMwMS/9+e0H/aJVQV//Lt5wuzP+E69v4aRSsNTmw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-ini@3.973.17': + resolution: {integrity: sha512-ged4KXdBkvIC81bLvNHHuQKdKak/VXhQTR1NWYTTqW0474nlmsxy9O/vlgTIohDDWH3xpBdtVMZRyjb+DnocDA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-login@3.972.79': + resolution: {integrity: sha512-L+Z85anONJd8MaiuraO4wRxATCdEejBZ3K3eymzWI5JPXa9sOS9CkIm72PBKqXKX+Z9p9NGMX5AIMXm0LEflgw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-node@3.972.84': + resolution: {integrity: sha512-oHt854odINVwzwsh+c5x69j0ajm4DbqqqVJ+O1ECsCIZeMDAbzFpXItaqP7UZstJj/ATdTk/KFSH0LaNAgV+kA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-process@3.972.72': + resolution: {integrity: sha512-rLIp2xbMjX/k9/od7APpqq1ZgXXnV0pOL1Th3ZsL8Wu0TRtBsDTVS8iPqcfRFcHakFxPvR04OSTv2ka2qOb/2A==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-sso@3.973.16': + resolution: {integrity: sha512-IGihaJfFZYacJJr/odqILCoK7W/mvrZ7cuK7ECn3sAu4vLC6u0V8bS7mCGbdugJ8Aum2tnvqmx0F2MRFp2rn9g==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.972.78': + resolution: {integrity: sha512-/y9WvNtlcPBGLR0qc1a+9J/xtYZfVczvLUOuXaVWylzttH7ewsxwHtjmiJSolNrVSDorIxHGHMU61CbonRkmwA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/eventstream-handler-node@3.972.35': + resolution: {integrity: sha512-a8xilRoRaalvSPZdfrs0VY3/BPc0uYhXW56Z/k6nmZ5Vk430LHeowf9APIPq8utM3tMJSNGSSuJMlB9YrPsN+A==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-eventstream@3.972.30': + resolution: {integrity: sha512-B6gvZlcnRBNWraKgyEjKsbhv+VjtbyHmpU7hmtTHzXpDSxHPpCJnYLpglEOOsF+SFne20DbZC5IVC1aNr2Pb4A==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-websocket@3.972.54': + resolution: {integrity: sha512-bhESdru8u8KosziH8jcVta/NM/dNreeRz2+2aU86si5bfBYOiJ6IiqD+9U4URUcU5WJO3Yw+jO3GLDIHlscXMQ==} + engines: {node: '>= 14.0.0'} + + '@aws-sdk/nested-clients@3.997.46': + resolution: {integrity: sha512-oRxtBcka/JGHGs9l9p9IVajGoTP8vTPmoAzdHGy4Qcy9P5vPnDf6nhIeM/COQNY9k/OahImTRaLkHftoXvfcmQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.996.47': + resolution: {integrity: sha512-Zk08macMvQTHzQJCLJVkOlviVoqwYMrpXv4lmLN7b7sAbiMoOK7Go0NYdR5UeF+MW8LIbRmwrNy9u/5VvX1U5g==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1127.0': + resolution: {integrity: sha512-Dv2TMWBshJ+tF6ahs2Sy5bh4Iabsd4GAQqVvE9XZmYmnoaVbpS2QKIKE/HRacc7bTtbjEEvP+laGzHvHlf1CiQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1138.0': + resolution: {integrity: sha512-GpyAr0DD63YOEmYFM6Df+gJuIgC92MMTiBK4FTKfxii5MJ9ge20epR7LyroulscYlG89J+ZB2ivFDPjvfQhzdw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/types@3.974.6': + resolution: {integrity: sha512-v/clNZzZnDxGyvpHMOGpJKVXFAExJzUNAAjaWGdcx8QAcXLGwTaOkw33p5SHAi0YAioK32xB3hWwOekRVfmfKg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/xml-builder@3.972.41': + resolution: {integrity: sha512-ctjVSyCMegrWfXlx6VqzSBFI6UqmQ5ZlnfMhdLIiWmhoH8UAQxSCP5N3OpG7X3k4LnS7ou74C4mt20+bfTW2aQ==} + engines: {node: '>=20.0.0'} + + '@aws/lambda-invoke-store@0.3.0': + resolution: {integrity: sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==} + engines: {node: '>=18.0.0'} + + '@babel/runtime@7.29.10': + resolution: {integrity: sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==} + engines: {node: '>=6.9.0'} + '@borewit/text-codec@0.2.2': resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} @@ -100,6 +196,15 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@earendil-works/pi-ai@0.99.2': + resolution: {integrity: sha512-9RFOEdY+ZTJ1AI+UuAFs4RM0tF2Tje/R/CEv9gWTJHt0iTu8XHZs64U/EIZxNSllFmec/4HfwsOxYj1qQek9bg==} + engines: {node: '>=22.19.0'} + hasBin: true + + '@earendil-works/pi-telemetry@0.99.2': + resolution: {integrity: sha512-WThYU4XM6jjjzH4FzLdreN7QAPS9SDdokL0W0Ldheg1ssCIJkfpK7PgebFm7/PoQub7OiXx+SRF6B/oF7z7lXA==} + engines: {node: '>=22.19.0'} + '@emnapi/runtime@1.11.3': resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} @@ -415,6 +520,15 @@ packages: cpu: [x64] os: [win32] + '@google/genai@2.21.0': + resolution: {integrity: sha512-+PDtco2/Z0ONdzCGekCoCT+O1VJS9xJQNN4XzQpXG/t3El/SWWMkCWlFRO1KmivOHPa4Q0VjUYu1HBKCZ/v33Q==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.25.2 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + '@img/colour@1.1.0': resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} engines: {node: '>=18'} @@ -606,13 +720,67 @@ packages: '@poppinss/exception@1.2.3': resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} + + '@protobufjs/eventemitter@1.1.1': + resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==} + + '@protobufjs/fetch@1.1.1': + resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.2': + resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} + '@sindresorhus/is@7.2.0': resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} engines: {node: '>=18'} + '@smithy/core@3.35.1': + resolution: {integrity: sha512-i4YPS4B6ts7bjn7UwLnGjiZdprOvHvgGobFZsYK3GIY3E5hIqtj0rReU69BcTpGp+fvtraSNXeG1l+jtJvF55w==} + engines: {node: '>=18.0.0'} + + '@smithy/credential-provider-imds@4.5.2': + resolution: {integrity: sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg==} + engines: {node: '>=18.0.0'} + + '@smithy/fetch-http-handler@5.8.0': + resolution: {integrity: sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA==} + engines: {node: '>=18.0.0'} + + '@smithy/node-http-handler@4.12.1': + resolution: {integrity: sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.7.4': + resolution: {integrity: sha512-tHy0K0VtqNd5Y7Y41h0a0Lhh0L1GzC08dTWg0F7vRJWFtTENg7IZikf3wQkanYIRdb7ngoIPMTmqgUi401fEeQ==} + engines: {node: '>=18.0.0'} + + '@smithy/types@4.19.0': + resolution: {integrity: sha512-r7jh49VJxGerfAcTQA6gXcKc+98zOp/tqRwzYjgOE+iSQsP6cEU1hq2QzbuipmP68QtYdY9wKEhiCQZIzHgZ4Q==} + engines: {node: '>=18.0.0'} + '@speed-highlight/core@1.2.24': resolution: {integrity: sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==} + '@stablelib/base64@1.0.1': + resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} + '@tokenizer/inflate@0.4.1': resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} engines: {node: '>=18'} @@ -623,23 +791,43 @@ packages: '@types/node@26.6.4': resolution: {integrity: sha512-ldVPDCzj7fsaGZrLB0NuHuTvJcsNasysBAqMolr/cgxrLd1xbqxIr3XJiPnHHJUCxj5sNF1vnRj9aWnrVh5Jcg==} + '@types/retry@0.12.0': + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + acorn@8.19.0: resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} engines: {node: '>=0.4.0'} hasBin: true + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + agent-base@9.0.0: + resolution: {integrity: sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==} + engines: {node: '>= 20'} + anynum@1.0.1: resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + bowser@2.14.1: + resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} @@ -657,6 +845,10 @@ packages: resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -682,6 +874,9 @@ packages: resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} engines: {node: '>=0.3.1'} + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -702,6 +897,12 @@ packages: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-sha256@1.3.0: + resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} + fast-xml-builder@1.3.1: resolution: {integrity: sha512-pIM/1n3ntFXKYrUZwW7QCK0gAW7XY+wzj1YMIV3tLDvPj/V+zTGJK5e3/4WJfwj0qWw2ElNXiTixda/R+3YSug==} @@ -709,10 +910,18 @@ packages: resolution: {integrity: sha512-R9iDuNrQYeQut46cn2r2wHKn4HYzVDvDm5J1wW+koZewykv0yuO2HChTYeZtrULyHIDM9cj9TUXloCsueCQUog==} hasBin: true + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + file-type@21.3.4: resolution: {integrity: sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==} engines: {node: '>=20'} + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -721,13 +930,41 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + gaxios@7.3.1: + resolution: {integrity: sha512-kB3rzJV7d9juLZh8/56QTXCwQfxyhdOMdyYk1HdQKFtF8TJTDTZQJtixWIwXdE9Jji91mC41DUNpjleo4L4eAQ==} + engines: {node: '>=18'} + + gcp-metadata@8.1.2: + resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} + engines: {node: '>=18'} + github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + google-auth-library@10.9.1: + resolution: {integrity: sha512-i1ydyHrqcIxXkWh/uBmVkzCvIuq5yiK2ATndIe5XxKholrG/MTYP9xGYka4sQhrbIAgGjL2B6NOE7rFaiF3fXw==} + engines: {node: '>=18'} + + google-logging-utils@1.1.3: + resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} + engines: {node: '>=14'} + guarded-fetch@0.1.3: resolution: {integrity: sha512-PSaNyJk8VJlUVEhMHPXT/Z/WgNrLBh43WaYQJiu1qvyCuPQA+kgFMNmAOxI3GU3uXrCkO/xRW11XjcswrksYOA==} engines: {node: '>=20.19'} + http-proxy-agent@9.1.0: + resolution: {integrity: sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig==} + engines: {node: '>= 20'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + https-proxy-agent@9.1.0: + resolution: {integrity: sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==} + engines: {node: '>= 20'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -748,15 +985,31 @@ packages: is-unsafe@2.0.2: resolution: {integrity: sha512-HgbIHPBH0KHHCcjLfGsCvhtPTVxjaAZlXjwdz7/GQC40SjSe4sfQsar8J5VFo8JOSbarkpV0OLG95bbaNd9aAQ==} + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + + json-schema-to-ts@3.1.1: + resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} + engines: {node: '>=16'} + just-bash@3.6.0: resolution: {integrity: sha512-2COjEgcHdqKXeQSiNfPAHmpwQx4S8wATaIwog83g2t645U5tom6FED4CBBdr3M+0ioX4xZ26eODw3/nD6RQ6xw==} engines: {node: '>=20.19'} hasBin: true + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + kleur@4.1.5: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -789,6 +1042,15 @@ packages: resolution: {integrity: sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==} engines: {node: ^18 || ^20 || >= 21} + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-gyp-build@4.8.4: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true @@ -801,9 +1063,40 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + openai@7.19.0: + resolution: {integrity: sha512-MX2s3u2L5racTO0CC/SWpCOasJQBCJrqLKXK+l82cAhdeF8mPMBEe/gxMm0ZFa2xpKpOFLRjxv5afYEZbBXmbQ==} + engines: {node: '>=22.0.0'} + peerDependencies: + '@aws-sdk/credential-provider-node': '>=3.972.0 <4' + '@smithy/hash-node': '>=4.3.0 <5' + '@smithy/signature-v4': '>=5.4.0 <6' + undici: '>=5 <9' + ws: ^8.21.0 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@aws-sdk/credential-provider-node': + optional: true + '@smithy/hash-node': + optional: true + '@smithy/signature-v4': + optional: true + undici: + optional: true + ws: + optional: true + zod: + optional: true + + p-retry@4.6.2: + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} + engines: {node: '>=8'} + papaparse@5.7.0: resolution: {integrity: sha512-qBGxg/7Q3Kl9Wfhrz2Z74UnvnHTXLNG6jmKJFeBvP2+y4lV7So+7SR62+Zd47JvdrCkX+nDcnr0ObPzek/+6RA==} + partial-json@0.1.7: + resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==} + path-expression-matcher@1.6.2: resolution: {integrity: sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==} engines: {node: '>=14.0.0'} @@ -820,6 +1113,19 @@ packages: deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. hasBin: true + protobufjs@7.6.6: + resolution: {integrity: sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==} + engines: {node: '>=12.0.0'} + + proxy-agent-negotiate@1.1.0: + resolution: {integrity: sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ==} + engines: {node: '>= 20'} + peerDependencies: + kerberos: ^2.0.0 + peerDependenciesMeta: + kerberos: + optional: true + pump@3.0.4: resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} @@ -834,6 +1140,10 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + run@2.1.3: resolution: {integrity: sha512-KUurW05zgjtZ2su0cBURC1q2RG/Uq0uzV3qURDsXqiKh03p9IXABQK4Qem56cFMqjT8TdQ2iTWsePrMprQWIRA==} engines: {node: '>=20.19.0'} @@ -880,6 +1190,9 @@ packages: sql.js@1.14.2: resolution: {integrity: sha512-3ZGPovObMFrdw79zrUHbfdE/DLIsy8jdNdssmMSQuRAymedU6q84asPt0kgiqrdMYlPegDItiIMfmIXzZnYFcw==} + standardwebhooks@1.1.1: + resolution: {integrity: sha512-bCbX9ZEyFkWPsRz7Bl3NuQUJohmwGSev/yhr7vhaGPlc4AfIrspIRa6cPTBuI1ItmrTDJ4d/S2hCsfe4+vQGnQ==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -909,6 +1222,9 @@ packages: resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} engines: {node: '>=14.16'} + ts-algebra@2.0.0: + resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -924,6 +1240,9 @@ packages: resolution: {integrity: sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==} engines: {node: '>=18', npm: '>=9'} + typebox@1.3.27: + resolution: {integrity: sha512-zu+jc1pcy4UiNThxikUr36f0Rybk9PEeCg/NE6adeWr/SKsdNO4EzZHYRDlv2YCVAfj3Odq3dESSo/jNyoBXzA==} + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -955,6 +1274,10 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + workerd@1.20261006.1: resolution: {integrity: sha512-8MadBuffZ5NdpLwZjUmsqT5QlaKXq4gjgT6wzcKeynZTICNXyePhc+5QVoKiK7+MMhFTLNrRO2KXLlpk8Q6BkA==} engines: {node: '>=16'} @@ -1002,6 +1325,195 @@ packages: snapshots: + '@anthropic-ai/sdk@0.124.0': + dependencies: + json-schema-to-ts: 3.1.1 + standardwebhooks: 1.1.1 + + '@aws-sdk/client-bedrock-runtime@3.1127.0': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/credential-provider-node': 3.972.84 + '@aws-sdk/eventstream-handler-node': 3.972.35 + '@aws-sdk/middleware-eventstream': 3.972.30 + '@aws-sdk/middleware-websocket': 3.972.54 + '@aws-sdk/token-providers': 3.1127.0 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/fetch-http-handler': 5.8.0 + '@smithy/node-http-handler': 4.12.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/core@3.978.1': + dependencies: + '@aws-sdk/types': 3.974.6 + '@aws-sdk/xml-builder': 3.972.41 + '@aws/lambda-invoke-store': 0.3.0 + '@smithy/core': 3.35.1 + '@smithy/signature-v4': 5.7.4 + '@smithy/types': 4.19.0 + bowser: 2.14.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-env@3.972.72': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.972.74': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/fetch-http-handler': 5.8.0 + '@smithy/node-http-handler': 4.12.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-ini@3.973.17': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/credential-provider-env': 3.972.72 + '@aws-sdk/credential-provider-http': 3.972.74 + '@aws-sdk/credential-provider-login': 3.972.79 + '@aws-sdk/credential-provider-process': 3.972.72 + '@aws-sdk/credential-provider-sso': 3.973.16 + '@aws-sdk/credential-provider-web-identity': 3.972.78 + '@aws-sdk/nested-clients': 3.997.46 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/credential-provider-imds': 4.5.2 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-login@3.972.79': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/nested-clients': 3.997.46 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-node@3.972.84': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.72 + '@aws-sdk/credential-provider-http': 3.972.74 + '@aws-sdk/credential-provider-ini': 3.973.17 + '@aws-sdk/credential-provider-process': 3.972.72 + '@aws-sdk/credential-provider-sso': 3.973.16 + '@aws-sdk/credential-provider-web-identity': 3.972.78 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/credential-provider-imds': 4.5.2 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-process@3.972.72': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.973.16': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/nested-clients': 3.997.46 + '@aws-sdk/token-providers': 3.1138.0 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-web-identity@3.972.78': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/nested-clients': 3.997.46 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/eventstream-handler-node@3.972.35': + dependencies: + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-eventstream@3.972.30': + dependencies: + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-websocket@3.972.54': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/fetch-http-handler': 5.8.0 + '@smithy/signature-v4': 5.7.4 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.997.46': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/signature-v4-multi-region': 3.996.47 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/fetch-http-handler': 5.8.0 + '@smithy/node-http-handler': 4.12.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/signature-v4-multi-region@3.996.47': + dependencies: + '@aws-sdk/types': 3.974.6 + '@smithy/signature-v4': 5.7.4 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1127.0': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/nested-clients': 3.997.46 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1138.0': + dependencies: + '@aws-sdk/core': 3.978.1 + '@aws-sdk/nested-clients': 3.997.46 + '@aws-sdk/types': 3.974.6 + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/types@3.974.6': + dependencies: + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.972.41': + dependencies: + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@aws/lambda-invoke-store@0.3.0': {} + + '@babel/runtime@7.29.10': {} + '@borewit/text-codec@0.2.2': {} '@cloudflare/computer@0.4.1(@cloudflare/workers-types@5.20261009.1)(supports-color@10.2.2)': @@ -1043,6 +1555,33 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@earendil-works/pi-ai@0.99.2(@aws-sdk/credential-provider-node@3.972.84)(@smithy/signature-v4@5.7.4)(supports-color@10.2.2)(undici@7.29.1)(ws@8.21.0)': + dependencies: + '@anthropic-ai/sdk': 0.124.0 + '@aws-sdk/client-bedrock-runtime': 3.1127.0 + '@earendil-works/pi-telemetry': 0.99.2 + '@google/genai': 2.21.0(supports-color@10.2.2) + '@smithy/node-http-handler': 4.12.1 + http-proxy-agent: 9.1.0(supports-color@10.2.2) + https-proxy-agent: 9.1.0(supports-color@10.2.2) + openai: 7.19.0(@aws-sdk/credential-provider-node@3.972.84)(@smithy/signature-v4@5.7.4)(undici@7.29.1)(ws@8.21.0) + partial-json: 0.1.7 + typebox: 1.3.27 + transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' + - '@modelcontextprotocol/sdk' + - '@smithy/hash-node' + - '@smithy/signature-v4' + - bufferutil + - kerberos + - supports-color + - undici + - utf-8-validate + - ws + - zod + + '@earendil-works/pi-telemetry@0.99.2': {} + '@emnapi/runtime@1.11.3': dependencies: tslib: 2.8.1 @@ -1204,6 +1743,17 @@ snapshots: '@esbuild/win32-x64@0.28.2': optional: true + '@google/genai@2.21.0(supports-color@10.2.2)': + dependencies: + google-auth-library: 10.9.1(supports-color@10.2.2) + p-retry: 4.6.2 + protobufjs: 7.6.6 + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + '@img/colour@1.1.0': {} '@img/sharp-darwin-arm64@0.35.4': @@ -1341,10 +1891,65 @@ snapshots: '@poppinss/exception@1.2.3': {} + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.5': {} + + '@protobufjs/eventemitter@1.1.1': {} + + '@protobufjs/fetch@1.1.1': + dependencies: + '@protobufjs/aspromise': 1.1.2 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.2': {} + '@sindresorhus/is@7.2.0': {} + '@smithy/core@3.35.1': + dependencies: + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.5.2': + dependencies: + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@smithy/fetch-http-handler@5.8.0': + dependencies: + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@smithy/node-http-handler@4.12.1': + dependencies: + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@smithy/signature-v4@5.7.4': + dependencies: + '@smithy/core': 3.35.1 + '@smithy/types': 4.19.0 + tslib: 2.8.1 + + '@smithy/types@4.19.0': + dependencies: + tslib: 2.8.1 + '@speed-highlight/core@1.2.24': {} + '@stablelib/base64@1.0.1': {} + '@tokenizer/inflate@0.4.1(supports-color@10.2.2)': dependencies: debug: 4.4.3(supports-color@10.2.2) @@ -1358,12 +1963,19 @@ snapshots: dependencies: undici-types: 8.9.0 + '@types/retry@0.12.0': {} + acorn@8.19.0: {} + agent-base@7.1.4: {} + + agent-base@9.0.0: {} + anynum@1.0.1: {} - base64-js@1.5.1: - optional: true + base64-js@1.5.1: {} + + bignumber.js@9.3.1: {} bl@4.1.0: dependencies: @@ -1374,6 +1986,10 @@ snapshots: blake3-wasm@2.1.5: {} + bowser@2.14.1: {} + + buffer-equal-constant-time@1.0.1: {} + buffer@5.7.1: dependencies: base64-js: 1.5.1 @@ -1389,6 +2005,8 @@ snapshots: cookie@1.1.1: {} + data-uri-to-buffer@4.0.1: {} + debug@4.4.3(supports-color@10.2.2): dependencies: ms: 2.1.3 @@ -1407,6 +2025,10 @@ snapshots: diff@8.0.4: {} + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + end-of-stream@1.4.5: dependencies: once: 1.4.0 @@ -1475,6 +2097,10 @@ snapshots: expand-template@2.0.3: optional: true + extend@3.0.2: {} + + fast-sha256@1.3.0: {} + fast-xml-builder@1.3.1: dependencies: path-expression-matcher: 1.6.2 @@ -1489,6 +2115,11 @@ snapshots: strnum: 2.4.2 xml-naming: 0.3.0 + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + file-type@21.3.4(supports-color@10.2.2): dependencies: '@tokenizer/inflate': 0.4.1(supports-color@10.2.2) @@ -1498,20 +2129,78 @@ snapshots: transitivePeerDependencies: - supports-color + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + fs-constants@1.0.0: optional: true fsevents@2.3.3: optional: true + gaxios@7.3.1(supports-color@10.2.2): + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6(supports-color@10.2.2) + node-fetch: 3.3.2 + transitivePeerDependencies: + - supports-color + + gcp-metadata@8.1.2(supports-color@10.2.2): + dependencies: + gaxios: 7.3.1(supports-color@10.2.2) + google-logging-utils: 1.1.3 + json-bigint: 1.0.0 + transitivePeerDependencies: + - supports-color + github-from-package@0.0.0: optional: true + google-auth-library@10.9.1(supports-color@10.2.2): + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 7.3.1(supports-color@10.2.2) + gcp-metadata: 8.1.2(supports-color@10.2.2) + google-logging-utils: 1.1.3 + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + + google-logging-utils@1.1.3: {} + guarded-fetch@0.1.3: dependencies: ipaddr.js: 2.2.0 undici: 7.29.0 + http-proxy-agent@9.1.0(supports-color@10.2.2): + dependencies: + agent-base: 9.0.0 + debug: 4.4.3(supports-color@10.2.2) + proxy-agent-negotiate: 1.1.0 + transitivePeerDependencies: + - kerberos + - supports-color + + https-proxy-agent@7.0.6(supports-color@10.2.2): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + https-proxy-agent@9.1.0(supports-color@10.2.2): + dependencies: + agent-base: 9.0.0 + debug: 4.4.3(supports-color@10.2.2) + proxy-agent-negotiate: 1.1.0 + transitivePeerDependencies: + - kerberos + - supports-color + ieee754@1.2.1: {} inherits@2.0.4: @@ -1526,6 +2215,15 @@ snapshots: is-unsafe@2.0.2: {} + json-bigint@1.0.0: + dependencies: + bignumber.js: 9.3.1 + + json-schema-to-ts@3.1.1: + dependencies: + '@babel/runtime': 7.29.10 + ts-algebra: 2.0.0 + just-bash@3.6.0(supports-color@10.2.2): dependencies: diff: 8.0.4 @@ -1550,8 +2248,21 @@ snapshots: transitivePeerDependencies: - supports-color + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + kleur@4.1.5: {} + long@5.3.2: {} + mimic-response@3.1.0: optional: true @@ -1589,6 +2300,14 @@ snapshots: node-addon-api@8.9.2: optional: true + node-domexception@1.0.0: {} + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-gyp-build@4.8.4: optional: true @@ -1603,8 +2322,22 @@ snapshots: wrappy: 1.0.2 optional: true + openai@7.19.0(@aws-sdk/credential-provider-node@3.972.84)(@smithy/signature-v4@5.7.4)(undici@7.29.1)(ws@8.21.0): + optionalDependencies: + '@aws-sdk/credential-provider-node': 3.972.84 + '@smithy/signature-v4': 5.7.4 + undici: 7.29.1 + ws: 8.21.0 + + p-retry@4.6.2: + dependencies: + '@types/retry': 0.12.0 + retry: 0.13.1 + papaparse@5.7.0: {} + partial-json@0.1.7: {} + path-expression-matcher@1.6.2: {} path-to-regexp@6.3.0: {} @@ -1627,6 +2360,22 @@ snapshots: tunnel-agent: 0.6.0 optional: true + protobufjs@7.6.6: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.5 + '@protobufjs/eventemitter': 1.1.1 + '@protobufjs/fetch': 1.1.1 + '@protobufjs/float': 1.0.2 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.2 + '@types/node': 26.6.4 + long: 5.3.2 + + proxy-agent-negotiate@1.1.0: {} + pump@3.0.4: dependencies: end-of-stream: 1.4.5 @@ -1650,12 +2399,13 @@ snapshots: util-deprecate: 1.0.2 optional: true + retry@0.13.1: {} + run@2.1.3(typescript@5.9.3): optionalDependencies: typescript: 5.9.3 - safe-buffer@5.2.1: - optional: true + safe-buffer@5.2.1: {} seek-bzip@2.0.0: dependencies: @@ -1712,6 +2462,11 @@ snapshots: sql.js@1.14.2: {} + standardwebhooks@1.1.1: + dependencies: + '@stablelib/base64': 1.0.1 + fast-sha256: 1.3.0 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -1753,8 +2508,9 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 - tslib@2.8.1: - optional: true + ts-algebra@2.0.0: {} + + tslib@2.8.1: {} tsx@4.23.15: dependencies: @@ -1771,6 +2527,8 @@ snapshots: dependencies: '@mixmark-io/domino': 2.2.0 + typebox@1.3.27: {} + typescript@5.9.3: {} typescript@6.0.3: {} @@ -1790,6 +2548,8 @@ snapshots: util-deprecate@1.0.2: optional: true + web-streams-polyfill@3.3.3: {} + workerd@1.20261006.1: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20261006.1 diff --git a/experiments/agent-changes/src/task-agent.ts b/experiments/agent-changes/src/task-agent.ts new file mode 100644 index 000000000..078e153cb --- /dev/null +++ b/experiments/agent-changes/src/task-agent.ts @@ -0,0 +1,135 @@ +import { DurableObject } from "cloudflare:workers"; +import { Workspace, WorkspaceProxy, WorkspaceServiceProxy, sh, type WorkspaceStub } from "@cloudflare/computer"; +import { ContainerBackend, withWorkspaceContainer } from "@cloudflare/computer/backends/container"; +import { WorkerShellBackend } from "@cloudflare/computer/backends/worker-shell"; +import { createPiTools } from "@cloudflare/computer/tools/pi-ai"; +import { createModels, type Message } from "@earendil-works/pi-ai"; +import { WORKERS_AI_PROVIDER, workersAI } from "./workers-ai.js"; + +export { WorkspaceProxy, WorkspaceServiceProxy }; + +const MODEL = "@cf/meta/llama-3.3-70b-instruct-fp8-fast"; +const PROJECT_DIR = "/workspace/repo"; + +export interface AgentInput { + id: string; + projectId: string; + prompt: string; + forkRemote: string; + token: string; + branch: string; +} + +class AgentBase extends DurableObject {} + +/** Each agent owns its own DO-backed filesystem; Linux compute is replaceable. */ +export class TaskAgent extends withWorkspaceContainer(AgentBase) { + readonly #container = new ContainerBackend({ + id: "container", + container: () => this, + workspace: { binding: "RUNS", id: this.ctx.id.toString() }, + egress: { mode: "direct" }, + instance: "standard-2", + }); + + readonly workspace = new Workspace({ + storage: this.ctx.storage as unknown as ConstructorParameters[0]["storage"], + backends: [ + new WorkerShellBackend({ + id: "shell", loader: this.env.LOADER, + workspace: { binding: "RUNS", id: this.ctx.id.toString() }, ctx: this.ctx, + }), + this.#container, + ], + }); + + override async fetch(request: Request): Promise { + if (new URL(request.url).pathname === "/api") return this.#container.handleFetch(request); + return new Response("Not found", { status: 404 }); + } + + async __getWorkspaceStub(): Promise { + await this.workspace.ready(); + return this.workspace.stub(); + } + + async start(input: AgentInput): Promise { + if (await this.ctx.storage.get("started")) throw new Error("Agent already started"); + await this.ctx.storage.put("started", true); + this.ctx.waitUntil(this.execute(input)); + } + + /** Never expose command output from invocations carrying a Git credential. */ + private async git(command: string): Promise { + const execution = await this.workspace.runtime.exec(command, { backend: "shell", encoding: "utf8" }); + try { + const result = await execution.result(); + if (result.exitCode !== 0) throw new Error("Git operation failed"); + return result.stdout.trim(); + } finally { + execution[Symbol.dispose]?.(); + } + } + + private async execute(input: AgentInput): Promise { + const coordinator = this.env.PROJECTS.get(this.env.PROJECTS.idFromName(input.projectId)); + try { + await coordinator.updateTask(input.id, { status: "running" }); + const authorization = `http.extraHeader=Authorization: Bearer ${input.token}`; + await this.git(sh`git -c ${authorization} clone ${input.forkRemote} ${PROJECT_DIR}`); + + const { tools, execute } = createPiTools({ workspace: this.workspace }); + const models = createModels(); + models.setProvider(workersAI(this.env.AI, MODEL)); + const model = models.getModel(WORKERS_AI_PROVIDER, MODEL); + if (!model) throw new Error("Model unavailable"); + + const messages: Message[] = [{ role: "user", content: input.prompt, timestamp: Date.now() }]; + let response = ""; + for (let turn = 0; turn < 8; turn++) { + const reply = await models.complete(model, { + systemPrompt: [ + `You are a coding agent working on a repository at ${PROJECT_DIR}.`, + "Implement the requested change and verify it using the provided tools.", + "Use shell for Git and searches, container for native Linux commands and tests.", + "Keep all edits under /workspace/repo. Do not commit, push, or change remotes.", + "Never seek or expose credentials.", + ].join("\n"), + messages, tools, + }); + messages.push(reply); + const calls = reply.content.filter((part) => part.type === "toolCall"); + if (!calls.length) { + response = reply.content.filter((part) => part.type === "text").map((part) => part.text).join(""); + break; + } + for (const call of calls) { + const result = await execute(call); + messages.push({ + role: "toolResult", toolCallId: call.id, toolName: call.name, + content: result.content, isError: result.isError, timestamp: Date.now(), + }); + } + } + + await this.git(sh`git -C ${PROJECT_DIR} add -A`); + const status = await this.workspace.runtime.exec(sh`git -C ${PROJECT_DIR} diff --cached --quiet`, { backend: "shell" }); + const exitCode = (await status.result()).exitCode; + status[Symbol.dispose]?.(); + if (exitCode !== 1) throw new Error(exitCode === 0 ? "Agent did not change files" : "Unable to inspect changes"); + await this.git(sh`git -C ${PROJECT_DIR} -c ${"user.name=DevSpace Agent"} -c ${"user.email=agent@devspace.invalid"} commit -m ${`Agent proposal ${input.id}`}`); + const headCommit = await this.git(sh`git -C ${PROJECT_DIR} rev-parse HEAD`); + await this.git(sh`git -C ${PROJECT_DIR} -c ${authorization} push origin ${`HEAD:${input.branch}`}`); + await coordinator.updateTask(input.id, { + status: "completed", headCommit, result: response.slice(0, 4000), + }); + } catch (error) { + await coordinator.updateTask(input.id, { + status: "failed", + // Avoid returning raw provider and shell errors: some may contain repo credentials. + error: error instanceof Error && ["Git operation failed", "Agent did not change files", "Model unavailable", "Unable to inspect changes"].includes(error.message) + ? error.message : "Agent execution failed; inspect Cloudflare logs", + }); + } + } +} diff --git a/experiments/agent-changes/src/worker.ts b/experiments/agent-changes/src/worker.ts index 7f2d2c29b..3e6e83cca 100644 --- a/experiments/agent-changes/src/worker.ts +++ b/experiments/agent-changes/src/worker.ts @@ -1,7 +1,8 @@ import { ProjectCoordinator } from "./project.js"; -import { publicGitUrl, repoName, type Project } from "./domain.js"; +import { publicGitUrl, repoName, requirePrompt, type Project, type Task } from "./domain.js"; +import { TaskAgent, WorkspaceProxy, WorkspaceServiceProxy } from "./task-agent.js"; -export { ProjectCoordinator }; +export { ProjectCoordinator, TaskAgent, WorkspaceProxy, WorkspaceServiceProxy }; type AppEnv = Env & { DEMO_TOKEN: string }; type ProjectStub = DurableObjectStub; @@ -44,6 +45,42 @@ async function createProject(request: Request, env: AppEnv): Promise { return Response.json(project, { status: 201 }); } +async function compare(request: Request, env: AppEnv, projectId: string): Promise { + const stub = projectStub(env, projectId); + const project = await stub.load(); + if (!project) return jsonError("Project not found", 404); + if ((await stub.tasks()).length) return jsonError("V0 supports one comparison per project", 409); + + const body = (await request.json()) as { prompts?: unknown }; + if (!Array.isArray(body.prompts) || body.prompts.length !== 2) { + return jsonError("Provide exactly two prompts", 400); + } + const prompts = body.prompts.map(requirePrompt); + + using source = await env.ARTIFACTS.get(project.baseRepo); + const baseCommit = (await source.log({ ref: project.defaultBranch, limit: 1 }))[0]?.hash; + if (!baseCommit) return jsonError("Source repository has no initial commit", 409); + + const tasks: Task[] = []; + for (const prompt of prompts) { + const id = crypto.randomUUID().replaceAll("-", "").slice(0, 12); + const forkRepo = repoName(projectId, id); + const fork = await source.fork(forkRepo, { defaultBranchOnly: true }); + const task: Task = { + id, projectId, prompt, forkRepo, forkRemote: fork.remote, + baseCommit, status: "queued", + }; + await stub.addTask(task); + tasks.push(task); + // The initial token is passed internally to the run DO, never to the browser. + await env.RUNS.get(env.RUNS.idFromName(id)).start({ + id, projectId, prompt, forkRemote: fork.remote, + token: fork.token, branch: project.defaultBranch, + }); + } + return Response.json({ tasks }, { status: 202 }); +} + export default { async fetch(request: Request, env: AppEnv): Promise { const url = new URL(request.url); @@ -56,6 +93,10 @@ export default { const project = await projectStub(env, match[1]).load(); return project ? Response.json(project) : jsonError("Project not found", 404); } + const comparison = /^\/api\/projects\/([a-f0-9]{16})\/compare$/.exec(url.pathname); + if (comparison && request.method === "POST") return await compare(request, env, comparison[1]); + const tasks = /^\/api\/projects\/([a-f0-9]{16})\/tasks$/.exec(url.pathname); + if (tasks && request.method === "GET") return Response.json({ tasks: await projectStub(env, tasks[1]).tasks() }); return jsonError("Not found", 404); } catch (error) { return jsonError(error, error instanceof SyntaxError ? 400 : 502); diff --git a/experiments/agent-changes/src/workers-ai.ts b/experiments/agent-changes/src/workers-ai.ts new file mode 100644 index 000000000..793b11b0f --- /dev/null +++ b/experiments/agent-changes/src/workers-ai.ts @@ -0,0 +1,96 @@ +// pi's Workers AI provider, transported over the `AI` binding rather +// than the REST endpoint, so the example needs no API key. Only the +// transport differs from pi's own provider. +// +// Lifted from the pi harness example in cloudflare/agents. + +import { + type ApiStreamOptions, + createProvider, + type Model, + type ProviderStreams, +} from "@earendil-works/pi-ai"; +import { openAICompletionsApi } from "@earendil-works/pi-ai/api/openai-completions.lazy"; + +export const WORKERS_AI_PROVIDER = "cloudflare-workers-ai"; + +type RunBinding = { + run( + model: string, + input: Record, + options: { returnRawResponse: true; signal?: AbortSignal }, + ): Promise; +}; + +function bodyText(body: BodyInit | null | undefined): string { + if (typeof body === "string") return body; + if (body instanceof Uint8Array) return new TextDecoder().decode(body); + throw new TypeError("Workers AI pi requests require a JSON request body"); +} + +function model(id: string): Model<"openai-completions"> { + return { + id, + name: id, + api: "openai-completions", + provider: WORKERS_AI_PROVIDER, + // Never dialed: the fetch below answers every request through the + // binding instead. pi still wants a syntactically valid base URL. + baseUrl: "https://workers-ai.binding.invalid/v1", + reasoning: false, + input: ["text"], + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 128_000, + maxTokens: 16_384, + compat: { + supportsStore: false, + supportsDeveloperRole: false, + supportsReasoningEffort: false, + supportsStrictMode: false, + maxTokensField: "max_tokens", + }, + }; +} + +export function workersAI(binding: Ai, modelId: string) { + // SAFETY: Workers AI returns a Response when `returnRawResponse` is + // set. The public `Ai` overload cannot express that correlation. + const runBinding = binding as unknown as RunBinding; + + const fetch = async (_input: RequestInfo | URL, init?: RequestInit): Promise => { + const input = JSON.parse(bodyText(init?.body)) as Record; + const name = typeof input.model === "string" ? input.model : undefined; + if (!name) throw new TypeError("Workers AI pi request is missing its model"); + delete input.model; + return runBinding.run(name, input, { + returnRawResponse: true, + ...(init?.signal ? { signal: init.signal } : {}), + }); + }; + + const api = openAICompletionsApi(); + const streams: ProviderStreams = { + stream: (m, context, options) => + api.stream(m, context, { ...options, fetch } as ApiStreamOptions), + streamSimple: (m, context, options) => api.streamSimple(m, context, { ...options, fetch }), + }; + + return createProvider({ + id: WORKERS_AI_PROVIDER, + name: "Cloudflare Workers AI", + // The binding carries its own authorization, so there is no key to + // resolve. pi still requires every provider to declare auth. + auth: { + apiKey: { + name: "Workers AI binding", + check: async () => ({ type: "api_key" as const, source: "Workers AI binding" }), + resolve: async () => ({ + auth: { apiKey: "workers-ai-binding" }, + source: "Workers AI binding", + }), + }, + }, + models: [model(modelId)], + api: streams, + }); +} diff --git a/experiments/agent-changes/wrangler.jsonc b/experiments/agent-changes/wrangler.jsonc index 9c9e0cbdf..d601cf3d5 100644 --- a/experiments/agent-changes/wrangler.jsonc +++ b/experiments/agent-changes/wrangler.jsonc @@ -4,9 +4,16 @@ "main": "src/worker.ts", "compatibility_date": "2026-10-09", "compatibility_flags": ["nodejs_compat", "experimental"], + "ai": {"binding": "AI", "remote": true}, + "worker_loaders": [{"binding": "LOADER"}], + "containers": [{ + "class_name": "TaskAgent", + "scheduling_policy": "durable_object", + "images": { "app": { "dockerfile": "./Dockerfile" } } + }], "artifacts": [{"binding": "ARTIFACTS", "namespace": "devspace-agent-changes", "remote": true}], "durable_objects": { - "bindings": [{"name": "PROJECTS", "class_name": "ProjectCoordinator"}] + "bindings": [{"name": "PROJECTS", "class_name": "ProjectCoordinator"}, {"name": "RUNS", "class_name": "TaskAgent"}] }, - "migrations": [{"tag": "v1", "new_sqlite_classes": ["ProjectCoordinator"]}] + "migrations": [{"tag": "v1", "new_sqlite_classes": ["ProjectCoordinator"]}, {"tag": "v2", "new_sqlite_classes": ["TaskAgent"]}] }