mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-16 12:47:19 +08:00
fix: support code_execute for go backend (#16903)
### Summary As title <img width="3764" height="2033" alt="image" src="https://github.com/user-attachments/assets/3f5084c2-0a04-4a44-bb31-a39a59c2a91f" />
This commit is contained in:
@@ -626,6 +626,52 @@ func TestCodeExec_LegacyDSLWrapperResolvesArgumentRefsFromState(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodeExec_LegacyDSLWrapperResolvesSysArgumentRefsFromCanvasState(t *testing.T) {
|
||||
prev := agenttool.GetSandboxClient()
|
||||
recorder := &codeExecSandboxRecorder{
|
||||
resp: &agenttool.SandboxResponse{
|
||||
ExitCode: 0,
|
||||
StructuredResult: map[string]any{
|
||||
"present": true,
|
||||
"value": "532",
|
||||
},
|
||||
},
|
||||
}
|
||||
agenttool.SetSandboxClient(recorder)
|
||||
t.Cleanup(func() { agenttool.SetSandboxClient(prev) })
|
||||
|
||||
c, err := New(componentNameCodeExec, map[string]any{
|
||||
"lang": "python",
|
||||
"script": "def main(num):\n" +
|
||||
" return num\n",
|
||||
"arguments": map[string]any{
|
||||
"num": "sys.query",
|
||||
},
|
||||
"outputs": map[string]any{
|
||||
"result": map[string]any{
|
||||
"type": "String",
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("New(CodeExec): %v", err)
|
||||
}
|
||||
|
||||
state := runtime.NewCanvasState("run-codeexec", "task-codeexec")
|
||||
state.Sys["query"] = "532"
|
||||
ctx := runtime.WithState(context.Background(), state)
|
||||
out, err := c.Invoke(ctx, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("CodeExec.Invoke: %v", err)
|
||||
}
|
||||
if got := recorder.req.Arguments["num"]; got != "532" {
|
||||
t.Fatalf("sandbox arguments[num] = %#v, want \"532\"", got)
|
||||
}
|
||||
if got := out["result"]; got != "532" {
|
||||
t.Fatalf("CodeExec result = %v, want 532", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodeExec_LegacyDSLWrapperContractMismatchSetsError(t *testing.T) {
|
||||
prev := agenttool.GetSandboxClient()
|
||||
recorder := &codeExecSandboxRecorder{
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// Universe A delegation wrappers. Canvas-facing components that
|
||||
// Package component Universe A delegation wrappers. Canvas-facing components that
|
||||
// delegate to their corresponding Universe B eino tool
|
||||
// implementations. The delegation pattern keeps the canvas
|
||||
// scheduler's Component contract thin and the eino tool's
|
||||
@@ -1496,6 +1496,17 @@ func (c *codeExecComponent) Inputs() map[string]string {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *codeExecComponent) GetInputForm() map[string]any {
|
||||
res := make(map[string]any, len(c.params))
|
||||
for k, _ := range c.params {
|
||||
res[k] = map[string]any{
|
||||
"type": "line",
|
||||
"name": k,
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *codeExecComponent) Outputs() map[string]string {
|
||||
return map[string]string{
|
||||
"result": "The main(...) return value rendered as the legacy CodeExec result field.",
|
||||
@@ -1517,7 +1528,8 @@ func (c *codeExecComponent) Invoke(ctx context.Context, inputs map[string]any) (
|
||||
merged[k] = v
|
||||
}
|
||||
if rawArgs, ok := merged["arguments"].(map[string]any); ok {
|
||||
merged["arguments"] = resolveCodeExecArguments(rawArgs, merged)
|
||||
state, _, _ := runtime.GetStateFromContext[*runtime.CanvasState](ctx)
|
||||
merged["arguments"] = resolveCodeExecArguments(rawArgs, merged, state)
|
||||
}
|
||||
common.Debug("CodeExec wrapper invoke",
|
||||
zap.Int("params_keys", len(c.params)),
|
||||
@@ -1656,29 +1668,29 @@ func cloneAnyMap(in map[string]any) map[string]any {
|
||||
return out
|
||||
}
|
||||
|
||||
func resolveCodeExecArguments(args map[string]any, merged map[string]any) map[string]any {
|
||||
func resolveCodeExecArguments(args map[string]any, merged map[string]any, state *runtime.CanvasState) map[string]any {
|
||||
if args == nil {
|
||||
return nil
|
||||
}
|
||||
out := make(map[string]any, len(args))
|
||||
for k, v := range args {
|
||||
out[k] = resolveCodeExecArgumentValue(v, merged)
|
||||
out[k] = resolveCodeExecArgumentValue(v, merged, state)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func resolveCodeExecArgumentValue(v any, merged map[string]any) any {
|
||||
func resolveCodeExecArgumentValue(v any, merged map[string]any, state *runtime.CanvasState) any {
|
||||
switch x := v.(type) {
|
||||
case map[string]any:
|
||||
return resolveCodeExecArguments(x, merged)
|
||||
return resolveCodeExecArguments(x, merged, state)
|
||||
case []any:
|
||||
out := make([]any, 0, len(x))
|
||||
for _, item := range x {
|
||||
out = append(out, resolveCodeExecArgumentValue(item, merged))
|
||||
out = append(out, resolveCodeExecArgumentValue(item, merged, state))
|
||||
}
|
||||
return out
|
||||
case string:
|
||||
if resolved, ok := lookupCodeExecArgumentRef(x, merged); ok {
|
||||
if resolved, ok := lookupCodeExecArgumentRef(x, merged, state); ok {
|
||||
return resolved
|
||||
}
|
||||
return x
|
||||
@@ -1687,11 +1699,16 @@ func resolveCodeExecArgumentValue(v any, merged map[string]any) any {
|
||||
}
|
||||
}
|
||||
|
||||
func lookupCodeExecArgumentRef(ref string, merged map[string]any) (any, bool) {
|
||||
func lookupCodeExecArgumentRef(ref string, merged map[string]any, state *runtime.CanvasState) (any, bool) {
|
||||
ref = strings.TrimSpace(ref)
|
||||
if ref == "" {
|
||||
return nil, false
|
||||
}
|
||||
if state != nil {
|
||||
if v, err := state.GetVar(ref); err == nil && v != nil {
|
||||
return v, true
|
||||
}
|
||||
}
|
||||
at := strings.Index(ref, "@")
|
||||
if at <= 0 || at >= len(ref)-1 {
|
||||
return nil, false
|
||||
|
||||
@@ -75,7 +75,7 @@ import (
|
||||
// selfManagedDefaultEndpoint is the canonical executor_manager
|
||||
// endpoint baked into the Python side. Operators override via
|
||||
// SANDBOX_EXECUTOR_MANAGER_URL.
|
||||
const selfManagedDefaultEndpoint = "http://sandbox-executor-manager:9385"
|
||||
const selfManagedDefaultEndpoint = "http://localhost:9385"
|
||||
|
||||
// SelfManagedProvider is the Go port of
|
||||
// `agent/sandbox/providers/self_managed.py::SelfManagedProvider`.
|
||||
|
||||
Reference in New Issue
Block a user