Files
ragflow/internal/agent/component/base.go
Zhichang Yu 3fa15c0e2f 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
2026-06-12 22:58:28 +08:00

85 lines
3.7 KiB
Go

// Package component implements the RAGFlow agent canvas components in Go.
//
// See plan: .claude/plans/agent-go-port.md §2.11 (5-tier porting strategy).
// Phase 2 P0 batch covers 8 components: LLM, Agent, ExitLoop, Switch,
// Categorize, Begin, Message, Invoke.
//
// Component is the runtime contract every RAGFlow component implements;
// it is a richer interface than internal/agent/runtime.Component (which
// is the minimal Invoke-only surface canvas needs at build time). Any
// concrete *Component here satisfies runtime.Component structurally,
// which is how the canvas builder consumes a registered component via
// runtime.DefaultFactory().
//
// ParamError and ErrNotImplemented are aliased from runtime so the
// canvas builder and the component implementations share the same
// types without a cycle.
package component
import (
"context"
"ragflow/internal/agent/runtime"
)
// Component is the runtime contract every RAGFlow component implements.
// Mirrors the Python ComponentBase.invoke / invoke_async surface
// (agent/component/base.py:365, 408, 422) plus a Stream variant for SSE
// output (the Message component).
//
// Inputs() and Outputs() return parameter metadata for tooling / docs /
// graph introspection — name → human description. Not used at runtime.
//
// Any value implementing this interface also satisfies the smaller
// runtime.Component interface (Invoke only), so the canvas builder
// can consume a *Component via runtime.DefaultFactory() without any
// extra adaptation.
type Component interface {
// Name returns the registered component name (e.g. "LLM", "Agent",
// "Switch"). Case-insensitive lookup — the registry normalizes input.
Name() string
// Invoke runs the component synchronously. inputs is the resolved
// parameter map (variable references already substituted by the canvas
// engine). Returns the output map; components should put their public
// outputs at top-level keys.
Invoke(ctx context.Context, inputs map[string]any) (map[string]any, error)
// Stream is the streaming variant. The default implementation may
// return a buffered channel that emits the same payload as Invoke, then
// closes — components that natively stream (LLM, Message) override.
// May return (nil, nil) for non-streaming components.
Stream(ctx context.Context, inputs map[string]any) (<-chan map[string]any, error)
// Inputs returns parameter metadata: param_name → description.
Inputs() map[string]string
// Outputs returns output metadata: param_name → description.
Outputs() map[string]string
}
// ParamBase is the optional parameter validation/serialization surface.
// Components that need validation can embed *BaseParam (below) or implement
// this directly. Components that don't need it (e.g. ExitLoop) can omit.
//
// Mirrors agent/component/param_base.py:ComponentParamBase (Python).
type ParamBase interface {
// Update copies conf into the receiver, validating types. Used by
// editors / APIs that hand-craft a params map.
Update(conf map[string]any) error
// Check performs deep validation (required fields, value ranges).
// Called once before Invoke — returning an error aborts the run.
Check() error
// AsDict returns the params as a plain map for serialization / debug.
AsDict() map[string]any
}
// ErrNotImplemented aliases runtime.ErrNotImplemented so component-side
// code (and the canvas builder it interoperates with) share a single
// sentinel value.
var ErrNotImplemented = runtime.ErrNotImplemented
// ParamError aliases runtime.ParamError. Existing code that constructs
// &ParamError{Field: ..., Reason: ...} continues to work; the value
// it produces is the same type runtime.SetDefaultFactory consumers see.
type ParamError = runtime.ParamError