summaryrefslogtreecommitdiff
path: root/subagents/workflow.lua
diff options
context:
space:
mode:
Diffstat (limited to 'subagents/workflow.lua')
-rw-r--r--subagents/workflow.lua47
1 files changed, 16 insertions, 31 deletions
diff --git a/subagents/workflow.lua b/subagents/workflow.lua
index b1d3e46..3cf58d9 100644
--- a/subagents/workflow.lua
+++ b/subagents/workflow.lua
@@ -40,12 +40,14 @@
-- * Handles the callback never awaited are awaited ("all") after it returns,
-- purely so no child is orphaned; those results are discarded.
-- * Structured output is decoded from result.structured_json and validated
--- against output.schema. Validation prefers the `jsonschema` rock and falls
--- back to the small built-in subset validator below when it is absent --
--- that rock pulls in lrexlib-pcre, which needs a system PCRE and fails to
--- build on stock macOS, and a failed rock install would otherwise take the
--- whole extension down silently. A validation failure turns the result into
--- status "failed"; it is never reported as a successful structured result.
+-- against output.schema by the one validator below: the JSON Schema subset
+-- a child's output tool actually uses, ignoring keywords it does not know.
+-- There is deliberately no second, rock-dependent path -- `jsonschema` needs
+-- lrexlib-pcre and a system PCRE that stock macOS lacks, so it is not a
+-- declared dependency, and a validator picked by whether a rock happens to
+-- be installed would make the same output pass here and fail there. A
+-- validation failure turns the result into status "failed"; it is never
+-- reported as a successful structured result.
-- * The host seam is reached through `require("panto").ext` at call time, not
-- aliased at load time, matching subagents/spawn.lua so a test can install a
-- fake `panto` module before the first call rather than before the require.
@@ -58,8 +60,6 @@ local M = {}
local workflow_mt = { __name = "subagents.workflow" }
-M.workflow_mt = workflow_mt
-
-- ---------------------------------------------------------------------------
-- Host seam access
-- ---------------------------------------------------------------------------
@@ -117,16 +117,15 @@ local function json_encode(value)
return tostring(value)
end
-M.json_decode = json_decode
M.json_encode = json_encode
-- ---------------------------------------------------------------------------
-- Schema validation
-- ---------------------------------------------------------------------------
--- Built-in fallback validator: the JSON Schema subset that structured child
--- output actually uses. Anything it does not understand is ignored rather than
--- rejected, so an unrecognized keyword never fails a legitimate result.
+-- The validator: the JSON Schema subset that structured child output actually
+-- uses. Anything it does not understand is ignored rather than rejected, so an
+-- unrecognized keyword never fails a legitimate result.
local function is_array_like(value)
local count = 0
for key in pairs(value) do
@@ -259,23 +258,6 @@ local function check_schema(value, schema, path)
return true
end
-local function validator_for(schema)
- local ok, jsonschema = pcall(require, "jsonschema")
- if ok and type(jsonschema) == "table" and jsonschema.generate_validator then
- local generated_ok, generated = pcall(jsonschema.generate_validator, schema)
- if generated_ok and type(generated) == "function" then
- return generated
- end
- end
- return function(value)
- return check_schema(value, schema, "output")
- end
-end
-
-M.validate = function(value, schema)
- return validator_for(schema)(value)
-end
-
-- ---------------------------------------------------------------------------
-- Result shaping
-- ---------------------------------------------------------------------------
@@ -312,8 +294,11 @@ local function shape_result(result, handle)
return shaped
end
+ -- An empty tool input is a real provider case (a chat-style provider
+ -- finalizes an argument-less call with ""), and it is not a validation
+ -- failure: nothing was produced to validate.
local raw = shaped.structured_json
- if type(raw) ~= "string" or raw == "" then
+ if raw == nil or raw == "" then
return fail(shaped, "structured output missing: the child produced no structured result")
end
@@ -322,7 +307,7 @@ local function shape_result(result, handle)
return fail(shaped, "structured output failed validation: " .. tostring(decoded))
end
- local valid, message = validator_for(schema)(decoded)
+ local valid, message = check_schema(decoded, schema, "output")
if not valid then
return fail(shaped, "structured output failed validation: " .. tostring(message or "schema mismatch"))
end