Skip to content

Make orchestration run input usable: object MCP schema + JSON Logic inputMapping - #240

Merged
arantespp merged 3 commits into
mainfrom
claude/dazzling-archimedes-wsznne
Jun 23, 2026
Merged

Make orchestration run input usable: object MCP schema + JSON Logic inputMapping#240
arantespp merged 3 commits into
mainfrom
claude/dazzling-archimedes-wsznne

Conversation

@arantespp

@arantespp arantespp commented Jun 23, 2026

Copy link
Copy Markdown
Member

Two related changes that together make values passed to start-orchestration-run actually usable downstream.

1. fix(server): MCP tools advertise object-typed body fields as objects

The MCP tool schema generator (soatToolsHelpers.ts) collapsed every OpenAPI object body field to type: string, because getJsonSchemaType had no object branch. So start-orchestration-run advertised input as a string and object inputs arrived as null (state: {}). The OpenAPI spec already declared input as object, so this was purely a generator bug; no spec/SDK/CLI regeneration was needed.

  if (schemaType === 'array') return 'array';
+ if (schemaType === 'object') return 'object';
  return 'string';

Benefits every object-typed body field across all REST-backed MCP tools, not just orchestration runs.

2. feat(orchestrations): evaluate inputMapping values as JSON Logic

inputMapping values were resolved only as state.<path> strings — no literals, no inline computation. Each value is now evaluated as JSON Logic against the run state, reusing the same evaluator as transform/condition nodes:

Value Behaviour
String, number, boolean, array, multi-key object Literal, passed as-is
{"var": "key"} Resolved from state (state.key; missing → null)
Any other single-key object Evaluated (cat, >, if, arithmetic, …)
"input_mapping": {
  "language": "pt-BR",
  "documentId": { "var": "temaDocumentId" },
  "label": { "cat": ["Tema: ", { "var": "titulo" }] },
  "isLong": { ">": [{ "var": "wordCount" }, 500] }
}

This makes run input directly usable: values passed via input become initial state and can be referenced with {"var": "key"} — eliminating boilerplate transform nodes.

outputMapping is intentionally unchanged (still a state.<path> write target — JSON Logic is a read-only evaluator and cannot express an assignment destination).

⚠️ Breaking change

inputMapping values are no longer state.<key> path strings. A bare string is now a literal; use {"var": "key"} to read from state. The orchestrate-a-sonnet tutorial, module docs, smoke tests, and affected unit tests are migrated.

Tests (red/green TDD)

  • Feat files #1: getJsonSchemaType('object') and buildInputSchema object-prop tests (the red test was object → string).
  • Feat files #2: rewrote the applyInputMapping unit suite for JSON Logic semantics; replaced the two obsolete resolveFromState-branch REST tests with an end-to-end test asserting literal + run-input {var} + computed expression via required_action.context; added a live-server smoke assertion.

🤖 Generated with Claude Code

The MCP tool schema generator collapsed every OpenAPI `object` body field
to `type: string` because getJsonSchemaType lacked an `object` branch. This
made start-orchestration-run advertise its `input` field as a string, so
object inputs never reached the server and run state was never initialized
from the run input (input: null, state: {}).

Add the missing `object` mapping so object-typed body fields are advertised
correctly across all REST-backed MCP tools. The OpenAPI spec already declared
`input` as object, so no spec/SDK/CLI regeneration is needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01452qqr3rQwdrBTmGnwtLtc
@github-actions

Copy link
Copy Markdown

Deploy Outputs

Package Stack Output Key Output Value
@soat/website SoatWebsite-claude-dazzling-archimedes-wsznne BucketWebsiteURL http://soatwebsite-claude-dazzling-archimede-staticbucket-wcojk72qzyah.s3-website-us-east-1.amazonaws.com

inputMapping values were resolved only as `state.<path>` strings, so there
was no way to pass a literal or compute a derived value inline — every
constant or rename required a dedicated transform node, and run-time input
could not be referenced at all.

Each inputMapping value is now evaluated as JSON Logic against the run
state, reusing the same evaluator as transform and condition nodes:

- single-key objects are expressions — `{var: 'key'}` reads state.key,
  `{cat: [...]}`, `{'>': [...]}`, etc. compute derived values
- everything else (string, number, boolean, array, multi-key object) is a
  literal, passed through as-is

This makes start-orchestration-run input directly usable: values passed at
run time become initial state and can be referenced with `{var: 'key'}`.

BREAKING CHANGE: inputMapping values are no longer `state.<key>` path
strings. A bare string is now a literal; use `{var: 'key'}` to read from
state. outputMapping is unchanged (still a state path — JSON Logic cannot
express a write target). Tutorial, module docs, smoke tests, and unit tests
migrated to the new syntax.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01452qqr3rQwdrBTmGnwtLtc
@arantespp arantespp changed the title fix(server): MCP tools advertise object-typed body fields as objects Make orchestration run input usable: object MCP schema + JSON Logic inputMapping Jun 23, 2026
@arantespp
arantespp enabled auto-merge (squash) June 23, 2026 15:22
Removing resolveFromState dropped orchestrationNodeExecutors.ts branch
coverage to 64.13% (below the 65% gate). Add lib tests for the agent and
memory_write missing-id DomainError throws, restoring branch coverage to
66.3%.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01452qqr3rQwdrBTmGnwtLtc
@arantespp
arantespp merged commit 3cadc79 into main Jun 23, 2026
4 checks passed
@arantespp
arantespp deleted the claude/dazzling-archimedes-wsznne branch June 23, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants