@electric-ax/agents-server-conformance-tests 0.1.8 → 0.1.10

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/dist/index.cjs CHANGED
@@ -2904,25 +2904,51 @@ function runElectricAgentsConformanceTests(config) {
2904
2904
  const block = result.content[0];
2905
2905
  return block?.type === `text` && block.text ? block.text : ``;
2906
2906
  }
2907
+ async function makeSandbox(workingDirectory) {
2908
+ const { unrestrictedSandbox } = await import(`../../agents-runtime/src/sandbox/unrestricted`);
2909
+ return unrestrictedSandbox({ workingDirectory });
2910
+ }
2907
2911
  (0, vitest.test)(`bash tool captures stdout and stderr`, async () => {
2908
2912
  const { createBashTool } = await import(`../../agents-runtime/src/tools`);
2909
- const tool = createBashTool(`/tmp`);
2910
- const result = await tool.execute(`test-tc`, { command: `echo "hello" && echo "error" >&2` });
2911
- (0, vitest.expect)(firstText(result)).toContain(`hello`);
2912
- (0, vitest.expect)(firstText(result)).toContain(`error`);
2913
- (0, vitest.expect)(result.details.exitCode).toBe(0);
2913
+ const sandbox = await makeSandbox(`/tmp`);
2914
+ try {
2915
+ const tool = createBashTool(sandbox);
2916
+ const result = await tool.execute(`test-tc`, { command: `echo "hello" && echo "error" >&2` });
2917
+ (0, vitest.expect)(firstText(result)).toContain(`hello`);
2918
+ (0, vitest.expect)(firstText(result)).toContain(`error`);
2919
+ (0, vitest.expect)(result.details.exitCode).toBe(0);
2920
+ } finally {
2921
+ await sandbox.dispose();
2922
+ }
2914
2923
  });
2915
2924
  (0, vitest.test)(`bash tool enforces timeout`, async () => {
2916
2925
  const { createBashTool } = await import(`../../agents-runtime/src/tools`);
2917
- const tool = createBashTool(`/tmp`);
2918
- const result = await tool.execute(`test-tc`, { command: `sleep 60` });
2919
- (0, vitest.expect)(result.details.timedOut).toBe(true);
2926
+ const sandbox = await makeSandbox(`/tmp`);
2927
+ try {
2928
+ const tool = createBashTool(sandbox);
2929
+ const result = await tool.execute(`test-tc`, { command: `sleep 60` });
2930
+ (0, vitest.expect)(result.details.timedOut).toBe(true);
2931
+ } finally {
2932
+ await sandbox.dispose();
2933
+ }
2920
2934
  }, 35e3);
2921
2935
  (0, vitest.test)(`read_file rejects paths outside working directory`, async () => {
2922
2936
  const { createReadFileTool } = await import(`../../agents-runtime/src/tools`);
2923
- const tool = createReadFileTool(`/tmp/test-workdir`);
2924
- const result = await tool.execute(`test-tc`, { path: `../../etc/passwd` });
2925
- (0, vitest.expect)(firstText(result)).toContain(`outside the working directory`);
2937
+ const fs = await import(`node:fs/promises`);
2938
+ const dir = `/tmp/test-workdir-${Date.now()}`;
2939
+ await fs.mkdir(dir, { recursive: true });
2940
+ const sandbox = await makeSandbox(dir);
2941
+ try {
2942
+ const tool = createReadFileTool(sandbox);
2943
+ const result = await tool.execute(`test-tc`, { path: `../../etc/passwd` });
2944
+ (0, vitest.expect)(firstText(result)).toContain(`outside the working directory`);
2945
+ } finally {
2946
+ await sandbox.dispose();
2947
+ await fs.rm(dir, {
2948
+ recursive: true,
2949
+ force: true
2950
+ });
2951
+ }
2926
2952
  });
2927
2953
  (0, vitest.test)(`read_file rejects binary files`, async () => {
2928
2954
  const { createReadFileTool } = await import(`../../agents-runtime/src/tools`);
@@ -2937,10 +2963,15 @@ function runElectricAgentsConformanceTests(config) {
2937
2963
  2,
2938
2964
  255
2939
2965
  ]));
2940
- const tool = createReadFileTool(dir);
2941
- const result = await tool.execute(`test-tc`, { path: `test.bin` });
2942
- (0, vitest.expect)(firstText(result)).toContain(`binary file`);
2943
- await fs.rm(dir, { recursive: true });
2966
+ const sandbox = await makeSandbox(dir);
2967
+ try {
2968
+ const tool = createReadFileTool(sandbox);
2969
+ const result = await tool.execute(`test-tc`, { path: `test.bin` });
2970
+ (0, vitest.expect)(firstText(result)).toContain(`binary file`);
2971
+ } finally {
2972
+ await sandbox.dispose();
2973
+ await fs.rm(dir, { recursive: true });
2974
+ }
2944
2975
  });
2945
2976
  (0, vitest.test)(`read_file rejects oversized files`, async () => {
2946
2977
  const { createReadFileTool } = await import(`../../agents-runtime/src/tools`);
@@ -2950,10 +2981,15 @@ function runElectricAgentsConformanceTests(config) {
2950
2981
  await fs.mkdir(dir, { recursive: true });
2951
2982
  const bigPath = path.join(dir, `big.txt`);
2952
2983
  await fs.writeFile(bigPath, `x`.repeat(600 * 1024));
2953
- const tool = createReadFileTool(dir);
2954
- const result = await tool.execute(`test-tc`, { path: `big.txt` });
2955
- (0, vitest.expect)(firstText(result)).toContain(`too large`);
2956
- await fs.rm(dir, { recursive: true });
2984
+ const sandbox = await makeSandbox(dir);
2985
+ try {
2986
+ const tool = createReadFileTool(sandbox);
2987
+ const result = await tool.execute(`test-tc`, { path: `big.txt` });
2988
+ (0, vitest.expect)(firstText(result)).toContain(`too large`);
2989
+ } finally {
2990
+ await sandbox.dispose();
2991
+ await fs.rm(dir, { recursive: true });
2992
+ }
2957
2993
  });
2958
2994
  (0, vitest.test)(`web_search tool has correct interface`, async () => {
2959
2995
  const { braveSearchTool } = await import(`../../agents-runtime/src/tools`);
@@ -2961,9 +2997,15 @@ function runElectricAgentsConformanceTests(config) {
2961
2997
  (0, vitest.expect)(typeof braveSearchTool.execute).toBe(`function`);
2962
2998
  });
2963
2999
  (0, vitest.test)(`fetch_url tool has correct interface`, async () => {
2964
- const { fetchUrlTool } = await import(`../../agents-runtime/src/tools`);
2965
- (0, vitest.expect)(fetchUrlTool.name).toBe(`fetch_url`);
2966
- (0, vitest.expect)(typeof fetchUrlTool.execute).toBe(`function`);
3000
+ const { createFetchUrlTool } = await import(`../../agents-runtime/src/tools`);
3001
+ const sandbox = await makeSandbox(`/tmp`);
3002
+ try {
3003
+ const tool = createFetchUrlTool(sandbox);
3004
+ (0, vitest.expect)(tool.name).toBe(`fetch_url`);
3005
+ (0, vitest.expect)(typeof tool.execute).toBe(`function`);
3006
+ } finally {
3007
+ await sandbox.dispose();
3008
+ }
2967
3009
  });
2968
3010
  });
2969
3011
  (0, vitest.describe)(`Electric Agents Send — State Protocol Format`, () => {
package/dist/index.js CHANGED
@@ -2880,25 +2880,51 @@ function runElectricAgentsConformanceTests(config) {
2880
2880
  const block = result.content[0];
2881
2881
  return block?.type === `text` && block.text ? block.text : ``;
2882
2882
  }
2883
+ async function makeSandbox(workingDirectory) {
2884
+ const { unrestrictedSandbox } = await import(`../../agents-runtime/src/sandbox/unrestricted`);
2885
+ return unrestrictedSandbox({ workingDirectory });
2886
+ }
2883
2887
  test(`bash tool captures stdout and stderr`, async () => {
2884
2888
  const { createBashTool } = await import(`../../agents-runtime/src/tools`);
2885
- const tool = createBashTool(`/tmp`);
2886
- const result = await tool.execute(`test-tc`, { command: `echo "hello" && echo "error" >&2` });
2887
- expect(firstText(result)).toContain(`hello`);
2888
- expect(firstText(result)).toContain(`error`);
2889
- expect(result.details.exitCode).toBe(0);
2889
+ const sandbox = await makeSandbox(`/tmp`);
2890
+ try {
2891
+ const tool = createBashTool(sandbox);
2892
+ const result = await tool.execute(`test-tc`, { command: `echo "hello" && echo "error" >&2` });
2893
+ expect(firstText(result)).toContain(`hello`);
2894
+ expect(firstText(result)).toContain(`error`);
2895
+ expect(result.details.exitCode).toBe(0);
2896
+ } finally {
2897
+ await sandbox.dispose();
2898
+ }
2890
2899
  });
2891
2900
  test(`bash tool enforces timeout`, async () => {
2892
2901
  const { createBashTool } = await import(`../../agents-runtime/src/tools`);
2893
- const tool = createBashTool(`/tmp`);
2894
- const result = await tool.execute(`test-tc`, { command: `sleep 60` });
2895
- expect(result.details.timedOut).toBe(true);
2902
+ const sandbox = await makeSandbox(`/tmp`);
2903
+ try {
2904
+ const tool = createBashTool(sandbox);
2905
+ const result = await tool.execute(`test-tc`, { command: `sleep 60` });
2906
+ expect(result.details.timedOut).toBe(true);
2907
+ } finally {
2908
+ await sandbox.dispose();
2909
+ }
2896
2910
  }, 35e3);
2897
2911
  test(`read_file rejects paths outside working directory`, async () => {
2898
2912
  const { createReadFileTool } = await import(`../../agents-runtime/src/tools`);
2899
- const tool = createReadFileTool(`/tmp/test-workdir`);
2900
- const result = await tool.execute(`test-tc`, { path: `../../etc/passwd` });
2901
- expect(firstText(result)).toContain(`outside the working directory`);
2913
+ const fs = await import(`node:fs/promises`);
2914
+ const dir = `/tmp/test-workdir-${Date.now()}`;
2915
+ await fs.mkdir(dir, { recursive: true });
2916
+ const sandbox = await makeSandbox(dir);
2917
+ try {
2918
+ const tool = createReadFileTool(sandbox);
2919
+ const result = await tool.execute(`test-tc`, { path: `../../etc/passwd` });
2920
+ expect(firstText(result)).toContain(`outside the working directory`);
2921
+ } finally {
2922
+ await sandbox.dispose();
2923
+ await fs.rm(dir, {
2924
+ recursive: true,
2925
+ force: true
2926
+ });
2927
+ }
2902
2928
  });
2903
2929
  test(`read_file rejects binary files`, async () => {
2904
2930
  const { createReadFileTool } = await import(`../../agents-runtime/src/tools`);
@@ -2913,10 +2939,15 @@ function runElectricAgentsConformanceTests(config) {
2913
2939
  2,
2914
2940
  255
2915
2941
  ]));
2916
- const tool = createReadFileTool(dir);
2917
- const result = await tool.execute(`test-tc`, { path: `test.bin` });
2918
- expect(firstText(result)).toContain(`binary file`);
2919
- await fs.rm(dir, { recursive: true });
2942
+ const sandbox = await makeSandbox(dir);
2943
+ try {
2944
+ const tool = createReadFileTool(sandbox);
2945
+ const result = await tool.execute(`test-tc`, { path: `test.bin` });
2946
+ expect(firstText(result)).toContain(`binary file`);
2947
+ } finally {
2948
+ await sandbox.dispose();
2949
+ await fs.rm(dir, { recursive: true });
2950
+ }
2920
2951
  });
2921
2952
  test(`read_file rejects oversized files`, async () => {
2922
2953
  const { createReadFileTool } = await import(`../../agents-runtime/src/tools`);
@@ -2926,10 +2957,15 @@ function runElectricAgentsConformanceTests(config) {
2926
2957
  await fs.mkdir(dir, { recursive: true });
2927
2958
  const bigPath = path.join(dir, `big.txt`);
2928
2959
  await fs.writeFile(bigPath, `x`.repeat(600 * 1024));
2929
- const tool = createReadFileTool(dir);
2930
- const result = await tool.execute(`test-tc`, { path: `big.txt` });
2931
- expect(firstText(result)).toContain(`too large`);
2932
- await fs.rm(dir, { recursive: true });
2960
+ const sandbox = await makeSandbox(dir);
2961
+ try {
2962
+ const tool = createReadFileTool(sandbox);
2963
+ const result = await tool.execute(`test-tc`, { path: `big.txt` });
2964
+ expect(firstText(result)).toContain(`too large`);
2965
+ } finally {
2966
+ await sandbox.dispose();
2967
+ await fs.rm(dir, { recursive: true });
2968
+ }
2933
2969
  });
2934
2970
  test(`web_search tool has correct interface`, async () => {
2935
2971
  const { braveSearchTool } = await import(`../../agents-runtime/src/tools`);
@@ -2937,9 +2973,15 @@ function runElectricAgentsConformanceTests(config) {
2937
2973
  expect(typeof braveSearchTool.execute).toBe(`function`);
2938
2974
  });
2939
2975
  test(`fetch_url tool has correct interface`, async () => {
2940
- const { fetchUrlTool } = await import(`../../agents-runtime/src/tools`);
2941
- expect(fetchUrlTool.name).toBe(`fetch_url`);
2942
- expect(typeof fetchUrlTool.execute).toBe(`function`);
2976
+ const { createFetchUrlTool } = await import(`../../agents-runtime/src/tools`);
2977
+ const sandbox = await makeSandbox(`/tmp`);
2978
+ try {
2979
+ const tool = createFetchUrlTool(sandbox);
2980
+ expect(tool.name).toBe(`fetch_url`);
2981
+ expect(typeof tool.execute).toBe(`function`);
2982
+ } finally {
2983
+ await sandbox.dispose();
2984
+ }
2943
2985
  });
2944
2986
  });
2945
2987
  describe(`Electric Agents Send — State Protocol Format`, () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electric-ax/agents-server-conformance-tests",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Conformance test suite for Electric Agents server implementations",
5
5
  "author": "Durable Stream contributors",
6
6
  "license": "Apache-2.0",
@@ -34,8 +34,8 @@
34
34
  "dist"
35
35
  ],
36
36
  "dependencies": {
37
- "@durable-streams/client": "https://pkg.pr.new/durable-streams/durable-streams/@durable-streams/client@5d5c217",
38
- "@electric-sql/client": "^1.5.19",
37
+ "@durable-streams/client": "^0.2.6",
38
+ "@electric-sql/client": "^1.5.20",
39
39
  "fast-check": "^4.6.0",
40
40
  "vitest": "^4.1.0"
41
41
  },
@@ -43,7 +43,7 @@
43
43
  "@mariozechner/pi-agent-core": "^0.70.2",
44
44
  "tsdown": "^0.9.0",
45
45
  "typescript": "^5.0.0",
46
- "@electric-ax/agents-server": "0.4.11"
46
+ "@electric-ax/agents-server": "0.4.15"
47
47
  },
48
48
  "engines": {
49
49
  "node": ">=18.0.0"