Typed inputs on ActionSpec + templating at job-create time #47

Closed
opened 2026-04-15 10:19:53 +00:00 by timur · 0 comments
Owner

Motivation

hero_logic is refactoring nodes to be thin pointers to hero_proc actions. The plan on the hero_logic side:

  • Remove the action-configuration fields from hero_logic node cards (no more Model / System prompt / Script / Temperature / Timeout / Retry on the workflow card).
  • A node becomes { node_id, input_schema, output_schema, action_name, action_context } — just I/O typing and a reference to the action that runs it.
  • The card shows a read-only preview of the referenced action (name, interpreter, short summary) + a Configure in hero_proc ↗ deep-link for editing.
  • A brand-new node renders as a dashed placeholder with a Create in hero_proc ↗ button — the user jumps to hero_proc_ui, defines the action there, comes back, and binds the node to it.
  • The toolbar drops the AI / Python / Bash / Rhai / Transform / Wait buttons. It just has + Step — kind/interpreter is a property of the referenced action, not the node.

The gap

Workflow-level inputs (typed fields the user fills in when running a step) need to reach the action. Today hero_logic works around this by: action.get → render {{var}} placeholders in script + ai_config.system_prompt → send the pre-rendered ActionSpec to job.create. Awkward: action in storage has raw {{foo}} placeholders that hero_proc itself can't render; every step is fetch+mutate+repush.

Proposal

1. input_schema: Option<String> on ActionSpec

JSON Schema (serialized) declaring the inputs an action expects. Optional. Validated on action.set.

2. inputs: Option<Value> on JobCreateInput

Caller-supplied values for this invocation. Validated against the action's input_schema.

3. Templating at dispatch time

hero_proc renders {{var}} / {{nested.path}} inside the executor across:

  • spec.script (user prompt / script body)
  • spec.ai_config.system_prompt
  • spec.ai_config.model / temperature / max_tokens
  • spec.env values

Unresolved placeholders stay literal. Port interpolate_template from hero_logic/src/engine/node_executors.rs.

4. Shell interpreters: also expose inputs as env vars

Merge inputs into child process env as HERO_INPUT_* (uppercase) so shell scripts can read them without {{}} syntax.

Implementation checklist

hero_proc / hero_proc_lib

  • Add input_schema: Option<String> on ActionSpec (openrpc + model + db).
  • Add inputs: Option<Value> on JobCreateInput (openrpc + server RPC).
  • New hero_proc_lib::template module with interpolate_template.
  • In supervisor/executor.rs, before dispatching any spec, render script + ai_config.* + env values against inputs.
  • Merge inputs into child process env with a HERO_INPUT_* prefix.
  • Validate inputs against input_schema at job.create; surface error via RPC.
  • Reject action.set when input_schema is set but doesn't parse as JSON Schema.

hero_proc_ui

  • Action form: add a field-list editor for input_schema (reuse hero_logic's editor design).
  • Action detail: render input_schema read-only + a test run form that calls job.create with typed inputs.

hero_logic (follow-up)

  • Remove ai_config / script / interpreter fields from the workflow editor's node body.
  • Replace the action form on the card with an action-preview + Configure in hero_proc ↗ link.
  • Switch execute_action to job.create(action_name, context, inputs) — drop fetch+mutate+repush.
  • Drop per-interpreter toolbar items; single + Step button.
  • Remove interpolate_template from hero_logic (now in hero_proc).

Non-goals

  • Not moving hero_logic's output_format / output parsing here — that's a workflow-execution concern.
  • Not building a JSON Schema validator from scratch — use jsonschema crate.

References

  • hero_logic issue: lhumina_code/hero_logic#2
  • Current workaround: hero_logic/src/engine/node_executors.rs::execute_action.
  • Current gap points:
    • hero_proc_server/src/rpc/job.rs:54-84 — no inputs on JobCreateInput.
    • hero_proc_lib/src/db/actions/model.rs:159-218 — no input_schema on ActionSpec.
    • hero_proc_server/src/supervisor/executor.rs:54-67, 89-241 — dispatch is literal; no templating.

hero_aibroker — verified working

Earlier RFC flagged system_prompt drop in aibroker. Re-verified end-to-end: hero_proc correctly builds [{role: system, ...}, {role: user, ...}] messages array (supervisor/executor.rs:123-133), hero_aibroker::handle_ai_chat parses system-role messages correctly (api/mod.rs:330-351), and the model respects the system prompt. No aibroker change needed. My earlier finding was looking at the OpenAI-compat HTTP endpoint, not the JSON-RPC path hero_proc uses.

## Motivation `hero_logic` is refactoring nodes to be thin pointers to `hero_proc` actions. The plan on the `hero_logic` side: - Remove the action-configuration fields from `hero_logic` node cards (no more Model / System prompt / Script / Temperature / Timeout / Retry on the workflow card). - A node becomes `{ node_id, input_schema, output_schema, action_name, action_context }` — just I/O typing and a reference to the action that runs it. - The card shows a read-only **preview** of the referenced action (name, interpreter, short summary) + a **Configure in hero_proc ↗** deep-link for editing. - A brand-new node renders as a dashed placeholder with a **Create in hero_proc ↗** button — the user jumps to `hero_proc_ui`, defines the action there, comes back, and binds the node to it. - The toolbar drops the AI / Python / Bash / Rhai / Transform / Wait buttons. It just has `+ Step` — kind/interpreter is a property of the referenced action, not the node. ## The gap Workflow-level inputs (typed fields the user fills in when running a step) need to reach the action. Today `hero_logic` works around this by: `action.get` → render `{{var}}` placeholders in `script` + `ai_config.system_prompt` → send the pre-rendered `ActionSpec` to `job.create`. Awkward: action in storage has raw `{{foo}}` placeholders that hero_proc itself can't render; every step is fetch+mutate+repush. ## Proposal ### 1. `input_schema: Option<String>` on `ActionSpec` JSON Schema (serialized) declaring the inputs an action expects. Optional. Validated on `action.set`. ### 2. `inputs: Option<Value>` on `JobCreateInput` Caller-supplied values for this invocation. Validated against the action's `input_schema`. ### 3. Templating at dispatch time hero_proc renders `{{var}}` / `{{nested.path}}` inside the executor across: - `spec.script` (user prompt / script body) - `spec.ai_config.system_prompt` - `spec.ai_config.model` / `temperature` / `max_tokens` - `spec.env` values Unresolved placeholders stay literal. Port `interpolate_template` from `hero_logic/src/engine/node_executors.rs`. ### 4. Shell interpreters: also expose inputs as env vars Merge `inputs` into child process env as `HERO_INPUT_*` (uppercase) so shell scripts can read them without `{{}}` syntax. ## Implementation checklist **hero_proc / hero_proc_lib** - [ ] Add `input_schema: Option<String>` on `ActionSpec` (openrpc + model + db). - [ ] Add `inputs: Option<Value>` on `JobCreateInput` (openrpc + server RPC). - [ ] New `hero_proc_lib::template` module with `interpolate_template`. - [ ] In `supervisor/executor.rs`, before dispatching any spec, render `script` + `ai_config.*` + `env` values against `inputs`. - [ ] Merge `inputs` into child process env with a `HERO_INPUT_*` prefix. - [ ] Validate `inputs` against `input_schema` at `job.create`; surface error via RPC. - [ ] Reject `action.set` when `input_schema` is set but doesn't parse as JSON Schema. **hero_proc_ui** - [ ] Action form: add a field-list editor for `input_schema` (reuse hero_logic's editor design). - [ ] Action detail: render `input_schema` read-only + a `test run` form that calls `job.create` with typed inputs. **hero_logic** (follow-up) - [ ] Remove `ai_config` / `script` / interpreter fields from the workflow editor's node body. - [ ] Replace the action form on the card with an action-preview + `Configure in hero_proc ↗` link. - [ ] Switch `execute_action` to `job.create(action_name, context, inputs)` — drop fetch+mutate+repush. - [ ] Drop per-interpreter toolbar items; single `+ Step` button. - [ ] Remove `interpolate_template` from `hero_logic` (now in hero_proc). ## Non-goals - Not moving hero_logic's `output_format` / output parsing here — that's a workflow-execution concern. - Not building a JSON Schema validator from scratch — use `jsonschema` crate. ## References - hero_logic issue: https://forge.ourworld.tf/lhumina_code/hero_logic/issues/2 - Current workaround: `hero_logic/src/engine/node_executors.rs::execute_action`. - Current gap points: - `hero_proc_server/src/rpc/job.rs:54-84` — no `inputs` on `JobCreateInput`. - `hero_proc_lib/src/db/actions/model.rs:159-218` — no `input_schema` on `ActionSpec`. - `hero_proc_server/src/supervisor/executor.rs:54-67, 89-241` — dispatch is literal; no templating. ## hero_aibroker — verified working Earlier RFC flagged `system_prompt` drop in aibroker. Re-verified end-to-end: `hero_proc` correctly builds `[{role: system, ...}, {role: user, ...}]` messages array (`supervisor/executor.rs:123-133`), `hero_aibroker::handle_ai_chat` parses system-role messages correctly (`api/mod.rs:330-351`), and the model respects the system prompt. **No aibroker change needed.** My earlier finding was looking at the OpenAI-compat HTTP endpoint, not the JSON-RPC path hero_proc uses.
timur closed this issue 2026-04-15 10:57:48 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_proc#47
No description provided.