@tangle-network/agent-bench 0.4.3 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.5
|
|
4
|
+
|
|
5
|
+
- Allow the zero-model Pier proof to complete a cold separate-verifier image build before its task and overall execution deadlines.
|
|
6
|
+
- Consume Runtime 0.107.5 with Eval 0.133.3, Interface 0.36.0, Knowledge 6.1.5, and Sandbox 0.15.1.
|
|
7
|
+
|
|
8
|
+
## 0.4.4
|
|
9
|
+
|
|
10
|
+
- Consume Runtime 0.107.2 and Sandbox 0.15.0 with the current Eval, Interface, and Knowledge packages.
|
|
11
|
+
- Publish fake Pier terminal results atomically so the full test suite cannot observe partial JSON.
|
|
12
|
+
|
|
3
13
|
## 0.4.3
|
|
4
14
|
|
|
5
15
|
- Consume Runtime 0.107.1 with Eval 0.133.0, Interface 0.36.0, and Knowledge 6.1.2.
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-bench",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Benchmark adapters and execution for agent-runtime across coding, tool-use, RAG, memory, browser, and terminal tasks.",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/tangle-network/agent-runtime.git",
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@tangle-network/agent-eval": "0.133.
|
|
28
|
+
"@tangle-network/agent-eval": "0.133.3",
|
|
29
29
|
"@tangle-network/agent-interface": "0.36.0",
|
|
30
|
-
"@tangle-network/agent-knowledge": "6.1.
|
|
31
|
-
"@tangle-network/sandbox": "0.
|
|
32
|
-
"@tangle-network/agent-runtime": "0.107.
|
|
30
|
+
"@tangle-network/agent-knowledge": "6.1.5",
|
|
31
|
+
"@tangle-network/sandbox": "0.15.1",
|
|
32
|
+
"@tangle-network/agent-runtime": "0.107.5"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@arethetypeswrong/cli": "0.18.5",
|
|
@@ -435,7 +435,7 @@ ${proofArm === 'success' ? "(task / 'src/status.txt').write_text('ready\\nowner=
|
|
|
435
435
|
workspace: taskWorkspace,
|
|
436
436
|
evaluatorTaskContainer: container,
|
|
437
437
|
limits: {
|
|
438
|
-
timeoutMs:
|
|
438
|
+
timeoutMs: 600_000,
|
|
439
439
|
maxSteps: 8,
|
|
440
440
|
maxModelCalls: 0,
|
|
441
441
|
maxInputTokens: 0,
|
|
@@ -85,18 +85,20 @@ test('the Pier result wait does not add time beyond an expired deadline', async
|
|
|
85
85
|
await chmod(fakeDocker, 0o700)
|
|
86
86
|
await writeFile(
|
|
87
87
|
supervisorPath,
|
|
88
|
-
`import { createReadStream } from 'node:fs'
|
|
89
|
-
import { writeFileSync } from 'node:fs'
|
|
88
|
+
`import { createReadStream, renameSync, writeFileSync } from 'node:fs'
|
|
90
89
|
import path from 'node:path'
|
|
91
90
|
const directory = process.argv[2]
|
|
92
91
|
process.on('SIGTERM', () => {
|
|
93
|
-
|
|
92
|
+
const target = path.join(directory, 'terminal.json')
|
|
93
|
+
const temporary = path.join(directory, '.terminal.json.tmp')
|
|
94
|
+
writeFileSync(temporary, JSON.stringify({
|
|
94
95
|
schemaVersion: 1,
|
|
95
96
|
kind: 'pier-trial-terminal',
|
|
96
97
|
status: 'stopped',
|
|
97
98
|
processExited: true,
|
|
98
99
|
containersRemoved: true,
|
|
99
100
|
}))
|
|
101
|
+
renameSync(temporary, target)
|
|
100
102
|
process.exit(0)
|
|
101
103
|
})
|
|
102
104
|
for await (const _chunk of createReadStream('', { fd: 3 })) {}
|
|
@@ -156,7 +158,7 @@ test('the supervisor receives only launch data and no inherited evaluator enviro
|
|
|
156
158
|
await chmod(fakeDocker, 0o700)
|
|
157
159
|
await writeFile(
|
|
158
160
|
supervisorPath,
|
|
159
|
-
`import { createReadStream, writeFileSync } from 'node:fs'
|
|
161
|
+
`import { createReadStream, renameSync, writeFileSync } from 'node:fs'
|
|
160
162
|
import path from 'node:path'
|
|
161
163
|
const chunks = []
|
|
162
164
|
for await (const chunk of createReadStream('', { fd: 3 })) chunks.push(Buffer.from(chunk))
|
|
@@ -165,7 +167,9 @@ const isolated = process.env.PIER_SUPERVISOR_MODE === 'explicit' &&
|
|
|
165
167
|
process.env.PIER_PARENT_SECRET === undefined &&
|
|
166
168
|
launch.env.PIER_PARENT_SECRET === undefined &&
|
|
167
169
|
launch.env.PIER_CHILD_SECRET === 'child-only'
|
|
168
|
-
|
|
170
|
+
const target = path.join(process.argv[2], 'terminal.json')
|
|
171
|
+
const temporary = path.join(process.argv[2], '.terminal.json.tmp')
|
|
172
|
+
writeFileSync(temporary, JSON.stringify({
|
|
169
173
|
schemaVersion: 1,
|
|
170
174
|
kind: 'pier-trial-terminal',
|
|
171
175
|
status: isolated ? 'completed' : 'failed',
|
|
@@ -173,6 +177,7 @@ writeFileSync(path.join(process.argv[2], 'terminal.json'), JSON.stringify({
|
|
|
173
177
|
containersRemoved: true,
|
|
174
178
|
...(isolated ? {} : { error: 'supervisor inherited evaluator environment' }),
|
|
175
179
|
}))
|
|
180
|
+
renameSync(temporary, target)
|
|
176
181
|
`,
|
|
177
182
|
)
|
|
178
183
|
const controller = new FilePierCandidateTrialController({
|
|
@@ -224,10 +229,12 @@ test('terminal acknowledgements reject unknown fields', async () => {
|
|
|
224
229
|
await chmod(fakeDocker, 0o700)
|
|
225
230
|
await writeFile(
|
|
226
231
|
supervisorPath,
|
|
227
|
-
`import { createReadStream, writeFileSync } from 'node:fs'
|
|
232
|
+
`import { createReadStream, renameSync, writeFileSync } from 'node:fs'
|
|
228
233
|
import path from 'node:path'
|
|
229
234
|
for await (const _chunk of createReadStream('', { fd: 3 })) {}
|
|
230
|
-
|
|
235
|
+
const target = path.join(process.argv[2], 'terminal.json')
|
|
236
|
+
const temporary = path.join(process.argv[2], '.terminal.json.tmp')
|
|
237
|
+
writeFileSync(temporary, JSON.stringify({
|
|
231
238
|
schemaVersion: 1,
|
|
232
239
|
kind: 'pier-trial-terminal',
|
|
233
240
|
status: 'completed',
|
|
@@ -235,6 +242,7 @@ writeFileSync(path.join(process.argv[2], 'terminal.json'), JSON.stringify({
|
|
|
235
242
|
containersRemoved: true,
|
|
236
243
|
containerRemoved: true,
|
|
237
244
|
}))
|
|
245
|
+
renameSync(temporary, target)
|
|
238
246
|
`,
|
|
239
247
|
)
|
|
240
248
|
const controller = new FilePierCandidateTrialController({
|
|
@@ -3,11 +3,25 @@ import { tmpdir } from 'node:os'
|
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
import { afterAll, describe, expect, it } from 'vitest'
|
|
5
5
|
import { runSupervisorShim, supervisorDriverKillGraceMs } from './arms.ts'
|
|
6
|
-
import {
|
|
6
|
+
import { ABORT_RC, run } from './proc.ts'
|
|
7
7
|
|
|
8
8
|
const dirs: string[] = []
|
|
9
9
|
const workerPids: number[] = []
|
|
10
10
|
|
|
11
|
+
async function waitForFile(path: string, timeoutMs = 10_000): Promise<void> {
|
|
12
|
+
const deadline = Date.now() + timeoutMs
|
|
13
|
+
while (Date.now() < deadline) {
|
|
14
|
+
try {
|
|
15
|
+
await access(path)
|
|
16
|
+
return
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error
|
|
19
|
+
}
|
|
20
|
+
await new Promise((resolve) => setTimeout(resolve, 10))
|
|
21
|
+
}
|
|
22
|
+
throw new Error(`timed out waiting for ${path}`)
|
|
23
|
+
}
|
|
24
|
+
|
|
11
25
|
afterAll(async () => {
|
|
12
26
|
for (const pid of workerPids) {
|
|
13
27
|
try {
|
|
@@ -122,6 +136,7 @@ export default function fakeExtension(pi) {
|
|
|
122
136
|
writeFileSync(join(runDir, 'state.json'), JSON.stringify({ status: 'running' }))
|
|
123
137
|
appendFileSync(join(runDir, 'journal.jsonl'), JSON.stringify({ kind: 'spawned', id, label: 'root' }) + '\\n')
|
|
124
138
|
appendFileSync(join(runDir, 'journal.jsonl'), JSON.stringify({ kind: 'spawned', id: id + ':s1', parent: id, label: 'w-0' }) + '\\n')
|
|
139
|
+
writeFileSync(join(ctx.cwd, 'outer-driver-ready.txt'), 'ready')
|
|
125
140
|
return text('spawned supervisor ' + id)
|
|
126
141
|
},
|
|
127
142
|
})
|
|
@@ -140,10 +155,11 @@ export default function fakeExtension(pi) {
|
|
|
140
155
|
`)
|
|
141
156
|
|
|
142
157
|
const cancelTimeoutMs = 1_500
|
|
143
|
-
const
|
|
158
|
+
const controller = new AbortController()
|
|
159
|
+
const resultPromise = run(process.execPath, [
|
|
144
160
|
'--import', 'tsx', runSupervisorShim, extension, workspace, params,
|
|
145
161
|
], {
|
|
146
|
-
|
|
162
|
+
signal: controller.signal,
|
|
147
163
|
killGraceMs: supervisorDriverKillGraceMs({
|
|
148
164
|
DRIVER_CANCEL_TIMEOUT_MS: String(cancelTimeoutMs),
|
|
149
165
|
}),
|
|
@@ -154,9 +170,19 @@ export default function fakeExtension(pi) {
|
|
|
154
170
|
DRIVER_CANCEL_TIMEOUT_MS: String(cancelTimeoutMs),
|
|
155
171
|
},
|
|
156
172
|
})
|
|
173
|
+
try {
|
|
174
|
+
await waitForFile(join(workspace, 'outer-driver-ready.txt'))
|
|
175
|
+
} catch (error) {
|
|
176
|
+
controller.abort()
|
|
177
|
+
await resultPromise
|
|
178
|
+
throw error
|
|
179
|
+
}
|
|
180
|
+
controller.abort()
|
|
181
|
+
const result = await resultPromise
|
|
157
182
|
|
|
158
|
-
expect(result.code, result.stdout + result.stderr).toBe(
|
|
159
|
-
expect(result.
|
|
183
|
+
expect(result.code, result.stdout + result.stderr).toBe(ABORT_RC)
|
|
184
|
+
expect(result.aborted).toBe(true)
|
|
185
|
+
expect(result.timedOut).toBe(false)
|
|
160
186
|
expect(await readFile(join(workspace, 'outer-cancel-settled.txt'), 'utf8')).toBe('settled')
|
|
161
187
|
expect(JSON.parse(await readFile(join(workspace, '.loops', 'supervisor', 'sup-2-fake34', 'state.json'), 'utf8')))
|
|
162
188
|
.toMatchObject({ status: 'cancelled' })
|
|
@@ -170,10 +196,10 @@ export default function fakeExtension(pi) {
|
|
|
170
196
|
const extension = join(dir, 'fake-extension.mjs')
|
|
171
197
|
await mkdir(workspace)
|
|
172
198
|
await writeFile(params, '{}')
|
|
173
|
-
const workerScript = `const fs=require('node:fs'); const marker=process.argv[1]; process.on('SIGTERM',()=>setTimeout(()=>{fs.writeFileSync(marker,'clean'); process.exit(0)},30)); setInterval(()=>{},1000)`
|
|
199
|
+
const workerScript = `const fs=require('node:fs'); const marker=process.argv[1]; const ready=process.argv[2]; process.on('SIGTERM',()=>setTimeout(()=>{fs.writeFileSync(marker,'clean'); process.exit(0)},30)); fs.writeFileSync(ready,'ready'); setInterval(()=>{},1000)`
|
|
174
200
|
await writeFile(extension, `
|
|
175
201
|
import { spawn } from 'node:child_process'
|
|
176
|
-
import { appendFileSync, mkdirSync, writeFileSync } from 'node:fs'
|
|
202
|
+
import { appendFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs'
|
|
177
203
|
import { join } from 'node:path'
|
|
178
204
|
|
|
179
205
|
const id = 'sup-3-signal56'
|
|
@@ -188,11 +214,13 @@ export default function fakeExtension(pi) {
|
|
|
188
214
|
writeFileSync(join(runDir, 'state.json'), JSON.stringify({ status: 'running' }))
|
|
189
215
|
appendFileSync(join(runDir, 'journal.jsonl'), JSON.stringify({ kind: 'spawned', id, label: 'root' }) + '\\n')
|
|
190
216
|
appendFileSync(join(runDir, 'journal.jsonl'), JSON.stringify({ kind: 'spawned', id: id + ':s1', parent: id, label: 'w-0' }) + '\\n')
|
|
191
|
-
|
|
217
|
+
const readyPath = join(ctx.cwd, 'signal-worker-ready.txt')
|
|
218
|
+
child = spawn(process.execPath, ['-e', ${JSON.stringify(workerScript)}, join(ctx.cwd, 'signal-worker-cleaned.txt'), readyPath], {
|
|
192
219
|
detached: true,
|
|
193
220
|
stdio: 'ignore',
|
|
194
221
|
})
|
|
195
222
|
writeFileSync(join(ctx.cwd, 'signal-worker.pid'), String(child.pid))
|
|
223
|
+
while (!existsSync(readyPath)) await new Promise((resolve) => setTimeout(resolve, 5))
|
|
196
224
|
writeFileSync(join(ctx.cwd, 'spawn-entered.txt'), 'entered')
|
|
197
225
|
await new Promise((resolve) => setTimeout(resolve, 30_000))
|
|
198
226
|
return text('spawned supervisor ' + id)
|
|
@@ -214,10 +242,11 @@ export default function fakeExtension(pi) {
|
|
|
214
242
|
`)
|
|
215
243
|
|
|
216
244
|
const cancelTimeoutMs = 2_000
|
|
217
|
-
const
|
|
245
|
+
const controller = new AbortController()
|
|
246
|
+
const resultPromise = run(process.execPath, [
|
|
218
247
|
'--import', 'tsx', runSupervisorShim, extension, workspace, params,
|
|
219
248
|
], {
|
|
220
|
-
|
|
249
|
+
signal: controller.signal,
|
|
221
250
|
killGraceMs: supervisorDriverKillGraceMs({
|
|
222
251
|
DRIVER_CANCEL_TIMEOUT_MS: String(cancelTimeoutMs),
|
|
223
252
|
}),
|
|
@@ -228,11 +257,21 @@ export default function fakeExtension(pi) {
|
|
|
228
257
|
DRIVER_CANCEL_TIMEOUT_MS: String(cancelTimeoutMs),
|
|
229
258
|
},
|
|
230
259
|
})
|
|
260
|
+
try {
|
|
261
|
+
await waitForFile(join(workspace, 'spawn-entered.txt'))
|
|
262
|
+
} catch (error) {
|
|
263
|
+
controller.abort()
|
|
264
|
+
await resultPromise
|
|
265
|
+
throw error
|
|
266
|
+
}
|
|
267
|
+
controller.abort()
|
|
268
|
+
const result = await resultPromise
|
|
231
269
|
const workerPid = Number(await readFile(join(workspace, 'signal-worker.pid'), 'utf8'))
|
|
232
270
|
workerPids.push(workerPid)
|
|
233
271
|
|
|
234
|
-
expect(result.code, result.stdout + result.stderr).toBe(
|
|
235
|
-
expect(result.
|
|
272
|
+
expect(result.code, result.stdout + result.stderr).toBe(ABORT_RC)
|
|
273
|
+
expect(result.aborted).toBe(true)
|
|
274
|
+
expect(result.timedOut).toBe(false)
|
|
236
275
|
expect(await readFile(join(workspace, 'spawn-entered.txt'), 'utf8')).toBe('entered')
|
|
237
276
|
expect(await readFile(join(workspace, 'signal-worker-cleaned.txt'), 'utf8')).toBe('clean')
|
|
238
277
|
expect(await readFile(join(workspace, 'signal-cancel-settled.txt'), 'utf8')).toBe('settled')
|