inputs feature needs to be restored hero_proc #137

Closed
opened 2026-06-07 04:32:10 +00:00 by despiegk · 2 comments
Owner

⏺ inputs, input_schema, JobCreateInput, and HERO_INPUT_* are completely absent from the SDK. The entire §1.5 "typed inputs" section
documents a feature that no longer exists. Now I have everything I need. Let me make all the corrections:

dont forget to use the oschema

⏺ inputs, input_schema, JobCreateInput, and HERO_INPUT_* are completely absent from the SDK. The entire §1.5 "typed inputs" section documents a feature that no longer exists. Now I have everything I need. Let me make all the corrections: dont forget to use the oschema
despiegk added this to the ACTIVE project 2026-06-07 04:32:26 +00:00
despiegk changed title from inputs feature needs to be restored to inputs feature needs to be restored hero_proc 2026-06-07 04:32:32 +00:00
mahmoud self-assigned this 2026-06-08 09:55:03 +00:00
mahmoud added this to the now milestone 2026-06-08 09:55:09 +00:00
Owner

Implementation Spec for #137 — Restore typed inputs end-to-end

Root cause

The typed-inputs feature is half-present. The server runtime still works through the legacy db-RPC job.create path: crates/hero_proc_server/src/rpc/job.rs handle_create reads an optional inputs object and calls apply_inputs() (job.rs:132), which renders {{var}} / {{nested.path}} into spec.script, every spec.env value, and spec.ai_config.{system_prompt,model} (ai only), and injects HERO_INPUT_<UPPERCASE_KEY> for non-ai interpreters. The {{var}} engine lives in crates/hero_proc_server/src/actions/template.rs and Action.input_schema still persists and is exposed (oschema jobs/10_action.oschema:94; mapped at jobs_impl.rs:271/303/995).

What broke is the SDK surface. The multi-domain SDK creates jobs only through run_quick_submit(RunSpec) (jobs_impl.rs:2608). RunSpec (oschema/jobs/40_run.oschema:37) has no inputs field, and run_quick_submit builds each job from action_from_api(action) and persists it (jobs_impl.rs:2647-2669) without ever calling apply_inputs. The old flat job_create(JobCreateInput{spec,context,inputs}) was dropped in the domain merge (MIGRATION_REMAP.md:34), so inputs / JobCreateInput / HERO_INPUT_* now exist only in the docs (docs/api.md §1.5 and friends). The docs describe a feature the SDK can no longer reach.

Design (oschema-first, fully generated types)

Two complementary, oschema-driven changes — no hand-written wire types:

  1. RunSpec.inputs — add one field inputs: {str: any} to RunSpec. {str: any} generates HashMap<String, serde_json::Value> in both the server model and the SDK type. run_quick_submit converts it to a JSON object once and calls the existing apply_inputs for every action before the job is built. This fixes the actual bug and makes the quick-submit/run path honor inputs.

  2. job_create method — add job_create(spec: Action, context: str, inputs: {str: any}) -> str to the Jobs service in 90_rpc.oschema. The codegen packs multi-param methods into a per-method input struct (verified in herolib_macros), so this generates exactly:

    pub struct JobCreateInput { pub spec: Action, pub context: String, pub inputs: HashMap<String, serde_json::Value> }
    

    restoring the documented JobCreateInput{spec, context, inputs} as a generated type and jobs().job_create(...) as a generated SDK call. The server handler mirrors the existing job.rs handle_create (one-shot job, reuse apply_inputs) and returns the new job sid.

input_schema stays declarative (persisted + exposed, not enforced) — matching the current docs. The no-inputs path is unchanged: apply_inputs short-circuits on an empty map (job.rs:138), and empty inputs/context are valid defaults.

Files to modify

  • crates/hero_proc_server/oschema/jobs/40_run.oschema — add inputs: {str: any} to RunSpec.
  • crates/hero_proc_server/oschema/jobs/90_rpc.oschema — add the job_create(...) method to service Jobs.
  • crates/hero_proc_server/src/rpc/impls/jobs_impl.rs — thread spec.inputs into apply_inputs inside run_quick_submit; implement the new job_create trait method (reusing crate::rpc::job::apply_inputs).
  • crates/hero_proc_sdk/src/{factory.rs,builders.rs} — set inputs: Default::default() on the existing RunSpec { .. } literals so no-inputs callers still compile; add a small .inputs(..) builder convenience and surface job_create.
  • crates/hero_proc_admin/docs/{api.md,overview.md,service_specs.md,cli_reference.md} — reconcile §1.5 with the restored surface (and fix the stale hero_proc_lib/src/template.rs path; the engine is in hero_proc_server/src/actions/template.rs).

Implementation plan

  1. OSchema — edit 40_run.oschema and 90_rpc.oschema as above. Regenerate by building hero_proc_sdk; confirm the generated SDK types and OpenRPC json now contain RunSpec.inputs, JobCreateInput, and the job_create method. (Generated files are never hand-edited.) Dependencies: none.
  2. Server: run path — in run_quick_submit, build a serde_json::Value::Object from spec.inputs once, then apply_inputs(&mut action_spec, &inputs_value) for each action before constructing the Job. Dependencies: step 1.
  3. Server: job_create — implement the generated job_create trait method: action_from_api(&spec), apply_inputs, build the one-shot Job, persist, return the sid. Dependencies: step 1.
  4. SDK — add inputs: Default::default() to the RunSpec literals, an .inputs(..) setter on the run/job builders, and confirm jobs().job_create(..) is reachable. Dependencies: step 1.
  5. Docs — reconcile §1.5 and sibling docs with the restored API; fix the template path. Dependencies: none (do last).
  6. Verify — workspace build + clippy; live private daemon; the api.md greet example (two invocations) asserting rendered output and HERO_INPUT_*; the hero_proc_test harness.

Acceptance criteria

  • Typed inputs are passable through the multi-domain SDK (via RunSpec.inputs and JobCreateInput).
  • {{var}} / {{nested.path}} render in spec.script, every spec.env value, and ai_config.{system_prompt,model} (ai only); unresolved placeholders stay literal.
  • Non-ai interpreters get HERO_INPUT_<UPPERCASE_KEY> (strings verbatim, non-strings JSON-serialized).
  • input_schema persists and is exposed.
  • JobCreateInput / inputs / input_schema / HERO_INPUT_* exist in the SDK and §1.5 is accurate (the greet example actually works).
  • All new types come from the oschema (regenerated), not hand-written.
  • No-inputs path unchanged; workspace builds clean; clippy clean.

Notes

  • The core bug is run_quick_submit never calling apply_inputs; adding RunSpec.inputs without that call would silently drop inputs.
  • RunSpec.inputs applies one input set to every action in the run, which matches the single-action §1.5 use case; per-action inputs would be a future Action field, out of scope here.
  • Verification is via a private isolated test daemon (own socket + own --db-path), not the shared daemon.
## Implementation Spec for #137 — Restore typed inputs end-to-end ### Root cause The typed-inputs feature is half-present. The server runtime still works through the legacy db-RPC `job.create` path: `crates/hero_proc_server/src/rpc/job.rs` `handle_create` reads an optional `inputs` object and calls `apply_inputs()` (job.rs:132), which renders `{{var}}` / `{{nested.path}}` into `spec.script`, every `spec.env` value, and `spec.ai_config.{system_prompt,model}` (ai only), and injects `HERO_INPUT_<UPPERCASE_KEY>` for non-ai interpreters. The `{{var}}` engine lives in `crates/hero_proc_server/src/actions/template.rs` and `Action.input_schema` still persists and is exposed (oschema `jobs/10_action.oschema:94`; mapped at `jobs_impl.rs:271/303/995`). What broke is the SDK surface. The multi-domain SDK creates jobs only through `run_quick_submit(RunSpec)` (`jobs_impl.rs:2608`). `RunSpec` (`oschema/jobs/40_run.oschema:37`) has no `inputs` field, and `run_quick_submit` builds each job from `action_from_api(action)` and persists it (`jobs_impl.rs:2647-2669`) **without ever calling `apply_inputs`**. The old flat `job_create(JobCreateInput{spec,context,inputs})` was dropped in the domain merge (`MIGRATION_REMAP.md:34`), so `inputs` / `JobCreateInput` / `HERO_INPUT_*` now exist only in the docs (`docs/api.md` §1.5 and friends). The docs describe a feature the SDK can no longer reach. ### Design (oschema-first, fully generated types) Two complementary, oschema-driven changes — no hand-written wire types: 1. **`RunSpec.inputs`** — add one field `inputs: {str: any}` to `RunSpec`. `{str: any}` generates `HashMap<String, serde_json::Value>` in both the server model and the SDK type. `run_quick_submit` converts it to a JSON object once and calls the existing `apply_inputs` for every action before the job is built. This fixes the actual bug and makes the quick-submit/run path honor inputs. 2. **`job_create` method** — add `job_create(spec: Action, context: str, inputs: {str: any}) -> str` to the Jobs service in `90_rpc.oschema`. The codegen packs multi-param methods into a per-method input struct (verified in `herolib_macros`), so this generates exactly: ```rust pub struct JobCreateInput { pub spec: Action, pub context: String, pub inputs: HashMap<String, serde_json::Value> } ``` restoring the documented `JobCreateInput{spec, context, inputs}` as a generated type and `jobs().job_create(...)` as a generated SDK call. The server handler mirrors the existing `job.rs handle_create` (one-shot job, reuse `apply_inputs`) and returns the new job sid. `input_schema` stays declarative (persisted + exposed, not enforced) — matching the current docs. The no-inputs path is unchanged: `apply_inputs` short-circuits on an empty map (job.rs:138), and empty `inputs`/`context` are valid defaults. ### Files to modify - `crates/hero_proc_server/oschema/jobs/40_run.oschema` — add `inputs: {str: any}` to `RunSpec`. - `crates/hero_proc_server/oschema/jobs/90_rpc.oschema` — add the `job_create(...)` method to `service Jobs`. - `crates/hero_proc_server/src/rpc/impls/jobs_impl.rs` — thread `spec.inputs` into `apply_inputs` inside `run_quick_submit`; implement the new `job_create` trait method (reusing `crate::rpc::job::apply_inputs`). - `crates/hero_proc_sdk/src/{factory.rs,builders.rs}` — set `inputs: Default::default()` on the existing `RunSpec { .. }` literals so no-inputs callers still compile; add a small `.inputs(..)` builder convenience and surface `job_create`. - `crates/hero_proc_admin/docs/{api.md,overview.md,service_specs.md,cli_reference.md}` — reconcile §1.5 with the restored surface (and fix the stale `hero_proc_lib/src/template.rs` path; the engine is in `hero_proc_server/src/actions/template.rs`). ### Implementation plan 1. **OSchema** — edit `40_run.oschema` and `90_rpc.oschema` as above. Regenerate by building `hero_proc_sdk`; confirm the generated SDK types and OpenRPC json now contain `RunSpec.inputs`, `JobCreateInput`, and the `job_create` method. (Generated files are never hand-edited.) Dependencies: none. 2. **Server: run path** — in `run_quick_submit`, build a `serde_json::Value::Object` from `spec.inputs` once, then `apply_inputs(&mut action_spec, &inputs_value)` for each action before constructing the `Job`. Dependencies: step 1. 3. **Server: job_create** — implement the generated `job_create` trait method: `action_from_api(&spec)`, `apply_inputs`, build the one-shot `Job`, persist, return the sid. Dependencies: step 1. 4. **SDK** — add `inputs: Default::default()` to the `RunSpec` literals, an `.inputs(..)` setter on the run/job builders, and confirm `jobs().job_create(..)` is reachable. Dependencies: step 1. 5. **Docs** — reconcile §1.5 and sibling docs with the restored API; fix the template path. Dependencies: none (do last). 6. **Verify** — workspace build + clippy; live private daemon; the api.md greet example (two invocations) asserting rendered output and `HERO_INPUT_*`; the `hero_proc_test` harness. ### Acceptance criteria - [ ] Typed `inputs` are passable through the multi-domain SDK (via `RunSpec.inputs` and `JobCreateInput`). - [ ] `{{var}}` / `{{nested.path}}` render in `spec.script`, every `spec.env` value, and `ai_config.{system_prompt,model}` (ai only); unresolved placeholders stay literal. - [ ] Non-ai interpreters get `HERO_INPUT_<UPPERCASE_KEY>` (strings verbatim, non-strings JSON-serialized). - [ ] `input_schema` persists and is exposed. - [ ] `JobCreateInput` / `inputs` / `input_schema` / `HERO_INPUT_*` exist in the SDK and §1.5 is accurate (the greet example actually works). - [ ] All new types come from the oschema (regenerated), not hand-written. - [ ] No-inputs path unchanged; workspace builds clean; clippy clean. ### Notes - The core bug is `run_quick_submit` never calling `apply_inputs`; adding `RunSpec.inputs` without that call would silently drop inputs. - `RunSpec.inputs` applies one input set to every action in the run, which matches the single-action §1.5 use case; per-action inputs would be a future `Action` field, out of scope here. - Verification is via a private isolated test daemon (own socket + own `--db-path`), not the shared daemon.
Owner

Implemented — PR #140

Typed inputs are restored end-to-end on the multi-domain jobs surface, oschema-first.

Files changed

  • oschema: jobs/40_run.oschema (RunSpec.inputs), jobs/30_job.oschema (JobCreate struct), jobs/90_rpc.oschema (job_create method); openrpc/openrpc_jobs.json regenerated.
  • server: rpc/impls/jobs_impl.rs — thread RunSpec.inputs through apply_inputs in run_quick_submit; implement job_create reusing apply_inputs.
  • sdk: factory.rs + builders.rs — generated JobCreate/JobCreateInput surfaced; .input()/.inputs() on job/run builders; .input_schema() on ActionBuilder; job builder creates via job_create.
  • docs: docs/api.md typed-inputs section + banner reconciled; stale template path fixed.
  • test: tests/basic/jobs_quick.rs new typed_inputs_render_and_env case.

How inputs flow now
SDK JobCreateInput { req: JobCreate { spec, context, inputs } } (or RunSpec.inputs) → wire job_create / run_quick_submit → server renders {{var}}/{{nested.path}} into spec.script, every spec.env value, and (ai) ai_config, and injects HERO_INPUT_<UPPER> for non-ai interpreters → job persisted and dispatched. Empty inputs are a no-op, so the no-inputs path is unchanged. input_schema stays declarative (persisted + exposed).

Verification

  • cargo build --workspace clean; cargo clippy --workspace zero errors (feature crates clean under -D warnings).
  • Live-daemon e2e (greet example, private isolated daemon): two invocations render hi alice (count=3) / hi bob (count=7), HERO_INPUT_NAME is set in the job env, and input_schema round-trips. New test passes.
  • Remaining full-suite failures are pre-existing in the integration test crate (it does not compile on development without the StateOutput.value fix included here) and are unrelated to typed inputs; the inputs-adjacent uc40_job_inputs_map passes when run alone.

PR: #140 (development_restore_typed_inputs -> development)

## Implemented — PR #140 Typed inputs are restored end-to-end on the multi-domain jobs surface, oschema-first. **Files changed** - oschema: `jobs/40_run.oschema` (RunSpec.inputs), `jobs/30_job.oschema` (JobCreate struct), `jobs/90_rpc.oschema` (job_create method); `openrpc/openrpc_jobs.json` regenerated. - server: `rpc/impls/jobs_impl.rs` — thread RunSpec.inputs through `apply_inputs` in `run_quick_submit`; implement `job_create` reusing `apply_inputs`. - sdk: `factory.rs` + `builders.rs` — generated `JobCreate`/`JobCreateInput` surfaced; `.input()/.inputs()` on job/run builders; `.input_schema()` on `ActionBuilder`; job builder creates via `job_create`. - docs: `docs/api.md` typed-inputs section + banner reconciled; stale template path fixed. - test: `tests/basic/jobs_quick.rs` new `typed_inputs_render_and_env` case. **How inputs flow now** SDK `JobCreateInput { req: JobCreate { spec, context, inputs } }` (or `RunSpec.inputs`) → wire `job_create` / `run_quick_submit` → server renders `{{var}}`/`{{nested.path}}` into `spec.script`, every `spec.env` value, and (ai) `ai_config`, and injects `HERO_INPUT_<UPPER>` for non-ai interpreters → job persisted and dispatched. Empty inputs are a no-op, so the no-inputs path is unchanged. `input_schema` stays declarative (persisted + exposed). **Verification** - `cargo build --workspace` clean; `cargo clippy --workspace` zero errors (feature crates clean under `-D warnings`). - Live-daemon e2e (greet example, private isolated daemon): two invocations render `hi alice (count=3)` / `hi bob (count=7)`, `HERO_INPUT_NAME` is set in the job env, and `input_schema` round-trips. New test passes. - Remaining full-suite failures are pre-existing in the integration test crate (it does not compile on `development` without the `StateOutput.value` fix included here) and are unrelated to typed inputs; the inputs-adjacent `uc40_job_inputs_map` passes when run alone. PR: https://forge.ourworld.tf/lhumina_code/hero_proc/pulls/140 (development_restore_typed_inputs -> development)
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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#137
No description provided.