Skip to content
Merged
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
28 changes: 20 additions & 8 deletions src/node/agent/node.lua
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ local function process_multiple_inputs(inputs)
if inputs.context and inputs.context.content ~= nil then
local context_content = inputs.context.content
if type(context_content) ~= "table" then
return nil, nil, nil, nil, "context must be a table/object"
return nil, nil, nil, nil, nil, "context must be a table/object"
end
input_context = context_content
end
Expand All @@ -509,7 +509,7 @@ local function process_multiple_inputs(inputs)
if inputs.agent_id and inputs.agent_id.content ~= nil then
local agent_id_content = inputs.agent_id.content
if type(agent_id_content) ~= "string" or agent_id_content == "" then
return nil, nil, nil, nil, "agent_id must be a non-empty string"
return nil, nil, nil, nil, nil, "agent_id must be a non-empty string"
end
agent_id_override = agent_id_content
end
Expand All @@ -518,14 +518,25 @@ local function process_multiple_inputs(inputs)
if inputs.model and inputs.model.content ~= nil then
local model_content = inputs.model.content
if type(model_content) ~= "string" or model_content == "" then
return nil, nil, nil, nil, "model must be a non-empty string"
return nil, nil, nil, nil, nil, "model must be a non-empty string"
end
model_override = model_content
end

local max_iterations_override = nil
if inputs.max_iterations and inputs.max_iterations.content ~= nil then
local max_iterations_content = tonumber(inputs.max_iterations.content)
if not max_iterations_content or max_iterations_content < 1
or max_iterations_content ~= math.floor(max_iterations_content) then
return nil, nil, nil, nil, nil, "max_iterations must be a positive integer"
end
max_iterations_override = max_iterations_content
end

local parts = {}
for key, input in pairs(inputs) do
if key ~= "context" and key ~= "agent_id" and key ~= "model" and input.content ~= nil then
if key ~= "context" and key ~= "agent_id" and key ~= "model" and key ~= "max_iterations"
and input.content ~= nil then
local content = input.content
if type(content) == "table" then
content = json.encode(content)
Expand All @@ -537,10 +548,10 @@ local function process_multiple_inputs(inputs)
end

if #parts == 0 then
return input_context, agent_id_override, model_override, "", nil
return input_context, agent_id_override, model_override, max_iterations_override, "", nil
end

return input_context, agent_id_override, model_override, table.concat(parts, "\n\n"), nil
return input_context, agent_id_override, model_override, max_iterations_override, table.concat(parts, "\n\n"), nil
end

local function validate_and_resolve_config(config)
Expand Down Expand Up @@ -1805,7 +1816,8 @@ local function run(args)
}, inputs_err)
end

local input_context, agent_id_override, model_override, input_data, input_err = process_multiple_inputs(inputs)
local input_context, agent_id_override, model_override, max_iterations_override, input_data, input_err =
process_multiple_inputs(inputs)
if input_err then
return n:fail({
code = agent_consts.ERROR.INPUT_VALIDATION_FAILED,
Expand Down Expand Up @@ -1917,7 +1929,7 @@ local function run(args)

local saved_state = ((args.node or {}).metadata or {}).state or {}
local iteration = saved_state.current_iteration or 0
local max_iterations = config.arena.max_iterations or agent_consts.DEFAULTS.MAX_ITERATIONS
local max_iterations = max_iterations_override or config.arena.max_iterations or agent_consts.DEFAULTS.MAX_ITERATIONS
local min_iterations = config.arena.min_iterations or agent_consts.DEFAULTS.MIN_ITERATIONS
local tool_calling = config.arena.tool_calling
local show_tool_calls = config.show_tool_calls ~= false
Expand Down
22 changes: 19 additions & 3 deletions src/node/agent/node_context_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,23 @@ local function define_tests()
-- An input_transform field whose expression resolves to nil produces
-- an entry with nil content; the reserved carriers read it as "not
-- provided", never as a malformed value.
local input_context, agent_id_override, model_override, input_data, err = process({
local input_context, agent_id_override, model_override, max_iterations_override, input_data, err = process({
context = { content = nil, metadata = {} },
model = { content = nil, metadata = {} },
agent_id = { content = nil, metadata = {} },
max_iterations = { content = nil, metadata = {} },
lead = { content = { name = "Jane" }, metadata = {} },
})
test.is_nil(err)
test.is_nil(input_context)
test.is_nil(agent_id_override)
test.is_nil(model_override)
test.is_nil(max_iterations_override)
test.is_true(input_data:find('<input key="lead">', 1, true) ~= nil)
end)

it("renders no input tag for a nil-content input", function()
local _, _, _, input_data, err = process({
local _, _, _, _, input_data, err = process({
empty = { content = nil, metadata = {} },
brief = { content = "text", metadata = {} },
})
Expand All @@ -72,18 +74,32 @@ local function define_tests()
end)

it("still merges a table context and applies string overrides", function()
local input_context, agent_id_override, model_override, input_data, err = process({
local input_context, agent_id_override, model_override, max_iterations_override, input_data, err = process({
context = { content = { kb_ids = { "kb-1" } }, metadata = {} },
model = { content = "class:fast", metadata = {} },
agent_id = { content = "ns:researcher", metadata = {} },
max_iterations = { content = 80, metadata = {} },
lead = { content = { name = "Jane" }, metadata = {} },
})
test.is_nil(err)
test.not_nil(input_context)
test.eq((input_context :: any).kb_ids[1], "kb-1")
test.eq(model_override, "class:fast")
test.eq(agent_id_override, "ns:researcher")
test.eq(max_iterations_override, 80)
test.is_true(input_data:find('<input key="context">', 1, true) == nil)
test.is_true(input_data:find('<input key="max_iterations">', 1, true) == nil)
end)

it("rejects a max_iterations input that is not a positive integer", function()
local _, _, _, _, _, err = process({
max_iterations = { content = "eighty", metadata = {} },
})
test.not_nil(err)
local _, _, _, _, _, err2 = process({
max_iterations = { content = -3, metadata = {} },
})
test.not_nil(err2)
end)
end)
end
Expand Down