Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import annotations

import json
import re
from pathlib import Path
from typing import get_args
Expand Down Expand Up @@ -165,13 +166,31 @@ def test_config_schema_names_every_tool_type_discriminator():
assert not missing, f"config-schema.md does not document tool type(s): {missing}"


def _contains_builtin_tool_entry(value: object) -> bool:
if isinstance(value, dict):
if value.get("type") == "builtin":
return True
return any(_contains_builtin_tool_entry(v) for v in value.values())
if isinstance(value, list):
return any(_contains_builtin_tool_entry(item) for item in value)
return False


def test_no_json_example_writes_a_builtin_tool_entry():
# The `builtin` arm survives only as legacy dual-read. The authoring agent copies these
# examples verbatim, so an example that still writes one would keep producing configs the
# resolver has to ignore.
content = _file("references/config-schema.md").content
for block in re.findall(r"```json\n(.*?)```", content, flags=re.DOTALL):
assert '"type": "builtin"' not in block, (
blocks = re.findall(r"```json\n(.*?)```", content, flags=re.DOTALL)
assert blocks, "config-schema.md must contain at least one JSON example"
for block in blocks:
try:
parsed = json.loads(block)
except json.JSONDecodeError as exc:
raise AssertionError(
f"config-schema.md has a json fence that is not valid JSON: {exc}"
) from exc
assert not _contains_builtin_tool_entry(parsed), (
"a JSON example in config-schema.md still writes a builtin tool entry"
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,11 @@ async def resolve(self, tools):


async def test_a_bare_tool_name_string_is_ignored_too():
# `coerce_tool_config` turns a bare string into a BuiltinToolConfig.
resolved = await ToolResolver().resolve(coerce_tool_configs(["read"]))
# `coerce_tool_configs` turns a bare string into a BuiltinToolConfig.
parsed = coerce_tool_configs(["read"])
assert parsed.tool_configs == [BuiltinToolConfig(name="read")]

resolved = await ToolResolver().resolve(parsed.tool_configs)

assert resolved.tool_specs == []

Expand Down
Loading