From 0048909598c2b09f3d5ef21ac96f44175fe37050 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Tue, 11 Aug 2026 18:42:38 -0600 Subject: [PATCH 1/6] chore(deps): agent-eval 0.145.0 with the caller-owned model call Bump @tangle-network/agent-eval from 0.143.0 to 0.145.0. Add a pnpm override so agent-runtime 0.126.0 cannot ghost a second eval version into the tree; pnpm resolves one version. agent-eval 0.144.0 removed apiKey and baseUrl from the DSPy RLM engine: the caller now owns each model call and returns a typed result, a cost receipt, and execution evidence. The CLI implements that call with agent-eval's own callLlm and receipt converters, and logs every execution observation to the analyst stderr log. --- package.json | 7 +- pnpm-lock.yaml | 357 ++++++++++++++++++++++++++++++++++++++++++++----- src/cli.ts | 59 ++++++-- 3 files changed, 377 insertions(+), 46 deletions(-) diff --git a/package.json b/package.json index e53e312..04437f7 100644 --- a/package.json +++ b/package.json @@ -59,11 +59,16 @@ "prepublishOnly": "pnpm check:source && pnpm build && pnpm check:package" }, "dependencies": { - "@tangle-network/agent-eval": "0.143.0", + "@tangle-network/agent-eval": "0.145.0", "@tangle-network/agent-runtime": "0.126.0", "@tangle-network/agent-trace-contract": "^1.0.2", "@tangle-network/sandbox": "0.17.2" }, + "pnpm": { + "overrides": { + "@tangle-network/agent-eval": "0.145.0" + } + }, "devDependencies": { "@types/node": "^22.0.0", "postcss": "^8.5.25", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 941c1d0..f4a2634 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,20 +5,18 @@ settings: excludeLinksFromLockfile: false overrides: - esbuild: ^0.28.1 - vite: ^8.1.2 - ws: ^8.21.0 + '@tangle-network/agent-eval': 0.145.0 importers: .: dependencies: '@tangle-network/agent-eval': - specifier: 0.143.0 - version: 0.143.0 + specifier: 0.145.0 + version: 0.145.0 '@tangle-network/agent-runtime': specifier: 0.126.0 - version: 0.126.0(@tangle-network/agent-eval@0.143.0)(@tangle-network/agent-interface@0.43.0)(@tangle-network/sandbox@0.17.2) + version: 0.126.0(@tangle-network/agent-eval@0.145.0)(@tangle-network/agent-interface@0.46.1)(@tangle-network/sandbox@0.17.2) '@tangle-network/agent-trace-contract': specifier: ^1.0.2 version: 1.0.2 @@ -42,11 +40,11 @@ importers: specifier: ^5.7.0 version: 5.9.3 vite: - specifier: ^8.1.2 - version: 8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0) + specifier: ^8.1.5 + version: 8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.19.21)(vite@8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0)) + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.19.21)(vite@8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0)) packages: @@ -64,156 +62,312 @@ packages: '@emnapi/wasi-threads@1.2.2': resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.28.1': resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.28.1': resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.28.1': resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.28.1': resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.28.1': resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.28.1': resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.28.1': resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.28.1': resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.28.1': resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.28.1': resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.28.1': resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.28.1': resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.28.1': resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.28.1': resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.28.1': resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.28.1': resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.28.1': resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-arm64@0.28.1': resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.28.1': resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-arm64@0.28.1': resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.28.1': resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/openharmony-arm64@0.28.1': resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.28.1': resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.28.1': resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.28.1': resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.28.1': resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} engines: {node: '>=18'} @@ -498,14 +652,20 @@ packages: '@tangle-network/agent-core@0.4.33': resolution: {integrity: sha512-if3DeIo4e2c9wELJjrWOu4SsKv3WnWdDrp+kezP6JrpiQ1DXValRRlN/aTppicFHepw67OD5JQI9i351Z/hvDQ==} - '@tangle-network/agent-eval@0.143.0': - resolution: {integrity: sha512-Vx26rz0+qhb1QYd8YkSfoTgvdcoWtqAkR+4H7de4iu4mXKjLlefdWm5iRd4Nwqxgrd4R3Zrgm17N/b282mMCLQ==} + '@tangle-network/agent-core@0.5.4': + resolution: {integrity: sha512-k6gYv3BlagkfuWrGyTJH6mKUBgsLY6TXxizACqt0QF8a1/5uqy0UYc6R2Wo9nqQVJuaRxDnoiRf8YtsRVqA75g==} + + '@tangle-network/agent-eval@0.145.0': + resolution: {integrity: sha512-R2f3Q8vQEAoz4VoOcb/TubNRaa3KaDrpqsBKdy+rmaIbx8bZqiT8CoGw63Fu2/oV5bTr2OZv1Fs1GwyINdCV0g==} engines: {node: '>=20'} hasBin: true '@tangle-network/agent-interface@0.43.0': resolution: {integrity: sha512-t35nGOJ3sWouHoUM/5A8eUmsR+8JcuRF6VFQbT9cPzxIMUV3NsFMJgYXPGmyIj65vtvs73O6Mvijp47FAAGbuQ==} + '@tangle-network/agent-interface@0.46.1': + resolution: {integrity: sha512-6a3GRkDxS+r6Bmlu8y6LQpiVE20oCYPzE2opb5o+AZeDzRW5KemyxreyYIprjgKfDrvBTMo0tgvC2JB51Sl84w==} + '@tangle-network/agent-knowledge@7.0.8': resolution: {integrity: sha512-FXA8KGCraUwX+2aNGWI8hZYAJ8f2T0iLBPbtzwbUoYl4t6h87munYoDQOh9YjarrAmkp6tcuGIGPKnw0FdCydg==} engines: {node: '>=20.19.0'} @@ -521,7 +681,7 @@ packages: engines: {node: '>=22.13.0'} hasBin: true peerDependencies: - '@tangle-network/agent-eval': '>=0.143.0 <0.144.0' + '@tangle-network/agent-eval': 0.145.0 '@tangle-network/agent-interface': '>=0.43.0 <0.44.0' '@tangle-network/sandbox': '>=0.17.2 <0.18.0' playwright: ^1.40.0 @@ -576,7 +736,7 @@ packages: resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} peerDependencies: msw: ^2.4.9 - vite: ^8.1.2 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: msw: optional: true @@ -662,7 +822,7 @@ packages: resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} peerDependencies: - esbuild: ^0.28.1 + esbuild: '>=0.18' cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} @@ -709,6 +869,11 @@ packages: es-module-lexer@2.2.0: resolution: {integrity: sha512-3lGxdTXCLfe1MYfTz1y2ksAAUM4NAOP6rPEjxGJVKO7TZ5+tvHCaQWGpC4Y3IXvW3ece0Cz1cIP4FWBxOnGCTQ==} + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + engines: {node: '>=18'} + hasBin: true + esbuild@0.28.1: resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} engines: {node: '>=18'} @@ -1090,7 +1255,7 @@ packages: peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 '@vitejs/devtools': ^0.3.0 - esbuild: ^0.28.1 + esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 sass: ^1.70.0 @@ -1142,7 +1307,7 @@ packages: '@vitest/ui': 4.1.10 happy-dom: '*' jsdom: '*' - vite: ^8.1.2 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -1203,81 +1368,159 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.27.7': + optional: true + '@esbuild/aix-ppc64@0.28.1': optional: true + '@esbuild/android-arm64@0.27.7': + optional: true + '@esbuild/android-arm64@0.28.1': optional: true + '@esbuild/android-arm@0.27.7': + optional: true + '@esbuild/android-arm@0.28.1': optional: true + '@esbuild/android-x64@0.27.7': + optional: true + '@esbuild/android-x64@0.28.1': optional: true + '@esbuild/darwin-arm64@0.27.7': + optional: true + '@esbuild/darwin-arm64@0.28.1': optional: true + '@esbuild/darwin-x64@0.27.7': + optional: true + '@esbuild/darwin-x64@0.28.1': optional: true + '@esbuild/freebsd-arm64@0.27.7': + optional: true + '@esbuild/freebsd-arm64@0.28.1': optional: true + '@esbuild/freebsd-x64@0.27.7': + optional: true + '@esbuild/freebsd-x64@0.28.1': optional: true + '@esbuild/linux-arm64@0.27.7': + optional: true + '@esbuild/linux-arm64@0.28.1': optional: true + '@esbuild/linux-arm@0.27.7': + optional: true + '@esbuild/linux-arm@0.28.1': optional: true + '@esbuild/linux-ia32@0.27.7': + optional: true + '@esbuild/linux-ia32@0.28.1': optional: true + '@esbuild/linux-loong64@0.27.7': + optional: true + '@esbuild/linux-loong64@0.28.1': optional: true + '@esbuild/linux-mips64el@0.27.7': + optional: true + '@esbuild/linux-mips64el@0.28.1': optional: true + '@esbuild/linux-ppc64@0.27.7': + optional: true + '@esbuild/linux-ppc64@0.28.1': optional: true + '@esbuild/linux-riscv64@0.27.7': + optional: true + '@esbuild/linux-riscv64@0.28.1': optional: true + '@esbuild/linux-s390x@0.27.7': + optional: true + '@esbuild/linux-s390x@0.28.1': optional: true + '@esbuild/linux-x64@0.27.7': + optional: true + '@esbuild/linux-x64@0.28.1': optional: true + '@esbuild/netbsd-arm64@0.27.7': + optional: true + '@esbuild/netbsd-arm64@0.28.1': optional: true + '@esbuild/netbsd-x64@0.27.7': + optional: true + '@esbuild/netbsd-x64@0.28.1': optional: true + '@esbuild/openbsd-arm64@0.27.7': + optional: true + '@esbuild/openbsd-arm64@0.28.1': optional: true + '@esbuild/openbsd-x64@0.27.7': + optional: true + '@esbuild/openbsd-x64@0.28.1': optional: true + '@esbuild/openharmony-arm64@0.27.7': + optional: true + '@esbuild/openharmony-arm64@0.28.1': optional: true + '@esbuild/sunos-x64@0.27.7': + optional: true + '@esbuild/sunos-x64@0.28.1': optional: true + '@esbuild/win32-arm64@0.27.7': + optional: true + '@esbuild/win32-arm64@0.28.1': optional: true + '@esbuild/win32-ia32@0.27.7': + optional: true + '@esbuild/win32-ia32@0.28.1': optional: true + '@esbuild/win32-x64@0.27.7': + optional: true + '@esbuild/win32-x64@0.28.1': optional: true @@ -1446,12 +1689,17 @@ snapshots: '@tangle-network/agent-interface': 0.43.0 zod: 4.4.3 - '@tangle-network/agent-eval@0.143.0': + '@tangle-network/agent-core@0.5.4': + dependencies: + '@tangle-network/agent-interface': 0.46.1 + zod: 4.4.3 + + '@tangle-network/agent-eval@0.145.0': dependencies: '@asteasolutions/zod-to-openapi': 9.1.0(zod@4.4.3) '@hono/node-server': 2.0.12(hono@4.12.32) - '@tangle-network/agent-core': 0.4.33 - '@tangle-network/agent-interface': 0.43.0 + '@tangle-network/agent-core': 0.5.4 + '@tangle-network/agent-interface': 0.46.1 '@tangle-network/agent-trace-contract': 1.0.2 hono: 4.12.32 linear-sum-assignment: 1.0.9 @@ -1464,23 +1712,29 @@ snapshots: spdx-expression-parse: 5.0.0 zod: 4.4.3 + '@tangle-network/agent-interface@0.46.1': + dependencies: + '@noble/hashes': 1.8.0 + spdx-expression-parse: 5.0.0 + zod: 4.4.3 + '@tangle-network/agent-knowledge@7.0.8': dependencies: - '@tangle-network/agent-eval': 0.143.0 + '@tangle-network/agent-eval': 0.145.0 '@tangle-network/agent-interface': 0.43.0 proper-lockfile: 4.1.2 zod: 4.4.3 - '@tangle-network/agent-profile-materialize@0.10.2(@tangle-network/agent-interface@0.43.0)': + '@tangle-network/agent-profile-materialize@0.10.2(@tangle-network/agent-interface@0.46.1)': dependencies: - '@tangle-network/agent-interface': 0.43.0 + '@tangle-network/agent-interface': 0.46.1 - '@tangle-network/agent-runtime@0.126.0(@tangle-network/agent-eval@0.143.0)(@tangle-network/agent-interface@0.43.0)(@tangle-network/sandbox@0.17.2)': + '@tangle-network/agent-runtime@0.126.0(@tangle-network/agent-eval@0.145.0)(@tangle-network/agent-interface@0.46.1)(@tangle-network/sandbox@0.17.2)': dependencies: - '@tangle-network/agent-eval': 0.143.0 - '@tangle-network/agent-interface': 0.43.0 + '@tangle-network/agent-eval': 0.145.0 + '@tangle-network/agent-interface': 0.46.1 '@tangle-network/agent-knowledge': 7.0.8 - '@tangle-network/agent-profile-materialize': 0.10.2(@tangle-network/agent-interface@0.43.0) + '@tangle-network/agent-profile-materialize': 0.10.2(@tangle-network/agent-interface@0.46.1) '@tangle-network/agent-trace-contract': 1.0.2 tar-stream: 3.2.0 optionalDependencies: @@ -1525,13 +1779,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.10(vite@8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0))': + '@vitest/mocker@4.1.10(vite@8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0) '@vitest/pretty-format@4.1.10': dependencies: @@ -1596,9 +1850,9 @@ snapshots: binary-search@1.3.6: {} - bundle-require@5.1.0(esbuild@0.28.1): + bundle-require@5.1.0(esbuild@0.27.7): dependencies: - esbuild: 0.28.1 + esbuild: 0.27.7 load-tsconfig: 0.2.5 cac@6.7.14: {} @@ -1627,6 +1881,35 @@ snapshots: es-module-lexer@2.2.0: {} + esbuild@0.27.7: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 + esbuild@0.28.1: optionalDependencies: '@esbuild/aix-ppc64': 0.28.1 @@ -2003,12 +2286,12 @@ snapshots: tsup@8.5.1(postcss@8.5.25)(tsx@4.23.1)(typescript@5.9.3)(yaml@2.9.0): dependencies: - bundle-require: 5.1.0(esbuild@0.28.1) + bundle-require: 5.1.0(esbuild@0.27.7) cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.2 debug: 4.4.3 - esbuild: 0.28.1 + esbuild: 0.27.7 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 @@ -2041,7 +2324,7 @@ snapshots: undici-types@6.21.0: {} - vite@8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0): + vite@8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.5 @@ -2050,15 +2333,15 @@ snapshots: tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.19.21 - esbuild: 0.28.1 + esbuild: 0.27.7 fsevents: 2.3.3 tsx: 4.23.1 yaml: 2.9.0 - vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.19.21)(vite@8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0)): + vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.19.21)(vite@8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0)) + '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -2075,7 +2358,7 @@ snapshots: tinyexec: 1.2.4 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 diff --git a/src/cli.ts b/src/cli.ts index ae819b4..70245a1 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -89,6 +89,7 @@ import { import { fileRunContextSupervisorRunReader, isFileRunContextDir } from './supervisor-run-context.js' import { resolveRunWatchTarget, watchRunTarget } from './run-watch.js' import { createDspyRlmTraceEngine, type TraceAnalysisEngine } from '@tangle-network/agent-eval/analyst' +import { callLlm, costReceiptFromLlm, costReceiptFromLlmError, type LlmCallRequest } from '@tangle-network/agent-eval' import type { OtlpSpan } from './otlp.js' import { serializeSpans, writeOtlpFile } from './otlp.js' import type { @@ -501,15 +502,57 @@ function buildAnalysisEngine(model: string, budgetUsd?: number): TraceAnalysisEn (tangleKey ? TANGLE_ROUTER_BASE_URL : 'https://api.openai.com/v1') const python = process.env.TRACES_PYTHON return createDspyRlmTraceEngine({ - apiKey, - baseUrl, + // agent-eval 0.144.0 stopped accepting provider credentials: the caller + // owns the execution path and returns a typed result plus a cost receipt + // for every admitted call. This CLI's path is one OpenAI-compatible HTTP + // call through agent-eval's own `callLlm`. + call: async ({ request, signal }) => { + const req = structuredClone(request) as LlmCallRequest + try { + const response = await callLlm(req, { apiKey, baseUrl, signal }) + return { + succeeded: true, + response, + receipt: costReceiptFromLlm(response), + execution: { + baseUrl, + requestedModel: req.model, + servedModel: response.servedModel ?? null, + finishReason: response.finishReason ?? null, + durationMs: response.durationMs, + }, + } + } catch (error) { + const err = error instanceof Error ? error : new Error(String(error)) + return { + succeeded: false, + error: err.message, + // costReceiptFromLlmError recovers the provider receipt when the + // response completed but violated the contract; otherwise usage + // and cost stay explicitly unknown. + receipt: costReceiptFromLlmError(err) ?? { + model: req.model, + inputTokens: 0, + outputTokens: 0, + costUnknown: true, + usageUnknown: true, + }, + execution: { baseUrl, requestedModel: req.model, error: err.message }, + } + } + }, + callRef: `traces-cli:${baseUrl}#${model}`, + recordExecution: (observation) => { + analystLog( + `[analyst] model call ${observation.sequence} ${observation.succeeded ? 'ok' : 'FAIL'} ${observation.model}`, + observation.succeeded ? undefined : { error: observation.error }, + ) + }, model, - // agent-eval 0.139.3's engine defaults are tuned below what real runs - // need. maxOutputTokens 4096 is under what current coding models emit for - // one findings array: glm-5.2 counts reasoning tokens in - // completion_tokens, the first oversized completion breaches its cost - // reservation, and the fail-closed ledger then refuses every later call - // in the run. + // Pinned, not defaulted: one findings array from a current coding model + // needs this cap, and glm-5.2 counts reasoning tokens in + // completion_tokens — a smaller cap breaches its cost reservation and the + // fail-closed ledger then refuses every later call in the run. maxOutputTokens: 16_384, // maxCostUsd defaults to $1 per analyst — a proxy-side ceiling separate // from --budget. With the larger token cap the per-call reservation grows From bd114c5d4c2fe1c80589b567ea44296a7268d3e6 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 12 Aug 2026 15:06:52 -0600 Subject: [PATCH 2/6] chore(deps): agent-eval 0.145.3 and agent-runtime 0.132.13, drop the pnpm override The published agent-runtime 0.132.13 peers on agent-eval '>=0.145.2 <0.146.0'. The override existed only to force past the old peer cap and is no longer needed. pnpm resolves one agent-eval version (0.145.3) across the tree. --- package.json | 9 +- pnpm-lock.yaml | 387 ++++++++----------------------------------------- 2 files changed, 63 insertions(+), 333 deletions(-) diff --git a/package.json b/package.json index 04437f7..689eb9f 100644 --- a/package.json +++ b/package.json @@ -59,16 +59,11 @@ "prepublishOnly": "pnpm check:source && pnpm build && pnpm check:package" }, "dependencies": { - "@tangle-network/agent-eval": "0.145.0", - "@tangle-network/agent-runtime": "0.126.0", + "@tangle-network/agent-eval": "0.145.3", + "@tangle-network/agent-runtime": "0.132.13", "@tangle-network/agent-trace-contract": "^1.0.2", "@tangle-network/sandbox": "0.17.2" }, - "pnpm": { - "overrides": { - "@tangle-network/agent-eval": "0.145.0" - } - }, "devDependencies": { "@types/node": "^22.0.0", "postcss": "^8.5.25", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f4a2634..a54d993 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,18 +5,20 @@ settings: excludeLinksFromLockfile: false overrides: - '@tangle-network/agent-eval': 0.145.0 + esbuild: ^0.28.1 + vite: ^8.1.2 + ws: ^8.21.0 importers: .: dependencies: '@tangle-network/agent-eval': - specifier: 0.145.0 - version: 0.145.0 + specifier: 0.145.3 + version: 0.145.3 '@tangle-network/agent-runtime': - specifier: 0.126.0 - version: 0.126.0(@tangle-network/agent-eval@0.145.0)(@tangle-network/agent-interface@0.46.1)(@tangle-network/sandbox@0.17.2) + specifier: 0.132.13 + version: 0.132.13(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)(@tangle-network/sandbox@0.17.2) '@tangle-network/agent-trace-contract': specifier: ^1.0.2 version: 1.0.2 @@ -40,11 +42,11 @@ importers: specifier: ^5.7.0 version: 5.9.3 vite: - specifier: ^8.1.5 - version: 8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0) + specifier: ^8.1.2 + version: 8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.19.21)(vite@8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0)) + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.19.21)(vite@8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0)) packages: @@ -62,312 +64,156 @@ packages: '@emnapi/wasi-threads@1.2.2': resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} - '@esbuild/aix-ppc64@0.27.7': - resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.28.1': resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.27.7': - resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.28.1': resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.27.7': - resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.28.1': resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.27.7': - resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.28.1': resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.27.7': - resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.28.1': resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.27.7': - resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.28.1': resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.27.7': - resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.28.1': resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.7': - resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.28.1': resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.27.7': - resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.28.1': resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.27.7': - resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.28.1': resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.27.7': - resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.28.1': resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.27.7': - resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.28.1': resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.27.7': - resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.28.1': resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.27.7': - resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.28.1': resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.27.7': - resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.28.1': resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.27.7': - resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.28.1': resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.27.7': - resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.28.1': resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.27.7': - resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-arm64@0.28.1': resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.7': - resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.28.1': resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.27.7': - resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-arm64@0.28.1': resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.7': - resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.28.1': resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.27.7': - resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - '@esbuild/openharmony-arm64@0.28.1': resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.27.7': - resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.28.1': resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.27.7': - resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.28.1': resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.27.7': - resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.28.1': resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.27.7': - resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.28.1': resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} engines: {node: '>=18'} @@ -652,44 +498,44 @@ packages: '@tangle-network/agent-core@0.4.33': resolution: {integrity: sha512-if3DeIo4e2c9wELJjrWOu4SsKv3WnWdDrp+kezP6JrpiQ1DXValRRlN/aTppicFHepw67OD5JQI9i351Z/hvDQ==} - '@tangle-network/agent-core@0.5.4': - resolution: {integrity: sha512-k6gYv3BlagkfuWrGyTJH6mKUBgsLY6TXxizACqt0QF8a1/5uqy0UYc6R2Wo9nqQVJuaRxDnoiRf8YtsRVqA75g==} + '@tangle-network/agent-core@0.6.1': + resolution: {integrity: sha512-vPpxnSmXpXA9NBjmbOzEnocMJBdskMTrueCepJnztQsO3Z7CKpPQShcJbA5XRv4KyH3KPF284vgMI5lojErvsw==} - '@tangle-network/agent-eval@0.145.0': - resolution: {integrity: sha512-R2f3Q8vQEAoz4VoOcb/TubNRaa3KaDrpqsBKdy+rmaIbx8bZqiT8CoGw63Fu2/oV5bTr2OZv1Fs1GwyINdCV0g==} + '@tangle-network/agent-eval@0.145.3': + resolution: {integrity: sha512-KPiYjw/SYLFF+mFZF2mjneUmU1Q6SQB6B1PiJRyw3UcnxNxdR8K6M+C7+YGoa/HsEVluhGkD25VPE3T1wTAAww==} engines: {node: '>=20'} hasBin: true '@tangle-network/agent-interface@0.43.0': resolution: {integrity: sha512-t35nGOJ3sWouHoUM/5A8eUmsR+8JcuRF6VFQbT9cPzxIMUV3NsFMJgYXPGmyIj65vtvs73O6Mvijp47FAAGbuQ==} - '@tangle-network/agent-interface@0.46.1': - resolution: {integrity: sha512-6a3GRkDxS+r6Bmlu8y6LQpiVE20oCYPzE2opb5o+AZeDzRW5KemyxreyYIprjgKfDrvBTMo0tgvC2JB51Sl84w==} + '@tangle-network/agent-interface@0.47.0': + resolution: {integrity: sha512-sCkr7FOT+SNut8EYtwh/x2JheI+Eer30V5IQVIrO8Fn6csC9pqlnLRuNDJh//pnk4+fsg4yLiiSW8/hL1l9e1w==} - '@tangle-network/agent-knowledge@7.0.8': - resolution: {integrity: sha512-FXA8KGCraUwX+2aNGWI8hZYAJ8f2T0iLBPbtzwbUoYl4t6h87munYoDQOh9YjarrAmkp6tcuGIGPKnw0FdCydg==} + '@tangle-network/agent-knowledge@7.2.4': + resolution: {integrity: sha512-xzDAH7YuMD3ijO4gnhvtWz92OvrQ5mlvjTco4tea5fBVkQJVZ1YfPVvgnJ0tTmJXSTe9hqpLiKUTZ5jqe9gnxg==} engines: {node: '>=20.19.0'} hasBin: true + peerDependencies: + '@tangle-network/agent-eval': '>=0.145.2 <0.146.0' + '@tangle-network/agent-interface': '>=0.47.0 <0.48.0' - '@tangle-network/agent-profile-materialize@0.10.2': - resolution: {integrity: sha512-u3MtUy8BD5odTWu/nK0b2XuieBSZMMx1kR9izwqIoR+c8pQaIRQiENNms9qeyQFLqqm7ewC1/Qq5oTtuihs/5g==} + '@tangle-network/agent-profile-materialize@0.14.0': + resolution: {integrity: sha512-LfuyhtrPFvjMvtmZoFoPQehk+8I2e3urAlozEzm9MGQAstkPhsv6lJ/M7mpJYSwD6UVm42Q2GhqgRASi0b8lww==} peerDependencies: - '@tangle-network/agent-interface': '>=0.38.0 <0.44.0' + '@tangle-network/agent-interface': '>=0.46.0 <0.48.0' - '@tangle-network/agent-runtime@0.126.0': - resolution: {integrity: sha512-JTsF13tdb0vv+Tb2Rzm9M2vm6izLno7bJ0Yk/VC0zDE63xllIia0tNKBj2ZGDAkbNFARSIz3wqGFZ/A00x52Yg==} + '@tangle-network/agent-runtime@0.132.13': + resolution: {integrity: sha512-SK7AiwYg2wGwi5q4gVniKFgD64T8J3TUvQRBwutVvX5hsjqd05zp2m1P7jKr0KTWWnViJnORNvVNJe0EVjhLzw==} engines: {node: '>=22.13.0'} hasBin: true peerDependencies: - '@tangle-network/agent-eval': 0.145.0 - '@tangle-network/agent-interface': '>=0.43.0 <0.44.0' - '@tangle-network/sandbox': '>=0.17.2 <0.18.0' - playwright: ^1.40.0 + '@tangle-network/agent-eval': '>=0.145.2 <0.146.0' + '@tangle-network/agent-interface': '>=0.47.0 <0.48.0' + '@tangle-network/sandbox': '>=0.21.1 <0.22.0' peerDependenciesMeta: '@tangle-network/sandbox': optional: true - playwright: - optional: true '@tangle-network/agent-trace-contract@1.0.2': resolution: {integrity: sha512-v7uMh56jkEp4vckevEU9xKsIatbs5dqzGPp69dFLSSXUVit0RP6VD6EANMXVlTCUk+6wVKBLHJx23XspVCEiIA==} @@ -736,7 +582,7 @@ packages: resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} peerDependencies: msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + vite: ^8.1.2 peerDependenciesMeta: msw: optional: true @@ -822,7 +668,7 @@ packages: resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} peerDependencies: - esbuild: '>=0.18' + esbuild: ^0.28.1 cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} @@ -869,11 +715,6 @@ packages: es-module-lexer@2.2.0: resolution: {integrity: sha512-3lGxdTXCLfe1MYfTz1y2ksAAUM4NAOP6rPEjxGJVKO7TZ5+tvHCaQWGpC4Y3IXvW3ece0Cz1cIP4FWBxOnGCTQ==} - esbuild@0.27.7: - resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} - engines: {node: '>=18'} - hasBin: true - esbuild@0.28.1: resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} engines: {node: '>=18'} @@ -1255,7 +1096,7 @@ packages: peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 '@vitejs/devtools': ^0.3.0 - esbuild: ^0.27.0 || ^0.28.0 + esbuild: ^0.28.1 jiti: '>=1.21.0' less: ^4.0.0 sass: ^1.70.0 @@ -1307,7 +1148,7 @@ packages: '@vitest/ui': 4.1.10 happy-dom: '*' jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + vite: ^8.1.2 peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -1368,159 +1209,81 @@ snapshots: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.27.7': - optional: true - '@esbuild/aix-ppc64@0.28.1': optional: true - '@esbuild/android-arm64@0.27.7': - optional: true - '@esbuild/android-arm64@0.28.1': optional: true - '@esbuild/android-arm@0.27.7': - optional: true - '@esbuild/android-arm@0.28.1': optional: true - '@esbuild/android-x64@0.27.7': - optional: true - '@esbuild/android-x64@0.28.1': optional: true - '@esbuild/darwin-arm64@0.27.7': - optional: true - '@esbuild/darwin-arm64@0.28.1': optional: true - '@esbuild/darwin-x64@0.27.7': - optional: true - '@esbuild/darwin-x64@0.28.1': optional: true - '@esbuild/freebsd-arm64@0.27.7': - optional: true - '@esbuild/freebsd-arm64@0.28.1': optional: true - '@esbuild/freebsd-x64@0.27.7': - optional: true - '@esbuild/freebsd-x64@0.28.1': optional: true - '@esbuild/linux-arm64@0.27.7': - optional: true - '@esbuild/linux-arm64@0.28.1': optional: true - '@esbuild/linux-arm@0.27.7': - optional: true - '@esbuild/linux-arm@0.28.1': optional: true - '@esbuild/linux-ia32@0.27.7': - optional: true - '@esbuild/linux-ia32@0.28.1': optional: true - '@esbuild/linux-loong64@0.27.7': - optional: true - '@esbuild/linux-loong64@0.28.1': optional: true - '@esbuild/linux-mips64el@0.27.7': - optional: true - '@esbuild/linux-mips64el@0.28.1': optional: true - '@esbuild/linux-ppc64@0.27.7': - optional: true - '@esbuild/linux-ppc64@0.28.1': optional: true - '@esbuild/linux-riscv64@0.27.7': - optional: true - '@esbuild/linux-riscv64@0.28.1': optional: true - '@esbuild/linux-s390x@0.27.7': - optional: true - '@esbuild/linux-s390x@0.28.1': optional: true - '@esbuild/linux-x64@0.27.7': - optional: true - '@esbuild/linux-x64@0.28.1': optional: true - '@esbuild/netbsd-arm64@0.27.7': - optional: true - '@esbuild/netbsd-arm64@0.28.1': optional: true - '@esbuild/netbsd-x64@0.27.7': - optional: true - '@esbuild/netbsd-x64@0.28.1': optional: true - '@esbuild/openbsd-arm64@0.27.7': - optional: true - '@esbuild/openbsd-arm64@0.28.1': optional: true - '@esbuild/openbsd-x64@0.27.7': - optional: true - '@esbuild/openbsd-x64@0.28.1': optional: true - '@esbuild/openharmony-arm64@0.27.7': - optional: true - '@esbuild/openharmony-arm64@0.28.1': optional: true - '@esbuild/sunos-x64@0.27.7': - optional: true - '@esbuild/sunos-x64@0.28.1': optional: true - '@esbuild/win32-arm64@0.27.7': - optional: true - '@esbuild/win32-arm64@0.28.1': optional: true - '@esbuild/win32-ia32@0.27.7': - optional: true - '@esbuild/win32-ia32@0.28.1': optional: true - '@esbuild/win32-x64@0.27.7': - optional: true - '@esbuild/win32-x64@0.28.1': optional: true @@ -1689,17 +1452,17 @@ snapshots: '@tangle-network/agent-interface': 0.43.0 zod: 4.4.3 - '@tangle-network/agent-core@0.5.4': + '@tangle-network/agent-core@0.6.1': dependencies: - '@tangle-network/agent-interface': 0.46.1 + '@tangle-network/agent-interface': 0.47.0 zod: 4.4.3 - '@tangle-network/agent-eval@0.145.0': + '@tangle-network/agent-eval@0.145.3': dependencies: '@asteasolutions/zod-to-openapi': 9.1.0(zod@4.4.3) '@hono/node-server': 2.0.12(hono@4.12.32) - '@tangle-network/agent-core': 0.5.4 - '@tangle-network/agent-interface': 0.46.1 + '@tangle-network/agent-core': 0.6.1 + '@tangle-network/agent-interface': 0.47.0 '@tangle-network/agent-trace-contract': 1.0.2 hono: 4.12.32 linear-sum-assignment: 1.0.9 @@ -1712,29 +1475,30 @@ snapshots: spdx-expression-parse: 5.0.0 zod: 4.4.3 - '@tangle-network/agent-interface@0.46.1': + '@tangle-network/agent-interface@0.47.0': dependencies: '@noble/hashes': 1.8.0 spdx-expression-parse: 5.0.0 zod: 4.4.3 - '@tangle-network/agent-knowledge@7.0.8': + '@tangle-network/agent-knowledge@7.2.4(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)': dependencies: - '@tangle-network/agent-eval': 0.145.0 - '@tangle-network/agent-interface': 0.43.0 + '@tangle-network/agent-eval': 0.145.3 + '@tangle-network/agent-interface': 0.47.0 proper-lockfile: 4.1.2 zod: 4.4.3 - '@tangle-network/agent-profile-materialize@0.10.2(@tangle-network/agent-interface@0.46.1)': + '@tangle-network/agent-profile-materialize@0.14.0(@tangle-network/agent-interface@0.47.0)': dependencies: - '@tangle-network/agent-interface': 0.46.1 + '@tangle-network/agent-interface': 0.47.0 - '@tangle-network/agent-runtime@0.126.0(@tangle-network/agent-eval@0.145.0)(@tangle-network/agent-interface@0.46.1)(@tangle-network/sandbox@0.17.2)': + '@tangle-network/agent-runtime@0.132.13(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)(@tangle-network/sandbox@0.17.2)': dependencies: - '@tangle-network/agent-eval': 0.145.0 - '@tangle-network/agent-interface': 0.46.1 - '@tangle-network/agent-knowledge': 7.0.8 - '@tangle-network/agent-profile-materialize': 0.10.2(@tangle-network/agent-interface@0.46.1) + '@tangle-network/agent-core': 0.6.1 + '@tangle-network/agent-eval': 0.145.3 + '@tangle-network/agent-interface': 0.47.0 + '@tangle-network/agent-knowledge': 7.2.4(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0) + '@tangle-network/agent-profile-materialize': 0.14.0(@tangle-network/agent-interface@0.47.0) '@tangle-network/agent-trace-contract': 1.0.2 tar-stream: 3.2.0 optionalDependencies: @@ -1779,13 +1543,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.10(vite@8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0))': + '@vitest/mocker@4.1.10(vite@8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0) '@vitest/pretty-format@4.1.10': dependencies: @@ -1850,9 +1614,9 @@ snapshots: binary-search@1.3.6: {} - bundle-require@5.1.0(esbuild@0.27.7): + bundle-require@5.1.0(esbuild@0.28.1): dependencies: - esbuild: 0.27.7 + esbuild: 0.28.1 load-tsconfig: 0.2.5 cac@6.7.14: {} @@ -1881,35 +1645,6 @@ snapshots: es-module-lexer@2.2.0: {} - esbuild@0.27.7: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.7 - '@esbuild/android-arm': 0.27.7 - '@esbuild/android-arm64': 0.27.7 - '@esbuild/android-x64': 0.27.7 - '@esbuild/darwin-arm64': 0.27.7 - '@esbuild/darwin-x64': 0.27.7 - '@esbuild/freebsd-arm64': 0.27.7 - '@esbuild/freebsd-x64': 0.27.7 - '@esbuild/linux-arm': 0.27.7 - '@esbuild/linux-arm64': 0.27.7 - '@esbuild/linux-ia32': 0.27.7 - '@esbuild/linux-loong64': 0.27.7 - '@esbuild/linux-mips64el': 0.27.7 - '@esbuild/linux-ppc64': 0.27.7 - '@esbuild/linux-riscv64': 0.27.7 - '@esbuild/linux-s390x': 0.27.7 - '@esbuild/linux-x64': 0.27.7 - '@esbuild/netbsd-arm64': 0.27.7 - '@esbuild/netbsd-x64': 0.27.7 - '@esbuild/openbsd-arm64': 0.27.7 - '@esbuild/openbsd-x64': 0.27.7 - '@esbuild/openharmony-arm64': 0.27.7 - '@esbuild/sunos-x64': 0.27.7 - '@esbuild/win32-arm64': 0.27.7 - '@esbuild/win32-ia32': 0.27.7 - '@esbuild/win32-x64': 0.27.7 - esbuild@0.28.1: optionalDependencies: '@esbuild/aix-ppc64': 0.28.1 @@ -2286,12 +2021,12 @@ snapshots: tsup@8.5.1(postcss@8.5.25)(tsx@4.23.1)(typescript@5.9.3)(yaml@2.9.0): dependencies: - bundle-require: 5.1.0(esbuild@0.27.7) + bundle-require: 5.1.0(esbuild@0.28.1) cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.2 debug: 4.4.3 - esbuild: 0.27.7 + esbuild: 0.28.1 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 @@ -2324,7 +2059,7 @@ snapshots: undici-types@6.21.0: {} - vite@8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0): + vite@8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.5 @@ -2333,15 +2068,15 @@ snapshots: tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.19.21 - esbuild: 0.27.7 + esbuild: 0.28.1 fsevents: 2.3.3 tsx: 4.23.1 yaml: 2.9.0 - vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.19.21)(vite@8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0)): + vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.19.21)(vite@8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0)) + '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -2358,7 +2093,7 @@ snapshots: tinyexec: 1.2.4 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.1.5(@types/node@22.19.21)(esbuild@0.27.7)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.1.5(@types/node@22.19.21)(esbuild@0.28.1)(tsx@4.23.1)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 From 5567945691af838bea413213f89b12f41b6109d5 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 12 Aug 2026 16:28:56 -0600 Subject: [PATCH 3/6] chore(deps): agent-runtime 0.133.0 and sandbox 0.21.1 agent-runtime 0.133.0 peers on sandbox '>=0.21.1 <0.22.0'. The repo held sandbox 0.17.2, which does not satisfy that range. sandbox 0.21.1 is published, so the peer contract closes with one version of each Tangle package in the tree. --- package.json | 4 ++-- pnpm-lock.yaml | 43 +++++++++++++------------------------------ 2 files changed, 15 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 689eb9f..f075f1b 100644 --- a/package.json +++ b/package.json @@ -60,9 +60,9 @@ }, "dependencies": { "@tangle-network/agent-eval": "0.145.3", - "@tangle-network/agent-runtime": "0.132.13", + "@tangle-network/agent-runtime": "0.133.0", "@tangle-network/agent-trace-contract": "^1.0.2", - "@tangle-network/sandbox": "0.17.2" + "@tangle-network/sandbox": "0.21.1" }, "devDependencies": { "@types/node": "^22.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a54d993..26df3eb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,14 +17,14 @@ importers: specifier: 0.145.3 version: 0.145.3 '@tangle-network/agent-runtime': - specifier: 0.132.13 - version: 0.132.13(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)(@tangle-network/sandbox@0.17.2) + specifier: 0.133.0 + version: 0.133.0(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)(@tangle-network/sandbox@0.21.1) '@tangle-network/agent-trace-contract': specifier: ^1.0.2 version: 1.0.2 '@tangle-network/sandbox': - specifier: 0.17.2 - version: 0.17.2 + specifier: 0.21.1 + version: 0.21.1 devDependencies: '@types/node': specifier: ^22.0.0 @@ -495,9 +495,6 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@tangle-network/agent-core@0.4.33': - resolution: {integrity: sha512-if3DeIo4e2c9wELJjrWOu4SsKv3WnWdDrp+kezP6JrpiQ1DXValRRlN/aTppicFHepw67OD5JQI9i351Z/hvDQ==} - '@tangle-network/agent-core@0.6.1': resolution: {integrity: sha512-vPpxnSmXpXA9NBjmbOzEnocMJBdskMTrueCepJnztQsO3Z7CKpPQShcJbA5XRv4KyH3KPF284vgMI5lojErvsw==} @@ -506,9 +503,6 @@ packages: engines: {node: '>=20'} hasBin: true - '@tangle-network/agent-interface@0.43.0': - resolution: {integrity: sha512-t35nGOJ3sWouHoUM/5A8eUmsR+8JcuRF6VFQbT9cPzxIMUV3NsFMJgYXPGmyIj65vtvs73O6Mvijp47FAAGbuQ==} - '@tangle-network/agent-interface@0.47.0': resolution: {integrity: sha512-sCkr7FOT+SNut8EYtwh/x2JheI+Eer30V5IQVIrO8Fn6csC9pqlnLRuNDJh//pnk4+fsg4yLiiSW8/hL1l9e1w==} @@ -525,8 +519,8 @@ packages: peerDependencies: '@tangle-network/agent-interface': '>=0.46.0 <0.48.0' - '@tangle-network/agent-runtime@0.132.13': - resolution: {integrity: sha512-SK7AiwYg2wGwi5q4gVniKFgD64T8J3TUvQRBwutVvX5hsjqd05zp2m1P7jKr0KTWWnViJnORNvVNJe0EVjhLzw==} + '@tangle-network/agent-runtime@0.133.0': + resolution: {integrity: sha512-c60aWdygPir4gEFFQg6olcWcGnL8FaKmd2qhgd83n5X1F1+UgLJD4u8bwrb+OBe/EyxqarqgUYYV+MqDM30YCw==} engines: {node: '>=22.13.0'} hasBin: true peerDependencies: @@ -540,8 +534,8 @@ packages: '@tangle-network/agent-trace-contract@1.0.2': resolution: {integrity: sha512-v7uMh56jkEp4vckevEU9xKsIatbs5dqzGPp69dFLSSXUVit0RP6VD6EANMXVlTCUk+6wVKBLHJx23XspVCEiIA==} - '@tangle-network/sandbox@0.17.2': - resolution: {integrity: sha512-e+p/Uet2nVej3pLLCOoxeRN29t38QfWEWpcnnJsC2b0BNsQEPUg6xNlEgdeT9Eo0U6++QyR+GUrDovJ/houd2g==} + '@tangle-network/sandbox@0.21.1': + resolution: {integrity: sha512-xlqI9fxq9TLCOnmcxOU2XgOD5Ls6IOxLAbfa3SxVa/wUNnUCHtnwRHYteF7zUCwngVs6HR01+9dyChc0Q8m2tA==} peerDependencies: '@mastra/core': ^1.36.0 '@modelcontextprotocol/sdk': ^1.29.0 @@ -1447,11 +1441,6 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@tangle-network/agent-core@0.4.33': - dependencies: - '@tangle-network/agent-interface': 0.43.0 - zod: 4.4.3 - '@tangle-network/agent-core@0.6.1': dependencies: '@tangle-network/agent-interface': 0.47.0 @@ -1469,12 +1458,6 @@ snapshots: re2js: 2.8.6 zod: 4.4.3 - '@tangle-network/agent-interface@0.43.0': - dependencies: - '@noble/hashes': 1.8.0 - spdx-expression-parse: 5.0.0 - zod: 4.4.3 - '@tangle-network/agent-interface@0.47.0': dependencies: '@noble/hashes': 1.8.0 @@ -1492,7 +1475,7 @@ snapshots: dependencies: '@tangle-network/agent-interface': 0.47.0 - '@tangle-network/agent-runtime@0.132.13(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)(@tangle-network/sandbox@0.17.2)': + '@tangle-network/agent-runtime@0.133.0(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)(@tangle-network/sandbox@0.21.1)': dependencies: '@tangle-network/agent-core': 0.6.1 '@tangle-network/agent-eval': 0.145.3 @@ -1502,7 +1485,7 @@ snapshots: '@tangle-network/agent-trace-contract': 1.0.2 tar-stream: 3.2.0 optionalDependencies: - '@tangle-network/sandbox': 0.17.2 + '@tangle-network/sandbox': 0.21.1 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -1510,10 +1493,10 @@ snapshots: '@tangle-network/agent-trace-contract@1.0.2': {} - '@tangle-network/sandbox@0.17.2': + '@tangle-network/sandbox@0.21.1': dependencies: - '@tangle-network/agent-core': 0.4.33 - '@tangle-network/agent-interface': 0.43.0 + '@tangle-network/agent-core': 0.6.1 + '@tangle-network/agent-interface': 0.47.0 zod: 4.4.3 '@tybys/wasm-util@0.10.3': From b61cf4b53f26ef4e967a49795c0a9e5387062dee Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 12 Aug 2026 16:48:32 -0600 Subject: [PATCH 4/6] fix(analyst): pass callId as the provider idempotency key The loopback proxy allocates callId as the cost ledger's stable identity for one paid call. callLlm retries transient failures, so without an idempotency key a response that is billed but lost is charged again on the retry. Also move structuredClone inside the try block. The engine contract requires the callback to resolve; a throw from clone rejected the promise and lost the execution record. The catch now reads the model from the immutable request. --- src/cli.ts | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 70245a1..7952e2a 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -506,10 +506,18 @@ function buildAnalysisEngine(model: string, budgetUsd?: number): TraceAnalysisEn // owns the execution path and returns a typed result plus a cost receipt // for every admitted call. This CLI's path is one OpenAI-compatible HTTP // call through agent-eval's own `callLlm`. - call: async ({ request, signal }) => { - const req = structuredClone(request) as LlmCallRequest + call: async ({ request, callId, signal }) => { try { - const response = await callLlm(req, { apiKey, baseUrl, signal }) + const req = structuredClone(request) as LlmCallRequest + // callId is the ledger's stable identity for this one paid call, so it + // is the provider idempotency key: callLlm retries transient failures, + // and without it a lost-but-billed response is charged twice. + const response = await callLlm(req, { + apiKey, + baseUrl, + signal, + idempotencyKey: callId, + }) return { succeeded: true, response, @@ -531,13 +539,17 @@ function buildAnalysisEngine(model: string, budgetUsd?: number): TraceAnalysisEn // response completed but violated the contract; otherwise usage // and cost stay explicitly unknown. receipt: costReceiptFromLlmError(err) ?? { - model: req.model, + model: request.model, inputTokens: 0, outputTokens: 0, costUnknown: true, usageUnknown: true, }, - execution: { baseUrl, requestedModel: req.model, error: err.message }, + execution: { + baseUrl, + requestedModel: request.model, + error: err.message, + }, } } }, From d258224318994162be93ee848accf4dd551c4036 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 12 Aug 2026 19:49:28 -0600 Subject: [PATCH 5/6] fix(analyst): keep abort, provider cause, and callId in the model-call record Move the owned model-call path out of the CLI into its own module so it can be tested directly. cli.ts runs main() at import, so the callback had no reachable test seam. Three defects in the failure path: - An abort resolved as a plain failure string. The proxy only sends 504 when it catches a thrown AbortError, so a cancelled call reached the bridge as a 502 that it retries against a dead intent. The failure text now names the class. - LlmCallError.body was dropped, leaving only the HTTP status. The provider's own reason now stays in the execution evidence, bounded, and out of the log line because a gateway can echo request headers into an error body. - callId was absent from the execution record, so a callback observation could not be correlated with the ledger entry for the same paid call. Cover the success, provider-error, and abort paths against a local OpenAI-compatible server, and raise agent-runtime to 0.133.2. --- package.json | 4 +- pnpm-lock.yaml | 10 +-- src/analyst-model-call.ts | 105 +++++++++++++++++++++++++++++ src/cli.ts | 54 +-------------- tests/analyst-model-call.test.ts | 110 +++++++++++++++++++++++++++++++ 5 files changed, 224 insertions(+), 59 deletions(-) create mode 100644 src/analyst-model-call.ts create mode 100644 tests/analyst-model-call.test.ts diff --git a/package.json b/package.json index f075f1b..91ce253 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@tangle-network/traces", "version": "0.11.5", - "description": "Point it at your coding-agent session traces (Claude Code, Codex, OpenCode, Gemini, Pi, …) and get failure-mode + efficiency findings. CLI + SDK over the @tangle-network/agent-eval analyst suite — observe live sessions, run your own analysts, redact, and upload to the Tangle Intelligence Platform.", + "description": "Point it at your coding-agent session traces (Claude Code, Codex, OpenCode, Gemini, Pi, \u2026) and get failure-mode + efficiency findings. CLI + SDK over the @tangle-network/agent-eval analyst suite \u2014 observe live sessions, run your own analysts, redact, and upload to the Tangle Intelligence Platform.", "type": "module", "license": "MIT", "repository": { @@ -60,7 +60,7 @@ }, "dependencies": { "@tangle-network/agent-eval": "0.145.3", - "@tangle-network/agent-runtime": "0.133.0", + "@tangle-network/agent-runtime": "0.133.2", "@tangle-network/agent-trace-contract": "^1.0.2", "@tangle-network/sandbox": "0.21.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 26df3eb..ee9dae2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,8 +17,8 @@ importers: specifier: 0.145.3 version: 0.145.3 '@tangle-network/agent-runtime': - specifier: 0.133.0 - version: 0.133.0(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)(@tangle-network/sandbox@0.21.1) + specifier: 0.133.2 + version: 0.133.2(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)(@tangle-network/sandbox@0.21.1) '@tangle-network/agent-trace-contract': specifier: ^1.0.2 version: 1.0.2 @@ -519,8 +519,8 @@ packages: peerDependencies: '@tangle-network/agent-interface': '>=0.46.0 <0.48.0' - '@tangle-network/agent-runtime@0.133.0': - resolution: {integrity: sha512-c60aWdygPir4gEFFQg6olcWcGnL8FaKmd2qhgd83n5X1F1+UgLJD4u8bwrb+OBe/EyxqarqgUYYV+MqDM30YCw==} + '@tangle-network/agent-runtime@0.133.2': + resolution: {integrity: sha512-dkqARkCxNEeofHOUiMV0+30Tdw4D2XGX0FErGeF525OeHVMOhfIH2CbbFIWZysHD1J8ZPBFaMnnj+4LztYjnDg==} engines: {node: '>=22.13.0'} hasBin: true peerDependencies: @@ -1475,7 +1475,7 @@ snapshots: dependencies: '@tangle-network/agent-interface': 0.47.0 - '@tangle-network/agent-runtime@0.133.0(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)(@tangle-network/sandbox@0.21.1)': + '@tangle-network/agent-runtime@0.133.2(@tangle-network/agent-eval@0.145.3)(@tangle-network/agent-interface@0.47.0)(@tangle-network/sandbox@0.21.1)': dependencies: '@tangle-network/agent-core': 0.6.1 '@tangle-network/agent-eval': 0.145.3 diff --git a/src/analyst-model-call.ts b/src/analyst-model-call.ts new file mode 100644 index 0000000..542570d --- /dev/null +++ b/src/analyst-model-call.ts @@ -0,0 +1,105 @@ +import { + callLlm, + costReceiptFromLlm, + costReceiptFromLlmError, + LlmCallError, + type LlmCallRequest, +} from '@tangle-network/agent-eval' +import type { createDspyRlmTraceEngine } from '@tangle-network/agent-eval/analyst' + +/** + * The engine's own model-call seam. Derived from the factory rather than + * imported, because agent-eval does not export the contract type by name and a + * hand-written copy would silently drift from the version installed here. + */ +type ExternalOptimizerModelCall = NonNullable[0]['call']> + +/** + * How much of a provider error body is retained as execution evidence. Enough + * to name the cause, bounded because the body is attacker-influenced and the + * proxy holds the whole execution record in memory. + */ +export const PROVIDER_ERROR_BODY_LIMIT = 2_000 + +/** + * The CLI's owned execution path for one admitted analyst model call. + * + * agent-eval 0.144.0 stopped accepting provider credentials: the caller owns + * execution and returns a typed result plus a cost receipt for every admitted + * call. This path is one OpenAI-compatible HTTP call through agent-eval's own + * `callLlm`. + * + * The callback always resolves. Rejecting loses the execution record and fails + * the whole optimizer attempt. + */ +export function createAnalystModelCall(opts: { + apiKey: string + baseUrl: string +}): ExternalOptimizerModelCall { + const { apiKey, baseUrl } = opts + return async ({ request, callId, signal }) => { + try { + const req = structuredClone(request) as LlmCallRequest + // callId is the ledger's stable identity for this one paid call, so it + // is the provider idempotency key: callLlm retries transient failures, + // and without it a lost-but-billed response is charged twice. + const response = await callLlm(req, { + apiKey, + baseUrl, + signal, + idempotencyKey: callId, + }) + return { + succeeded: true, + response, + receipt: costReceiptFromLlm(response), + execution: { + callId, + baseUrl, + requestedModel: req.model, + servedModel: response.servedModel ?? null, + finishReason: response.finishReason ?? null, + durationMs: response.durationMs, + }, + } + } catch (error) { + const err = error instanceof Error ? error : new Error(String(error)) + // The callback must resolve, so an abort cannot reach the proxy as a + // thrown AbortError and can never take its 504 branch. Naming the class + // in the failure text is what lets the bridge tell a cancelled call apart + // from a transient one it should retry. + const aborted = signal.aborted || err.name === 'AbortError' + const message = aborted ? `AbortError: ${err.message}` : err.message + // LlmCallError carries the provider's own reason (bad key, context + // length, unknown model). Without it the operator sees only the HTTP + // status. It stays in the execution evidence and out of the log line, + // because a gateway can echo request headers into an error body. + const detail = + err instanceof LlmCallError + ? { status: err.status, body: err.body.slice(0, PROVIDER_ERROR_BODY_LIMIT) } + : {} + return { + succeeded: false, + error: message, + // costReceiptFromLlmError recovers the provider receipt when the + // response completed but violated the contract; otherwise usage and + // cost stay explicitly unknown. + receipt: costReceiptFromLlmError(err) ?? { + model: request.model, + inputTokens: 0, + outputTokens: 0, + costUnknown: true, + usageUnknown: true, + }, + execution: { + callId, + baseUrl, + requestedModel: request.model, + aborted, + error: message, + ...detail, + }, + } + } + } +} diff --git a/src/cli.ts b/src/cli.ts index 7952e2a..cab88bd 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -89,7 +89,7 @@ import { import { fileRunContextSupervisorRunReader, isFileRunContextDir } from './supervisor-run-context.js' import { resolveRunWatchTarget, watchRunTarget } from './run-watch.js' import { createDspyRlmTraceEngine, type TraceAnalysisEngine } from '@tangle-network/agent-eval/analyst' -import { callLlm, costReceiptFromLlm, costReceiptFromLlmError, type LlmCallRequest } from '@tangle-network/agent-eval' +import { createAnalystModelCall } from './analyst-model-call.js' import type { OtlpSpan } from './otlp.js' import { serializeSpans, writeOtlpFile } from './otlp.js' import type { @@ -502,57 +502,7 @@ function buildAnalysisEngine(model: string, budgetUsd?: number): TraceAnalysisEn (tangleKey ? TANGLE_ROUTER_BASE_URL : 'https://api.openai.com/v1') const python = process.env.TRACES_PYTHON return createDspyRlmTraceEngine({ - // agent-eval 0.144.0 stopped accepting provider credentials: the caller - // owns the execution path and returns a typed result plus a cost receipt - // for every admitted call. This CLI's path is one OpenAI-compatible HTTP - // call through agent-eval's own `callLlm`. - call: async ({ request, callId, signal }) => { - try { - const req = structuredClone(request) as LlmCallRequest - // callId is the ledger's stable identity for this one paid call, so it - // is the provider idempotency key: callLlm retries transient failures, - // and without it a lost-but-billed response is charged twice. - const response = await callLlm(req, { - apiKey, - baseUrl, - signal, - idempotencyKey: callId, - }) - return { - succeeded: true, - response, - receipt: costReceiptFromLlm(response), - execution: { - baseUrl, - requestedModel: req.model, - servedModel: response.servedModel ?? null, - finishReason: response.finishReason ?? null, - durationMs: response.durationMs, - }, - } - } catch (error) { - const err = error instanceof Error ? error : new Error(String(error)) - return { - succeeded: false, - error: err.message, - // costReceiptFromLlmError recovers the provider receipt when the - // response completed but violated the contract; otherwise usage - // and cost stay explicitly unknown. - receipt: costReceiptFromLlmError(err) ?? { - model: request.model, - inputTokens: 0, - outputTokens: 0, - costUnknown: true, - usageUnknown: true, - }, - execution: { - baseUrl, - requestedModel: request.model, - error: err.message, - }, - } - } - }, + call: createAnalystModelCall({ apiKey, baseUrl }), callRef: `traces-cli:${baseUrl}#${model}`, recordExecution: (observation) => { analystLog( diff --git a/tests/analyst-model-call.test.ts b/tests/analyst-model-call.test.ts new file mode 100644 index 0000000..7288661 --- /dev/null +++ b/tests/analyst-model-call.test.ts @@ -0,0 +1,110 @@ +import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http' +import type { AddressInfo } from 'node:net' +import { afterEach, describe, expect, it } from 'vitest' +import { createAnalystModelCall, PROVIDER_ERROR_BODY_LIMIT } from '../src/analyst-model-call.js' + +type Handler = (req: IncomingMessage, res: ServerResponse) => void + +let server: Server | undefined + +async function startGateway(handler: Handler): Promise { + const created = createServer(handler) + server = created + await new Promise((resolve) => created.listen(0, '127.0.0.1', resolve)) + const { port } = created.address() as AddressInfo + return `http://127.0.0.1:${port}/v1` +} + +afterEach(async () => { + const running = server + server = undefined + if (running) await new Promise((resolve) => running.close(() => resolve())) +}) + +function chatRequest(model = 'test-model') { + return { + model, + messages: [{ role: 'user' as const, content: 'why did this run fail?' }], + } +} + +function callArgs(request: ReturnType, signal: AbortSignal) { + // Shape of one admitted call the loopback proxy hands to the execution owner. + return { request, callId: 'call-abc123', signal } as unknown as Parameters< + ReturnType + >[0] +} + +describe('analyst model call', () => { + it('returns a receipt and execution evidence, and sends callId as the idempotency key', async () => { + let seenIdempotencyKey: string | undefined + const baseUrl = await startGateway((req, res) => { + seenIdempotencyKey = req.headers['idempotency-key'] as string | undefined + res.writeHead(200, { 'content-type': 'application/json' }) + res.end( + JSON.stringify({ + id: 'chatcmpl-1', + object: 'chat.completion', + model: 'test-model', + choices: [{ index: 0, message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }], + usage: { prompt_tokens: 11, completion_tokens: 7, total_tokens: 18 }, + }), + ) + }) + + const call = createAnalystModelCall({ apiKey: 'test-key', baseUrl }) + const result = await call(callArgs(chatRequest(), new AbortController().signal)) + + expect(result.succeeded).toBe(true) + if (!result.succeeded) return + expect(result.response.content).toBe('ok') + expect(result.receipt.inputTokens).toBe(11) + expect(result.receipt.outputTokens).toBe(7) + // callId must reach the provider so a retried-but-already-billed call is + // not charged twice. + expect(seenIdempotencyKey).toBe('call-abc123') + const execution = result.execution as Record + expect(execution.callId).toBe('call-abc123') + expect(execution.servedModel).toBe('test-model') + expect(execution.finishReason).toBe('stop') + }) + + it('keeps the provider reason in execution evidence on a non-2xx response', async () => { + const baseUrl = await startGateway((_req, res) => { + res.writeHead(400, { 'content-type': 'application/json' }) + res.end(JSON.stringify({ error: { message: 'model not found: test-model', type: 'invalid_request_error' } })) + }) + + const call = createAnalystModelCall({ apiKey: 'test-key', baseUrl }) + const result = await call(callArgs(chatRequest(), new AbortController().signal)) + + expect(result.succeeded).toBe(false) + if (result.succeeded) return + const execution = result.execution as Record + expect(execution.status).toBe(400) + expect(String(execution.body)).toContain('model not found: test-model') + expect(String(execution.body).length).toBeLessThanOrEqual(PROVIDER_ERROR_BODY_LIMIT) + expect(execution.aborted).toBe(false) + // A failed call must never read as a free, measured call. + expect(result.receipt.costUnknown).toBe(true) + expect(result.receipt.usageUnknown).toBe(true) + }) + + it('marks an aborted call so it is distinguishable from a transient failure', async () => { + const controller = new AbortController() + const baseUrl = await startGateway(() => { + // Never responds: the abort is the only way this call ends. + controller.abort() + }) + + const call = createAnalystModelCall({ apiKey: 'test-key', baseUrl }) + const result = await call(callArgs(chatRequest(), controller.signal)) + + expect(result.succeeded).toBe(false) + if (result.succeeded) return + expect(result.error.startsWith('AbortError:')).toBe(true) + const execution = result.execution as Record + expect(execution.aborted).toBe(true) + expect(execution.callId).toBe('call-abc123') + }) +}) From da25c8fad575952413264c5f7c2a33cf68cb6844 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Wed, 12 Aug 2026 20:24:41 -0600 Subject: [PATCH 6/6] fix(analyst): key the cancellation marker on the caller signal only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit callLlm aborts an internal controller to enforce its own per-attempt timeout, so a plain provider timeout rethrows a DOMException named AbortError while the caller signal stays clear. Reading the error name marked that timeout as a cancellation, which is the one state the bridge does not retry — the inverse of what the marker is for. Reproduced against agent-eval 0.145.3: a gateway that never answers gives err.name 'AbortError' with signal.aborted false. Also raise engines.node to 22.13.0, the floor agent-runtime 0.133.2 declares. --- package.json | 2 +- src/analyst-model-call.ts | 8 +++++++- tests/analyst-model-call.test.ts | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 91ce253..d8d6ec6 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "README.md" ], "engines": { - "node": ">=22" + "node": ">=22.13.0" }, "scripts": { "dev": "tsx src/cli.ts", diff --git a/src/analyst-model-call.ts b/src/analyst-model-call.ts index 542570d..d90e1ef 100644 --- a/src/analyst-model-call.ts +++ b/src/analyst-model-call.ts @@ -68,7 +68,13 @@ export function createAnalystModelCall(opts: { // thrown AbortError and can never take its 504 branch. Naming the class // in the failure text is what lets the bridge tell a cancelled call apart // from a transient one it should retry. - const aborted = signal.aborted || err.name === 'AbortError' + // + // Only the caller's signal proves a cancellation. `callLlm` aborts an + // internal controller to enforce its own per-attempt timeout, so a plain + // provider timeout also surfaces as an `AbortError` while this signal + // stays clear. Reading the error name here would mark that timeout + // uncancellable and stop the bridge retrying a call it should retry. + const aborted = signal.aborted const message = aborted ? `AbortError: ${err.message}` : err.message // LlmCallError carries the provider's own reason (bad key, context // length, unknown model). Without it the operator sees only the HTTP diff --git a/tests/analyst-model-call.test.ts b/tests/analyst-model-call.test.ts index 7288661..5fba11f 100644 --- a/tests/analyst-model-call.test.ts +++ b/tests/analyst-model-call.test.ts @@ -90,6 +90,25 @@ describe('analyst model call', () => { expect(result.receipt.usageUnknown).toBe(true) }) + it('does not mark a provider timeout as a cancellation', async () => { + const baseUrl = await startGateway(() => { + // Never responds, so callLlm's own per-attempt timeout fires. + }) + + const call = createAnalystModelCall({ apiKey: 'test-key', baseUrl }) + // callLlm aborts an internal controller to enforce this timeout, so the + // error arrives as an AbortError even though nobody cancelled the call. + const request = { ...chatRequest(), timeoutMs: 250 } + const result = await call(callArgs(request, new AbortController().signal)) + + expect(result.succeeded).toBe(false) + if (result.succeeded) return + // The bridge retries a transient failure and gives up on a cancelled one, + // so a timeout must not carry the cancellation marker. + expect(result.error.startsWith('AbortError:')).toBe(false) + expect((result.execution as Record).aborted).toBe(false) + }) + it('marks an aborted call so it is distinguishable from a transient failure', async () => { const controller = new AbortController() const baseUrl = await startGateway(() => {