Skip to content

[FEATURE]: Go bindings (cpex-ffi + cgo) #18

Description

@terylt

Epic: CPEX Rust Core (#12)

Summary

Create the C FFI layer (cpex-ffi crate) and Go bindings (go/ package) as the first language binding for the Rust core. Go is prioritized for K8s deployments expressed interest and Python already has a complete implementation.

Motivation

Kagenti and other Go-based agent platforms need CPEX plugin execution with the same semantics as the Python/Rust implementations. A shared Rust core with Go bindings ensures behavioral parity without reimplementing the PluginManager in Go.

Scope

cpex-ffi crate

  • #[repr(C)] result struct — continue_processing, violation_code, violation_reason, modified_payload (pointer + length)
  • Opaque handle types — cpex_manager_t, managed via Arc internally
  • Lifecycle — cpex_manager_new(), cpex_manager_free()
  • Hook dispatch — cpex_invoke_hook() with payload as byte buffer (MessagePack default, JSON debug)
  • Result access — cpex_result_blocked(), cpex_result_payload(), cpex_result_free()
  • Error reporting — cpex_last_error() (thread-local)
  • ABI versioning — cpex_abi_version()
  • cbindgen.toml → generates include/cpex.h

Go bindings (go/)

  • go.mod with module path github.com/contextforge/cpex/go, package name cpex
  • cpex.goNewManager(), InvokeHook(), Close()
  • types.goPluginResult, HookType, Extensions
  • errors.go — error types bridging cpex_last_error()
  • internal/ffi.go — cgo bindings to cpex.h (pkg-config + relative path fallback)
  • internal/memory.go — handle lifecycle, free safety

Wire Format

  • MessagePack as default (fast, compact, schema-less)
  • JSON as debug option (human-readable)
  • Zero-copy where possible: Go pins memory for input, Rust reads directly. C struct envelope for result scalars.

Acceptance Criteria

  • go test ./... passes from the monorepo (cargo build -p cpex-ffi && cd go && go test)
  • cpex.NewManager() initializes a Rust PluginManager via cgo
  • cpex.InvokeHook() dispatches through the 5-phase executor
  • ABI version check at init time
  • Result envelope readable without deserialization (C struct scalars)
  • Payload serialized only when modified

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

Fields

No fields configured for Task.

Projects

Status
Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions