Skip to content

fix: convert V2 goal plan tool input to JSON Schema - #68

Closed
abeisleem wants to merge 2 commits into
prevalentWare:mainfrom
abeisleem:nxl/fix-v2-plan-tool-schema
Closed

abeisleem wants to merge 2 commits into
prevalentWare:mainfrom
abeisleem:nxl/fix-v2-plan-tool-schema

Conversation

@abeisleem

@abeisleem abeisleem commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

summary

  • Convert PlanToolSchema to draft-7 JSON Schema for the V2 update_goal_plan tool instead of putting Zod instances directly into properties.
  • Use input mode to preserve optional evidence and defaulted decisions; retain Zod parsing/refinements in the executor and leave V1 unchanged.
  • Add a regression test for the serialized schema, required fields, nested arrays, nullable evidence, bounds, and strict objects. Update the tracked server bundle without unrelated compiler-renaming churn.

On OpenCode 2.0.25 with plugin 0.1.59, ordinary OpenAI Responses requests fail before generation:

invalid_function_parameters: Invalid schema for function 'update_goal_plan':
"optional" is not valid under any of the schemas listed in the 'anyOf' keyword

v2ObjectSchema(planToolArgs) only wraps the supplied properties; it does not convert their Zod types into JSON Schema. This affects ordinary prompts even when no goal is active because the registered tool catalog accompanies model requests.

testing

  • Regression test fails on the old implementation and passes with the fix.
  • Lint, typecheck, build, and pack dry-run pass.
  • Focused V2 schema/plan tests: 3 pass, 0 fail.
  • Isolated lifecycle smoke passes on OpenCode 2.0.25 using the built plugin and a deterministic local model; validated the update_goal_plan JSON Schema with Ajv in all 10 actual model requests. No live provider credentials or user goal state used. The temporary smoke harness adapts the existing script's older API routes/provider package name to 2.0.25; these unrelated harness changes are not in this PR. Not tested against a live OpenAI endpoint.
  • Full suite: 360 pass, 2 fail (V1 paused-goal sampledAt clock mismatch and restart pending-attempt timeout). Untouched upstream also fails: 359 pass, 2 fail (restart pending-attempt timeout and V2 watchdog timing assertion). A separate V2 run showed watchdog timing failures too. These pre-existing/time-sensitive failures are outside this fix.

contribution disclosure

Implemented with OpenAI GPT-6.1 Sol through the OpenCode agent harness.

@danyel117 danyel117 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The schema conversion is sound in the local review, and lint, typecheck, 362 tests, build, and pack checks pass. This PR overlaps #70 for the same provider-schema bug, so please coordinate on one final fix to avoid merging two implementations. If this PR is the chosen one, please add Closes #69 and the AI model/agent harness used (or state that the change was manual) to the description, as CONTRIBUTING.md requires. Its fork CI is also awaiting workflow approval.

@abeisleem

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @danyel117. I recommend consolidating into #70 so we can ship one fix promptly rather than duplicate the work. I have offered our nested-schema regression assertions and complementary OpenCode 2.0.25 wire-schema verification there: #70 (comment)

I have also added the required AI model/harness attribution to this description (OpenAI GPT-6.1 Sol through OpenCode). I have not added Closes #69 here because I am proposing #70 as the issue-closing PR.

Please confirm that #70 is the chosen implementation; I will then close this PR as superseded. Happy to help with any remaining verification.

@SimSonic

SimSonic commented Oct 9, 2026

Copy link
Copy Markdown

DeepSeek the same:

image

baldassarreFe added a commit to baldassarreFe/opencode-goal-plugin that referenced this pull request Oct 9, 2026
…ld dist with minimal diff

Co-authored-by: abeisleem <abeisleem@users.noreply.github.com>
danyel117 pushed a commit that referenced this pull request Oct 10, 2026
)

* fix: emit provider-safe JSON Schema for update_goal_plan tool input

The V2 update_goal_plan registration passed raw zod objects from
planToolArgs as the tool input, so hosts serialized zod internals
(def/checks/shape/optional plus null-valued keywords like
maxLength/format) into the JSON Schema sent to providers. Providers
that strictly validate tool schemas (e.g. Mistral mistral-large-4)
reject those requests with 'Invalid tool schema', breaking every
session that includes the goal tools on such models.

Convert PlanToolSchema once via z.toJSONSchema and hand each
registration a deep copy so hosts or test frameworks that mutate a
received tool input cannot corrupt the shared schema. Runtime
argument validation is unchanged: planFromTool still parses through
PlanToolSchema.

* test: port nested plan schema assertions from #68; rebuild dist with minimal diff

Co-authored-by: abeisleem <abeisleem@users.noreply.github.com>

---------

Co-authored-by: abeisleem <abeisleem@users.noreply.github.com>
@danyel117

Copy link
Copy Markdown
Contributor

Thanks for the independent fix and schema regression coverage. PR #70 has now merged the provider-safe schema change and ported your nested-plan assertions with attribution, so I am closing this overlapping PR as superseded.

@danyel117 danyel117 closed this Oct 10, 2026
@abeisleem
abeisleem deleted the nxl/fix-v2-plan-tool-schema branch October 10, 2026 13:37
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.

3 participants