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
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ Erlang support is optional because its toolchain is not needed for other languag

The Erlang option uses Homebrew on macOS and the RabbitMQ Team Erlang PPA on Ubuntu when the system OTP is missing or too old. The Ubuntu configuration has been tested with Erlang/OTP 26+; the macOS Erlang configuration has not been tested and uses the current formula versions selected by Homebrew. On Linux, rebar3 and ELP are installed into `~/.local/bin`; ensure this directory is on `PATH` in new shells. You can still install these tools manually, verify `rebar3 version` and `elp version`, and set `ELP_COMMAND` to an absolute ELP path if needed.

Chisel support is also optional. To install or verify `firtool` plus the FM-Agent CIRCT pass plugin used by the Chisel backend, run:

```bash
./install.sh --with-chisel
```

The Chisel backend uses a real CIRCT FIRRTL pass to build an authoritative module graph. When CIRCT inputs are available, FM-Agent uses CIRCT to identify Chisel hardware modules and module-instantiation edges, then slices source bodies only for the matched module declarations in the CIRCT-reported source files. The current implementation treats `Module`, `RawModule`, `ExtModule`, `BlackBox`, and `MultiIOModule` as supported hardware-module units. Bundles are kept as surrounding source context and are not extracted as standalone units. If CIRCT support is unavailable, FM-Agent falls back to conservative source-based extraction.

(Optional) If needed, you can manually set the default LLM model and API key of OpenCode in its configuration file.

**Important:** FM-Agent automatically derives test cases based on the reasoning process to trigger potential bugs, which help developers locate and fix them. Before running FM-Agent, please ensure the execution environment for test cases is ready, and if necessary, specify how to run test cases in `md/bug_validator.md`. If you do not specify, the agent will autonomously decide the execution method.
Expand Down Expand Up @@ -300,7 +308,7 @@ A `summary.json` file in `fm_agent/bug_validation/` aggregates all bug results w

1. FM-Agent will create an `fm_agent/` directory under your codebase directory. Make sure there is no name conflict.
2. The markdown files under `md/` provide general instructions that guide the agent's reasoning process. Prefer `--domain-knowledge` for project-specific context such as invariants, protocols, encoding rules, and domain terminology. For reusable framework behavior, customize the built-in prompts; for example, if you are reasoning about a compiler, modify `md/bug_validator.md` to instruct the agent to compare outputs against a reference implementation (e.g., GCC).
3. **Supported languages**: Rust, C, C++, Python, Java, Go, CUDA, JavaScript, TypeScript, ArkTS, Erlang. Erlang function extraction and call graphs require ELP; if ELP is unavailable, Erlang files are skipped with a warning.
3. **Supported languages**: Rust, C, C++, Python, Java, Go, CUDA, JavaScript, TypeScript, ArkTS, Erlang, Chisel. Erlang function extraction and call graphs require ELP; if ELP is unavailable, Erlang files are skipped with a warning. Chisel extraction and module graphs require CIRCT `firtool` plus the FM-Agent Chisel CIRCT pass plugin; when available, CIRCT is authoritative for module identification and module-instantiation edges, and FM-Agent uses source scanning only to materialize the matched Chisel module bodies. If CIRCT support is unavailable, FM-Agent falls back to conservative source-based extraction.

## Citation

Expand Down
12 changes: 12 additions & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ Erlang 工具链不影响其他语言,因此默认不安装。如需自动安

该选项在 macOS 上使用 Homebrew;在 Ubuntu 上,当系统 OTP 缺失或版本过低时使用 RabbitMQ Team Erlang PPA。Ubuntu 配置已使用 Erlang/OTP 26+ 验证;macOS Erlang 配置尚未测试,将使用 Homebrew 选择的当前公式版本。Linux 下的 rebar3 和 ELP 会安装到 `~/.local/bin`,请确保新终端的 `PATH` 包含该目录。你也可以手动安装这些工具,确认 `rebar3 version` 和 `elp version` 可执行,并在需要时将 `ELP_COMMAND` 设置为 ELP 的绝对路径。

Chisel 工具链同样是可选的。如需安装或检查 `firtool` 以及 FM-Agent 的 Chisel CIRCT pass plugin,请运行:

```bash
./install.sh --with-chisel
```

Chisel 后端会使用真实的 CIRCT FIRRTL pass 构建权威的模块图。当 CIRCT 输入可用时,FM-Agent 会以 CIRCT 结果作为硬件模块识别和模块实例化边的唯一依据,然后只在 CIRCT 命中的源文件中切取对应模块声明的源码 body。当前支持提取的硬件单元包括 `Module`、`RawModule`、`ExtModule`、`BlackBox` 和 `MultiIOModule`。`Bundle` 仅作为上下文保留,不会被单独提取为独立单元。若 CIRCT 支持不可用,则会回退到保守的源码提取路径。

(可选)如有需要,可在 OpenCode 的配置文件中手动设置默认 LLM 模型和 API 密钥。

**重要提示:** FM-Agent 会根据推理过程自动生成测试用例,以触发潜在 Bug,帮助开发者定位和修复问题。运行 FM-Agent 前,请确保目标代码库的测试环境已就绪,并在必要时在 `md/bug_validator.md` 中指定测试用例的运行方式。若未指定,Agent 将自主决定执行方式。
Expand Down Expand Up @@ -147,6 +155,10 @@ Erlang 工具链不影响其他语言,因此默认不安装。如需自动安
| `OPENCODE_TIMEOUT_SECONDS` | `1800` | 单个 `opencode run` 子进程的硬超时时间(秒);超时后子进程会被终止并重试该调用 |
| `ELP_COMMAND` | `elp` | 用于 Erlang 函数抽取与调用图分析的 ELP 可执行文件或命令 |
| `ELP_TIMEOUT_SECONDS` | `180` | ELP 初始化、索引及单次 LSP 请求的超时时间(秒) |
| `FM_AGENT_CHISEL_CIRCT_INPUT` | unset | 可选;指向 FIRRTL/MLIR 输入文件,供 Chisel CIRCT pass 构建模块图 |
| `FM_AGENT_CHISEL_CIRCT_COMMAND` | `firtool` | 用于执行 Chisel CIRCT pass 的 `firtool` 命令 |
| `FM_AGENT_CHISEL_CIRCT_PLUGIN` | unset | 可选;FM-Agent Chisel CIRCT plugin 的绝对路径 |
| `FM_AGENT_CHISEL_CIRCT_TIMEOUT_SECONDS` | `180` | Chisel CIRCT pass 构图命令的超时时间(秒) |

**重要说明:** 强烈建议使用 Claude Sonnet 4.6 等能力较强的模型,其他模型可能推理能力,无法有效发现 Bug。此外,请使用有权限访问 Claude 模型的 API 密钥,因为 FM-Agent 调用的 OpenCode 可能会使用 Claude 模型。

Expand Down
76 changes: 74 additions & 2 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,24 @@ set -euo pipefail
echo "=== fm-agent: installing required software ==="

INSTALL_ERLANG_SUPPORT=0
INSTALL_CHISEL_SUPPORT=0
for arg in "$@"; do
case "$arg" in
--with-erlang)
INSTALL_ERLANG_SUPPORT=1
;;
--with-chisel)
INSTALL_CHISEL_SUPPORT=1
;;
-h|--help)
echo "Usage: ./install.sh [--with-erlang]"
echo "Usage: ./install.sh [--with-erlang] [--with-chisel]"
echo " --with-erlang Install/verify Erlang/OTP 26+, rebar3 3.24.0+, and ELP"
echo " --with-chisel Install/verify CIRCT firtool and the FM-Agent Chisel CIRCT pass plugin"
exit 0
;;
*)
echo "[!!] unknown option: $arg"
echo "Usage: ./install.sh [--with-erlang]"
echo "Usage: ./install.sh [--with-erlang] [--with-chisel]"
exit 1
;;
esac
Expand Down Expand Up @@ -214,6 +219,61 @@ print(max(candidates)[2])
export PATH="$HOME/.local/bin:$PATH"
}

install_circt_and_chisel_tool() {
local circt_root circt_src circt_build tool_build repo_root parallel_jobs
circt_root="${FM_AGENT_CIRCT_ROOT:-$HOME/.cache/fm-agent/circt}"
circt_src="$circt_root/src"
circt_build="$circt_root/build"
tool_build="$circt_root/fm-agent-chisel-build"
repo_root="$SCRIPT_DIR"
parallel_jobs="${FM_AGENT_CIRCT_JOBS:-1}"

command -v git &>/dev/null || { echo "[!!] git is required for CIRCT support"; exit 1; }
command -v cmake &>/dev/null || { echo "[!!] cmake is required for CIRCT support"; exit 1; }
command -v ninja &>/dev/null || { echo "[!!] ninja is required for CIRCT support"; exit 1; }
command -v clang++ &>/dev/null || { echo "[!!] clang++ is required for CIRCT support"; exit 1; }

mkdir -p "$circt_root"
if [[ ! -d "$circt_src/.git" ]]; then
echo "[..] cloning llvm/circt"
git clone --depth 1 --recursive --shallow-submodules https://github.com/llvm/circt.git "$circt_src"
else
echo "[ok] CIRCT source found: $circt_src"
fi

if [[ ! -f "$circt_build/lib/cmake/circt/CIRCTConfig.cmake" ]]; then
echo "[..] configuring CIRCT"
cmake -G Ninja "$circt_src/llvm/llvm" -B "$circt_build" \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DLLVM_TARGETS_TO_BUILD=host \
-DLLVM_ENABLE_PROJECTS=mlir \
-DLLVM_EXTERNAL_PROJECTS=circt \
-DLLVM_EXTERNAL_CIRCT_SOURCE_DIR="$circt_src"
fi

if [[ ! -x "$circt_build/bin/firtool" || ! -x "$circt_build/bin/circt-opt" ]]; then
echo "[..] building CIRCT firtool"
ninja -C "$circt_build" -j"$parallel_jobs" bin/firtool
fi

echo "[..] configuring FM-Agent Chisel CIRCT plugin"
cmake -G Ninja -S "$repo_root/tools/chisel-circt" -B "$tool_build" \
-DCIRCT_DIR="$circt_build/lib/cmake/circt" \
-DMLIR_DIR="$circt_build/lib/cmake/mlir" \
-DLLVM_DIR="$circt_build/lib/cmake/llvm"

echo "[..] building FM-Agent Chisel CIRCT plugin"
ninja -C "$tool_build" -j"$parallel_jobs" FMAgentChiselCirctPlugin

mkdir -p "$HOME/.local/bin" "$HOME/.local/lib"
install -m 0755 "$circt_build/bin/firtool" "$HOME/.local/bin/firtool"
plugin_path="$(find "$tool_build" -name 'libFMAgentChiselCirctPlugin.so' -o -name 'FMAgentChiselCirctPlugin.so' -o -name 'libFMAgentChiselCirctPlugin.dylib' -o -name 'FMAgentChiselCirctPlugin.dylib' | head -n 1)"
[[ -n "$plugin_path" ]] || { echo "[!!] Chisel CIRCT plugin build succeeded but no plugin library was found"; exit 1; }
install -m 0755 "$plugin_path" "$HOME/.local/lib/$(basename "$plugin_path")"
export PATH="$HOME/.local/bin:$PATH"
}

if [[ "$INSTALL_ERLANG_SUPPORT" -eq 1 ]]; then
echo "[..] installing/verifying optional Erlang support"
os_name="$(uname -s)"
Expand Down Expand Up @@ -287,5 +347,17 @@ if [[ "$INSTALL_ERLANG_SUPPORT" -eq 1 ]]; then
echo "[ok] $(elp version)"
fi

if [[ "$INSTALL_CHISEL_SUPPORT" -eq 1 ]]; then
echo "[..] installing/verifying optional Chisel/CIRCT support"
install_circt_and_chisel_tool
command -v firtool &>/dev/null || { echo "[!!] firtool was not installed"; exit 1; }
find "$HOME/.local/lib" -maxdepth 1 \( -name 'libFMAgentChiselCirctPlugin.so' -o -name 'FMAgentChiselCirctPlugin.so' -o -name 'libFMAgentChiselCirctPlugin.dylib' -o -name 'FMAgentChiselCirctPlugin.dylib' \) | grep -q . || {
echo "[!!] FM-Agent Chisel CIRCT plugin was not installed"
exit 1
}
echo "[ok] firtool installed"
echo "[ok] FM-Agent Chisel CIRCT plugin installed"
fi

echo ""
echo "=== all dependencies installed ==="
Loading