← Back to PRs

#12642: feat(tools): typed tool schemas for xAI/Grok compatibility

by 2nd-ren open 2026-02-09 12:23 View on GitHub →
agents stale
## Problem When using xAI Grok models with OpenClaw, tool calls frequently fail. The root cause is that several tool schemas use `Type.Object({}, { additionalProperties: true })` — which produces `{"type": "object"}` with **no defined properties** in the JSON Schema sent to the LLM. Claude infers the expected fields from natural-language descriptions, but Grok follows the schema literally and sends empty objects (e.g. `job: {}`), causing runtime validation failures. **Affected tools:** `cron-tool`, `browser-tool`, `message-tool` ## Solution Replace the loose/permissive object schemas with fully typed TypeBox definitions: - **cron-tool.ts**: Added `CronJobSchema`, `CronPatchSchema`, `CronScheduleSchema`, `CronPayloadSchema`, `CronDeliverySchema` with all fields, types, and enums. Uses a flattened-union pattern (single object with `kind` discriminator, variant fields as optional) to stay provider-friendly. - **browser-tool.schema.ts**: Replaced loose `fields` array items with typed `{ ref, targetId, value }` objects. - **message-tool.ts**: Replaced loose `card` object with typed Adaptive Card schema (`type`, `version`, `body` array with text block fields). - **transcript-policy.ts**: Added `"xai"` to `OPENAI_PROVIDERS` so xAI models get the correct transcript sanitization mode (`images-only`), matching their OpenAI-compatible API. ## Impact - **Backward compatible**: All schemas are strictly additive — existing fields and behavior are preserved. Models that previously worked (Claude, OpenAI, etc.) will continue to work identically since they already handle well-typed schemas. - **No runtime behavior changes**: The tool handlers still perform the same runtime validation. The only change is that the LLM now receives proper field definitions instead of empty objects. - **All existing tests pass** (855 test files, 5512 tests). ## Testing - Verified that `pnpm build` succeeds - Verified that `pnpm test` passes (all 5512 tests) - Manually tested cron job creation with xAI Grok — tool calls now include correct field values instead of empty objects ## Related This works in conjunction with a companion change in [pi-mono](https://github.com/badlogic/pi-mono) that adds configurable `strict` mode for xAI tool schemas (PR submitted separately). However, **this PR is independently valuable** — typed schemas improve tool reliability for all providers. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR replaces permissive `Type.Object({}, { additionalProperties: true })` tool parameter schemas with more explicit TypeBox object shapes for the cron tool (`job`/`patch` with schedule/payload/delivery sub-schemas), browser tool `fill.fields`, and message tool `card`. It also treats `xai` as an OpenAI-like provider in `resolveTranscriptPolicy` so xAI models get the OpenAI transcript sanitization behavior. These changes fit into the existing “flattened object schema” approach used elsewhere in the agents/tools layer to keep schemas provider-friendly while preserving runtime validation and normalization in the tool handlers. <h3>Confidence Score: 2/5</h3> - This PR is not safe to merge as-is due to a likely runtime crash in the Message tool schema construction. - Most changes are schema-tightening and should be low risk, but the updated `Type.Object` call in `message-tool.ts` appears to use an invalid signature (extra argument), which would throw during module evaluation and break tool initialization. Until that is corrected and validated, merge risk is high. - src/agents/tools/message-tool.ts <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs