Skip to content

fix(policies): load Windows-generated ToolGuard modules - #14374

Merged
erichare merged 3 commits into
release-1.11.2from
fix/le-2094-toolguard-policies
Aug 3, 2026
Merged

fix(policies): load Windows-generated ToolGuard modules#14374
erichare merged 3 commits into
release-1.11.2from
fix/le-2094-toolguard-policies

Conversation

@erichare

@erichare erichare commented Aug 3, 2026

Copy link
Copy Markdown
Member

Summary

  • backport ToolGuard's Windows module-path conversion at the Langflow integration boundary
  • apply the compatibility patch only when the installed ToolGuard still lacks backslash handling
  • regenerate the bundled component index and cover both legacy and already-fixed ToolGuard behavior

Root cause

The flow attached to #14050 contains generated FileTwin paths with Windows \\ separators. ToolGuard 0.2.21 only maps / to Python module dots, so Guard mode raises ModuleNotFoundError while loading those policies from memory. In agent execution, the retries surface as the reported long run and eventual Job queue ... missing error.

This release-scoped compatibility patch leaves the generated files unchanged and updates only ToolGuard's module-name conversion when a behavior probe shows that it is needed. Future ToolGuard versions containing the upstream fix are left untouched.

The Generate-mode Anthropic thinking.thinking symptom is already fixed on release-1.11.2 by #14092 and follow-ups #14145 / #14157. This PR addresses the remaining Guard-mode half without a broader dependency bump.

Upstream permanent fix: AgentToolkit/toolguard#29

Test plan

  • 69 Policies component tests passed
  • Ruff check and format checks passed
  • regenerated component index loaded successfully (131 components, version 1.11.2)
  • reporter's attached flow completed both allowed and denied guard paths in under 0.001 seconds with ToolGuard 0.2.21
  • git diff --check

Fixes #14050

Summary by CodeRabbit

  • Bug Fixes
    • Improved Policies component compatibility on Windows by handling module paths consistently.
    • Prevented issues with older ToolGuard runtime converters while preserving compatibility with newer versions.
  • Tests
    • Added coverage for Windows path normalization and compatibility behavior across ToolGuard runtime versions.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: da910a82-c4e9-43de-9bd1-5091d934eedc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The PR adds a ToolGuard module-path compatibility helper, applies it during lazy loading, tests Windows separator normalization, and updates the embedded component asset metadata.

Changes

ToolGuard compatibility

Layer / File(s) Summary
Path conversion compatibility
src/lfx/src/lfx/components/models_and_agents/policies/module_utils.py, src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py
The helper probes ToolGuard’s private path converter and patches older converters to normalize Windows and POSIX separators. Tests cover normalization and preservation of fixed converters.
Lazy loading integration
src/lfx/src/lfx/components/models_and_agents/policies_component.py, src/lfx/src/lfx/_assets/component_index.json
Lazy ToolGuard loading applies the helper to the runtime module. The embedded component source and asset checksums are updated.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: adam-aghili

🚥 Pre-merge checks | ✅ 9
✅ Passed checks (9 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Test Coverage For New Implementations ✅ Passed The PR updates the backend test file with two focused regression tests for legacy Windows-separator normalization and preservation of fixed ToolGuard converters; the file follows test_*.py naming.
Test Quality And Coverage ✅ Passed Pytest tests directly verify legacy backslash normalization and preservation of a fixed converter; existing async component tests use pytest.mark.asyncio, and no API or frontend changes apply.
Test File Naming And Structure ✅ Passed The changed test is a pytest test_*.py file in the backend unit-test directory. Tests have descriptive names and docstrings, and cover legacy normalization, fixed-converter preservation, and existi...
Excessive Mock Usage Warning ✅ Passed The two added tests use real ModuleType instances and callable converters; the diff adds no mocks, while existing mocks isolate ToolGuard and filesystem boundaries.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: fixing ToolGuard module loading for Windows-generated modules.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/le-2094-toolguard-policies

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Aug 3, 2026
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

✅ Test Coverage Advisor

No source changes detected without accompanying tests. Thanks for keeping coverage up! 🎉

Advisory check only — never blocks merge.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Aug 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lfx/src/lfx/components/models_and_agents/policies/module_utils.py`:
- Around line 21-33: Update the converter compatibility check in
_import_toolguard so both “policies.guard” and the known legacy forward-slash
result are treated as supported and leave the existing converter unchanged. Only
install the local file_to_module_name fallback when neither result matches, and
broaden the converter exception handling to catch unsupported or unexpected
exceptions without aborting _import_toolguard().
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 48bab9da-77bc-4fe0-850c-8cc168b69982

📥 Commits

Reviewing files that changed from the base of the PR and between d3d7007 and 3ac2b1e.

📒 Files selected for processing (4)
  • src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py
  • src/lfx/src/lfx/_assets/component_index.json
  • src/lfx/src/lfx/components/models_and_agents/policies/module_utils.py
  • src/lfx/src/lfx/components/models_and_agents/policies_component.py

Comment on lines +21 to +33
probe = r"policies\guard.py"
try:
if converter(probe) == "policies.guard":
return
except (TypeError, ValueError):
# A future ToolGuard may change the private helper's contract. In that
# case, do not replace behavior we no longer understand.
return

def file_to_module_name(file_path: str | Path) -> str:
return str(file_path).removesuffix(".py").replace("\\", ".").replace("/", ".")

runtime_module.__dict__["_file_to_module_name"] = file_to_module_name

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

uv run python - <<'PY'
from pathlib import Path
import toolguard.runtime.runtime as runtime

converter = runtime._file_to_module_name
for value in ("policies/guard.py", r"policies\guard.py", Path("policies/guard.py")):
    try:
        print(repr(value), "->", repr(converter(value)))
    except Exception as exc:
        print(repr(value), "raised", type(exc).__name__, str(exc))
PY

Repository: langflow-ai/langflow

Length of output: 198


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repository files around toolguard/runtime:"
git ls-files | rg '(^|/)runtime\.py$|toolguard|guard\.py|module_utils\.py' | head -200

echo
echo "Candidate module_utils.py:"
file="$(git ls-files | rg '(^|/)module_utils\.py$' | grep 'lfx/components/models_and_agents/policies/module_utils.py' || true)"
if [ -n "${file:-}" ]; then
  wc -l "$file"
  sed -n '1,120p' "$file" | cat -n
fi

echo
echo "Search for ensure_toolguard_module_path_compat and _file_to_module_name:"
rg -n "ensure_toolguard_module_path_compat|_file_to_module_name|ToolGuard|toolguard" . --glob '!**/.git/**' | head -300

Repository: langflow-ai/langflow

Length of output: 50376


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import urllib.request
from urllib.parse import quote
import tarfile
from io import BytesIO

url = "https://files.pythonhosted.org/packages/1b/12/e78f303f2c306de58bb72c21a58b19f3dd4bb45aae2a5b6a61717255cae8ba7/toolguard-0.2.21.tar.gz"
print("Downloading", url)
with urllib.request.urlopen(url, timeout=30) as r:
    data = r.read()
print("Downloaded", len(data), "bytes")

with tarfile.open(fileobj=BytesIO(data), mode="r:gz") as tf:
    names = [name for name in tf.getnames() if name.endswith("/runtime.py") or name.endswith("/runtime/__init__.py")]
    print("runtime files:", names)
    for name in names:
        print("\n---", name, "---")
        text = tf.extractfile(name).read().decode("utf-8", errors="replace")
        for i, line in enumerate(text.splitlines(), 1):
            if "_file_to_module_name" in line or "FileTwin" in line or "normalize" in line.lower():
                lo=max(1,i-8); hi=min(len(text.splitlines()),i+12)
                lines=text.splitlines()
                for j in range(lo,hi+1):
                    print(f"{j:4d}\t{lines[j-1]}")
                print()

PY

python3 - <<'PY'
import urllib.request
import tempfile
import os

def ensure_path_imports(path):
    parent = os.path.dirname(os.path.abspath(path))
    if parent not in __import__("sys").path:
        __import__("sys").path.insert(0, parent)
        return lambda: __import__("sys").path.remove(parent)
    return lambda: None

if not os.path.exists("/tmp/toolguard-0.2.21"):
    import urllib.request, tarfile
    url = "https://files.pythonhosted.org/packages/1b/12/e78f303f2c306de58bb72c21a58b19f3dd4bb45aae2a5b6a61717255cae8ba7/toolguard-0.2.21.tar.gz"
    with urllib.request.urlopen(url, timeout=30) as r:
        data = r.read()
    with tempfile.NamedTemporaryFile(delete=False, suffix=".tar.gz") as f:
        f.write(data)
        tmp = f.name
    tarfile.open(tmp, "r:gz").extractall("/tmp/toolguard-0.2.21")
    os.unlink(tmp)

import sys, types
sys.modules.pop("toolguard", None)
for k in list(sys.modules):
    if k.startswith("toolguard"):
        del sys.modules[k]
unregister = ensure_path_imports("/tmp/toolguard-0.2.21/toolguard-0.2.21")

import toolguard.runtime
print("runtime module file:", getattr(toolguard.runtime, "__file__", None))
print("has runtime._file_to_module_name:", hasattr(toolguard.runtime.runtime, "_file_to_module_name"))

if hasattr(toolguard.runtime.runtime, "_file_to_module_name"):
    converter = toolguard.runtime.runtime._file_to_module_name
    for path in ("policies/guard.py", r"policies\guard.py"):
        print(path, "->", repr(converter(path)))
    import pathlib
    try:
        print(repr(pathlib.Path("policies/guard.py")), "->", repr(converter(pathlib.Path("policies/guard.py"))))
    except Exception as exc:
        print(repr(pathlib.Path("policies/guard.py")), "raised", type(exc).__name__, str(exc))
else:
    candidate = None
    import inspect
    for name in dir(toolguard.runtime.runtime):
        obj = getattr(toolguard.runtime.runtime, name)
        if callable(obj) and "_file_to_module_name" in (getattr(obj, "__qualname__", "") or ""):
            print(name)
            try:
                print(inspect.getsource(obj))
            except Exception as exc:
                print("source_error", exc)
unregister()
PY

python3 - <<'PY'
from pathlib import Path
def converter(path):
    return str(path).removesuffix(".py").replace("\\", ".")
print("legacy converter:")
for value in ("policies/guard.py", r"policies\guard.py"):
    try:
        print(repr(value), "->", repr(converter(value)))
    except Exception as exc:
        print(repr(value), "raised", type(exc).__name__, str(exc))

current = "policies.guard"  # installed ToolGuard result to patch on
def patched(file_path: str | Path) -> str:
    return str(file_path).removesuffix(".py").replace("\\", ".").replace("/", ".")
print("if current is patched:")
for value in ("policies/guard.py", r"policies\guard.py", Path("policies/guard.py")):
    try:
        print(repr(value), "->", repr(patched(value)))
    except Exception as exc:
        print(repr(value), "raised", type(exc).__name__, str(exc))
PY

Repository: langflow-ai/langflow

Length of output: 2590


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import urllib.request
import tarfile
import tempfile
import os
import pathlib

url = "https://files.pythonhosted.org/packages/1b/12/e78f303f2c306de58bb72c21a58b19f3dd4bb45aae2a5b6a61717255cae8ba7/toolguard-0.2.21.tar.gz"
print("Downloading", url)
unpin_ssl = __import__("urllib3.util.ssl_")
try:
    unpin_ssl.create_urllib3_context = lambda ciphers=None: None
except Exception:
    pass
with urllib.request.urlopen(url, timeout=30, context=pathlib.Path("/tmp")._accessor._ssl_context if hasattr(pathlib.Path("/tmp")._accessor, "_ssl_context") else None) as r:
    data = r.read()
print("Downloaded", len(data), "bytes")

with tempfile.TemporaryDirectory() as td:
    with tarfile.open(fileobj=bytes(data), mode="r:gz") as tf:
        tf.extractall(td, filter="data")
    tg = pathlib.Path(td)
    for root, _, files in os.walk(tg):
        if "runtime.py" in files or "guard.py" in files:
            p = pathlib.Path(root, files[0])
            print("\n---", p, "---")
            text = p.read_text(encoding="utf-8", errors="replace").splitlines()
            for i, line in enumerate(text, 1):
                if "_file_to_module_name" in line or "FileTwin" in line or "normalize" in line.lower():
                    lo=max(1,i-8); hi=min(len(text),i+12)
                    for j in range(lo, hi+1):
                        print(f"{j:4d}\t{text[j-1]}")
                    print()

    # Local import from extracted source.
    sys = __import__("sys")
    venv_py = next((p / "bin" / "python" if (p / "bin" / "python").exists() else p / "python3") for p in tg.glob("*/"))
    print("venv python:", venv_py)
PY

Repository: langflow-ai/langflow

Length of output: 424


🌐 Web query:

pypi toolguard 0.2.21 runtime.py _file_to_module_name

💡 Result:

The package toolguard (version 0.2.21) on PyPI is a tool designed for policy adherence and guarding AI agent tools [1][2]. It analyzes policy documents to generate deterministic Python code that enforces operational constraints during tool invocation [1][3]. Regarding the specific reference to runtime.py and _file_to_module_name, historical records of the AgentToolkit/toolguard repository indicate that the internal structure of the library has undergone modifications related to how modules are loaded and mapped from file paths [4]. Previously, the library contained utility functions such as load_module_from_path, which handled file-to-module transformations [4]. However, development activity—specifically commit e4237bf—shows a transition toward using importlib and custom path-to-module logic (e.g., path_to_module) rather than the earlier implementation patterns that may have included functions named _file_to_module_name [4]. It is important to distinguish this package (AgentToolkit/toolguard) from another project on PyPI named py-toolguard, which is an unrelated project focused on security interception and fuzzing for AI agents [5][6][7]. The two projects are distinct in scope, ownership, and functionality [1][5].

Citations:


🌐 Web query:

AgentToolkit/toolguard e4237bf runtime _file_to_module_name

💡 Result:

The term _file_to_module_name is not a documented function or component within the AgentToolkit/toolguard project [1][2][3]. The repository AgentToolkit/toolguard is a tool for generating deterministic Python code to enforce operational policies on AI agent tools, featuring toolguard.buildtime and toolguard.runtime modules [1][3]. While the query references e4237bf, this appears to be a git commit hash [4]. Research indicates this specific hash does not correspond to a version or artifact within the AgentToolkit/toolguard repository, which uses different commit patterns and release versioning (e.g., ece4a29 for version 0.2.13) [5][6]. The identifier file_to_module_name is commonly found in Python metaprogramming and dynamic module loading utilities (such as in external projects unrelated to toolguard like auger) to map file system paths to Python module names [7]. It is not a standard part of the AgentToolkit/toolguard codebase [1][3].

Citations:


🌐 Web query:

GitHub AgentToolkit/toolguard v0.2.21 runtime.py

💡 Result:

ToolGuard is an open-source library within the AgentToolkit GitHub repository designed to provide deterministic, interpretable policy adherence for AI agents at the tool level [1][2]. Version 0.2.21 of this toolkit was released on June 30, 2026 [3]. The library operates by analyzing policy documents and OpenAPI specifications to generate guard specifications (ToolGuardSpec) and executable Python code [1][4]. These guards are designed to be executed prior to tool invocation to ensure compliance with predefined business rules [1][2]. Within the ToolGuard architecture, the runtime module (found in toolguard/runtime.py) is a core component of the Runtime API [1][2]. Its primary functions include: 1. Runtime Enforcement: Executing pre-tool activation policy constraints before a tool is invoked [2][5]. 2. ToolguardRuntime: Providing the mechanism to execute guards (specifically via methods like guard_toolcall) [1][2]. 3. Error Handling: Raising a PolicyViolationException if a tool invocation violates defined policies [1][2]. 4. Invoker Support: Supporting various invoker types, such as ToolFunctionsInvoker (for Python functions), ToolMethodsInvoker (for class methods), and LangchainToolInvoker (for LangChain tools) [1][2]. To utilize the runtime capabilities, developers typically load generated guards using functions such as load_toolguards and integrate them into their tool invocation workflows via the provided invokers [1][2].

Citations:


🌐 Web query:

"toolguard\>=0.2.20" "toolguard" "0.2.21"

💡 Result:

There are multiple distinct software projects and entities identified by the name or a variation of "ToolGuard" as of August 2026. The specific versions "0.2.20" and "0.2.21" refer to a Python package available on PyPI [1]. The package named toolguard on PyPI is a utility focused on policy adherence and code generation for guarding AI agent tools [1]. It provides APIs to: 1. Generate guard specifications from policy text (Buildtime API) [1]. 2. Enforce these operational policies during tool invocation (Runtime API) [1]. It should not be confused with other similarly named projects: - py-toolguard: A separate package (currently v6.1.1) described as a "Cloudflare for AI Agents" that includes a 7-layer security interceptor and observability dashboard [2][3][4][5]. - ToolGuard (toolguard.ai): A security gateway platform for Model Context Protocol (MCP) servers, which isolates secrets and enforces policies at the gateway level [6][7][8]. - Other entities: There are unrelated businesses named "Toolsguard" (a workshop management software) [9] and "TradeGuard" (an insurance/compliance platform) [10]. If you are working with the package that uses version 0.2.21, you are likely using the library for defining and enforcing deterministic Python-based guard specifications for AI tool calls [1].

Citations:


🌐 Web query:

raw.githubusercontent.com Harshit-J004 toolguard 0.2.21 toolguard/runtime/runtime.py

💡 Result:

ToolGuard is a security and observability framework for AI agents, often described as a "Cloudflare for AI Agents" [1][2]. Developed by Harshit Joshi (GitHub user Harshit-J004), the project provides a 7-layer security interceptor, real-time observability, and automated reliability testing for AI tool chains and Model Context Protocol (MCP) implementations [1][3]. The specific path referenced, toolguard/runtime/runtime.py, is part of the ToolGuard codebase hosted in the Harshit-J004/toolguard repository [1][4]. Key characteristics of ToolGuard as of August 2026: - Architecture: Initially a local Python library [5], it evolved into a distributed, language-agnostic enterprise firewall in version 6.1.0 [6]. This version introduced an HTTP Proxy Sidecar, Redis-based distributed state management, and support for asynchronous webhook-based human-in-the-loop approvals [6]. - Security Features: It implements various protections including semantic analysis, injection prevention, schema drift detection, and identity spoofing detection [6][5]. - Ecosystem: The package is published on PyPI as py-toolguard [2]. Development has focused on enabling agents to operate safely in production environments, specifically addressing challenges like hallucinations, prompt injection, and destructive tool calls [1][2]. - Recent Updates: Version 6.1.1, released in April 2026, focused on hardening concurrency for the proxy by implementing threadpool offloading and improving resilience against network issues in distributed deployments [7]. The project repository is accessible at https://github.com/Harshit-J004/toolguard [1].

Citations:


🌐 Web query:

raw.githubusercontent.com Harshit-J004 toolguard 0.2.21 runtime runtime.py _file_to_module_name

💡 Result:

The function _file_to_module_name is located in the toolguard.runtime module of the toolguard package (version 0.2.21) [1]. This version of toolguard appears to be part of an earlier codebase (associated with the AgentToolkit/toolguard repository) [2][3], which is distinct from the more recent "Cloudflare for AI Agents" project by Harshit-J004 (which uses the package name py-toolguard and is currently on version 6.1.1) [4][5][6][7]. In the context of toolguard v0.2.21, runtime.py provides the runtime API for executing security guards during tool invocations [1][3]. The _file_to_module_name function is an internal utility used within the runtime framework to map filesystem paths to Python module identifiers for dynamic loading [1][2][3]. Documentation for v0.2.21 highlights the following components of the Runtime API [1][3]: - load_toolguards: Loads generated guards for runtime use. - ToolguardRuntime.guard_toolcall: Executes a guard before tool invocation. - ToolFunctionsInvoker: Invoker for Python functions. - ToolMethodsInvoker: Invoker for class methods. - LangchainToolInvoker: Invoker for LangChain tools. - PolicyViolationException: Exception raised upon policy violation. If you are working with the newer py-toolguard (v6.x.x) by Harshit-J004, note that the library architecture has evolved into a distributed, language-agnostic enterprise firewall [6], and reliance on internal path-to-module mapping functions may differ significantly or be deprecated in favor of its HTTP proxy sidecar and enterprise-grade infrastructure [6][7].

Citations:


🌐 Web query:

site:raw.githubusercontent.com AgentsTool toolguard 0.2.21 _file_to_module_name

💡 Result:

There is no widely recognized technical package or library named "AgentsTool" or "toolguard" version 0.2.21 that provides a function named _file_to_module_name. The term "ToolGuard" appears as a specific class or component within several distinct and unrelated AI agent development projects, such as pydantic-ai-shields [1] and others involved in AI governance or safety [2][3][4]. Similarly, patterns like _file_to_module_name are common internal utility functions in Python for mapping file paths to module structures [5][6][7], but they are not standardized or associated with a single public package under the name "AgentsTool". It is likely that the query refers to: 1. A proprietary, internal, or highly specific custom tool. 2. A misunderstanding or conflation of components from different AI agent frameworks (e.g., OpenAI's agent tools [8][9], Pydantic AI harness [1], or Microsoft's Agent Governance Toolkit [4]). If you are encountering this in a specific codebase, it is recommended to search for the definition of _file_to_module_name within your local project files, as it is likely a local helper function rather than a public API.

Citations:


🌐 Web query:

"https://raw.githubusercontent.com/AgencyNetworkTool/toolguard/0.2.21" "_file_to_module_name"

💡 Result:

In the context of the AgencyNetworkTool/toolguard library (specifically version 0.2.21), _file_to_module_name refers to a utility function used to convert a filesystem path into a valid Python module import string [1]. While the exact implementation of this function has evolved in the codebase [1], its primary purpose is to enable the dynamic loading of Python files as modules. The function typically performs the following logic: 1. It takes a file path (e.g., /path/to/my_tool.py) as input [1]. 2. It strips the file extension and replaces directory separators (such as / or ) with the dot notation required for Python imports (e.g., path.to.my_tool) [1]. 3. This converted string is then passed to Python's importlib.import_module or related import utilities to programmatically load the file's contents for inspection or execution [1]. This mechanism is central to toolguard's ability to analyze and guard AI agent tools by dynamically importing and introspecting function definitions from specified source files [1]. Note that there are multiple projects named toolguard [2][3][4], and this specific functionality is associated with the AgentToolkit/toolguard repository [1][3].

Citations:


🌐 Web query:

raw.githubusercontent.com AgencyNetworkTool toolguard 0.2.21 _file_to_module_name

💡 Result:

The reference to _file_to_module_name in the context of toolguard 0.2.21 pertains to internal utilities within the AgentToolkit/toolguard library, which is a deterministic tool-level policy enforcement framework for AI agents [1][2][3]. In version 0.2.21, the library's internal code structure included utility functions—often found in modules such as toolguard.utils.py or similar helper files—that managed the mapping of file paths to Python module names for dynamic code loading [4]. Specifically, these helpers are used by the library's buildtime API to load and analyze tool definitions from local Python files [5][4]. While _file_to_module_name was part of the internal implementation to facilitate these imports (often using importlib.util), the codebase has evolved; for example, subsequent commits shifted toward direct usage of importlib.path_to_module or similar standard library patterns to handle file-to-module resolution more robustly [4]. If you are interacting with this library, toolguard is designed to be used via its primary Buildtime and Runtime APIs rather than by calling internal utility functions directly [5][3]. The library generates ToolGuardSpec objects and Python code to enforce operational policies before tool invocation, ensuring agentic actions remain within defined compliance boundaries [1][5].

Citations:


Only patch the known legacy converter behavior.

Handle the existing forward-slash result as unchanged too. If the current converter("policies\guard.py") returns "policies.guard", the patch still overwrites it on Windows and drops legacy behavior. Also use an unsupported-case except so an unexpected converter exception does not abort _import_toolguard().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lfx/src/lfx/components/models_and_agents/policies/module_utils.py` around
lines 21 - 33, Update the converter compatibility check in _import_toolguard so
both “policies.guard” and the known legacy forward-slash result are treated as
supported and leave the existing converter unchanged. Only install the local
file_to_module_name fallback when neither result matches, and broaden the
converter exception handling to catch unsupported or unexpected exceptions
without aborting _import_toolguard().

Source: Coding guidelines

@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.59%. Comparing base (d3d7007) to head (2cb25b5).
⚠️ Report is 1 commits behind head on release-1.11.2.

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##           release-1.11.2   #14374      +/-   ##
==================================================
+ Coverage           61.44%   61.59%   +0.14%     
==================================================
  Files                2452     2398      -54     
  Lines              239862   238187    -1675     
  Branches            36330    35735     -595     
==================================================
- Hits               147395   146707     -688     
+ Misses              90661    89674     -987     
  Partials             1806     1806              
Flag Coverage Δ
backend 68.35% <ø> (+1.18%) ⬆️
lfx 60.73% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 360 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 47%
47.33% (67565/142734) 70.29% (9507/13525) 45.8% (1555/3395)

Unit Test Results

Tests Skipped Failures Errors Time
5401 0 💤 0 ❌ 0 🔥 20m 42s ⏱️

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Aug 3, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Aug 3, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Aug 3, 2026
@erichare
erichare merged commit 36cddb0 into release-1.11.2 Aug 3, 2026
168 checks passed
@erichare
erichare deleted the fix/le-2094-toolguard-policies branch August 3, 2026 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant