feat(agent): Go port — canvas engine, 22 components, DSL v2, 13 endpoints (#15952)

Ports the agent canvas subsystem from Python to Go.

## What's included

### Canvas Engine (Phase 0/1)
- State engine, scheduler, variable resolver, Redis checkpoint store,
cancel protocol
- **209 tests** across canvas / component / io packages

### 22 Components (P0–P4)
| Tier | Components |
|---|---|
| P0 T1+T2+T3 | LLM, Agent, ExitLoop, Switch, Categorize, Begin,
Message, Invoke |
| P1 T3 | VariableAggregator, VariableAssigner, StringTransform,
ListOperations, DataOperations |
| P2 T3 | Iteration, IterationItem, Loop, LoopItem |
| P3 T3 | UserFillUp, Fillup |
| P4 T5 | Browser, ExcelProcessor, DocsGenerator |

### DSL v2 Schema (Phase 2.5)
- Typed v2 in-memory model with v1-to-v2 auto-detect converter
- v1 legacy field stripping per plan §2.11.7

### HTTP Endpoints & Bug Fixes (Plans PR1–PR3)
- **DELETE SQL bug fix**: gorm v2 `Where("id = ?", id).Delete(...)`
pattern
- **CreateAgent validation**: title/DSL required, duplicate check, 103
envelope
- **13 new endpoints**: templates, prompts, tags, sessions CRUD,
chat/completions (SSE + non-stream stubs), rerun, test_db_connection,
logs, webhook/logs
- **756 Go unit tests** (745 → 756, +18)
- **17 → 0 Python integration test failures** (test_agents.py +
test_session_management/)

### Tools
21 eino tools: HTTPHelper, search tools, financial/data tools, mandatory
stubs

### Infrastructure
OTel observability, NATS message queue, DeepDoc gRPC client, SSRF
guards, IDOR mitigation
This commit is contained in:
Zhichang Yu
2026-06-12 22:58:28 +08:00
committed by GitHub
parent cafa0f2e4f
commit 3fa15c0e2f
232 changed files with 44641 additions and 3993 deletions

117
build.sh
View File

@@ -14,7 +14,7 @@ PROJECT_ROOT="$SCRIPT_DIR"
# Build directories
CPP_DIR="$PROJECT_ROOT/internal/cpp"
BUILD_DIR="$CPP_DIR/cmake-build-release"
RAGFLOW_SERVER_BINARY="$PROJECT_ROOT/bin/server_main"
RAGFLOW_SERVER_BINARY="$PROJECT_ROOT/bin/ragflow_server"
ADMIN_SERVER_BINARY="$PROJECT_ROOT/bin/admin_server"
RAGFLOW_CLI_BINARY="$PROJECT_ROOT/bin/ragflow_cli"
@@ -29,6 +29,52 @@ print_section() {
echo -e "\n${YELLOW}>>> $1${NC}"
}
# Detect the package-install command for pcre2 development files.
# Outputs the command on stdout; empty string if no supported manager is found.
detect_pcre2_install_cmd() {
if [ "$(uname)" = "Darwin" ]; then
echo "brew install pcre2"
elif command -v apt-get >/dev/null 2>&1; then
echo "sudo apt-get install -y libpcre2-dev"
elif command -v zypper >/dev/null 2>&1; then
echo "sudo zypper install -y pcre2-devel"
elif command -v dnf >/dev/null 2>&1; then
echo "sudo dnf install -y pcre2-devel"
elif command -v pacman >/dev/null 2>&1; then
echo "sudo pacman -S --noconfirm pcre2"
else
echo ""
fi
}
# Check whether libpcre2-8 is available (static or shared).
check_pcre2() {
# Prefer pkg-config when available — works across distros.
if command -v pkg-config >/dev/null 2>&1 && pkg-config --exists libpcre2-8; then
return 0
fi
# Fall back to known library paths:
# Debian/Ubuntu -> /usr/lib/x86_64-linux-gnu
# openSUSE/RHEL -> /usr/lib64
# generic Linux -> /usr/lib, /usr/local/lib
# macOS Homebrew -> /opt/homebrew/lib (Apple Silicon), /usr/local/lib (Intel)
for p in \
/usr/lib/x86_64-linux-gnu/libpcre2-8.a \
/usr/lib/x86_64-linux-gnu/libpcre2-8.so \
/usr/lib64/libpcre2-8.a \
/usr/lib64/libpcre2-8.so \
/usr/lib/libpcre2-8.a \
/usr/lib/libpcre2-8.so \
/usr/local/lib/libpcre2-8.a \
/usr/local/lib/libpcre2-8.so \
/usr/local/lib/libpcre2-8.dylib \
/opt/homebrew/lib/libpcre2-8.a \
/opt/homebrew/lib/libpcre2-8.dylib; do
[ -f "$p" ] && return 0
done
return 1
}
# Check dependencies
check_cpp_deps() {
print_section "Checking c++ dependencies"
@@ -36,15 +82,16 @@ check_cpp_deps() {
command -v cmake >/dev/null 2>&1 || { echo -e "${RED}Error: cmake is required but not installed.${NC}"; exit 1; }
command -v g++ >/dev/null 2>&1 || { echo -e "${RED}Error: g++ is required but not installed.${NC}"; exit 1; }
# Check for pcre2 library (static .a or shared .so; -lpcre2-8 finds either)
if [ -f "/usr/lib/x86_64-linux-gnu/libpcre2-8.a" ] \
|| [ -f "/usr/lib/x86_64-linux-gnu/libpcre2-8.so" ] \
|| [ -f "/usr/local/lib/libpcre2-8.a" ] \
|| [ -f "/usr/local/lib/libpcre2-8.so" ]; then
if check_pcre2; then
echo "✓ pcre2 library found"
else
echo -e "${YELLOW}Warning: libpcre2-8 not found. You may need to install libpcre2-dev:${NC}"
echo " sudo apt-get install libpcre2-dev"
install_cmd="$(detect_pcre2_install_cmd)"
echo -e "${YELLOW}Warning: libpcre2-8 not found. You may need to install it:${NC}"
if [ -n "$install_cmd" ]; then
echo " $install_cmd"
else
echo " (No supported package manager detected — install pcre2 development files manually)"
fi
fi
echo "✓ Required tools are available"
@@ -164,21 +211,21 @@ build_go() {
exit 1
fi
# Check for pcre2 library — known Linux paths + macOS Homebrew (Apple Silicon
# at /opt/homebrew, Intel Macs at /usr/local). Checks both .a and .so.
if [ -f "/usr/lib/x86_64-linux-gnu/libpcre2-8.a" ] \
|| [ -f "/usr/lib/x86_64-linux-gnu/libpcre2-8.so" ] \
|| [ -f "/usr/local/lib/libpcre2-8.a" ] \
|| [ -f "/usr/local/lib/libpcre2-8.so" ] \
|| [ -f "/opt/homebrew/lib/libpcre2-8.a" ]; then
if check_pcre2; then
echo "✓ pcre2 library found"
else
if [ "$(uname)" = "Darwin" ]; then
echo -e "${RED}Error: libpcre2-8 not found. Install with: brew install pcre2${NC}"
install_cmd="$(detect_pcre2_install_cmd)"
if [ -z "$install_cmd" ]; then
echo -e "${RED}Error: libpcre2-8 not found and no supported package manager detected.${NC}"
echo "Please install pcre2 development files manually."
exit 1
fi
echo -e "${YELLOW}Warning: libpcre2-8 not found. You may need to install libpcre2-dev:${NC}"
sudo apt -y install libpcre2-dev
if [ "$(uname)" = "Darwin" ]; then
echo -e "${RED}Error: libpcre2-8 not found. Install with: $install_cmd${NC}"
exit 1
fi
echo -e "${YELLOW}Warning: libpcre2-8 not found. Installing with: $install_cmd${NC}"
eval "$install_cmd"
fi
# Check / install office_oxide native library
@@ -230,22 +277,29 @@ clean() {
# Run the server
run() {
if [ ! -f "$ADMIN_SERVER_BINARY" ]; then
echo -e "${RED}Error: Binary not found. Build first with --all or --go${NC}"
echo -e "${RED}Error: $ADMIN_SERVER_BINARY not found. Build first with --all or --go${NC}"
exit 1
fi
print_section "Starting ADMIN server"
cd "$PROJECT_ROOT"
./admin_server
if [ ! -f "$RAGFLOW_SERVER_BINARY" ]; then
echo -e "${RED}Error: Binary not found. Build first with --all or --go${NC}"
echo -e "${RED}Error: $RAGFLOW_SERVER_BINARY not found. Build first with --all or --go${NC}"
exit 1
fi
print_section "Starting server"
cd "$PROJECT_ROOT"
./server_main
# admin_server must be running before ragflow_server, otherwise ragflow_server's
# heartbeats to admin will error out (see internal/development.md).
print_section "Starting admin server (background)"
"$ADMIN_SERVER_BINARY" &
ADMIN_PID=$!
trap 'kill "$ADMIN_PID" 2>/dev/null || true' EXIT INT TERM
# Give admin_server a moment to bind its listening port (9383) before
# ragflow_server starts sending heartbeats to it.
sleep 1
print_section "Starting RAGFlow server (foreground)"
"$RAGFLOW_SERVER_BINARY"
}
# Show help
@@ -274,8 +328,11 @@ DEPENDENCIES:
- cmake >= 4.0
- go >= 1.24
- g++ with C++17/23 support
- libpcre2-dev
- office_oxide native library (auto-downloaded on first build)
- pcre2 development files
- Debian/Ubuntu: libpcre2-dev
- openSUSE/RHEL/Fedora: pcre2-devel
- macOS (Homebrew): pcre2
EOF
}