feat: implemented dynamic coercion for legacy tool argument aliases

- Added `normalizeSingleStringField` to dynamically map misplaced string inputs to required schema fields for single-argument tools.
- Integrated argument normalization into `validateToolArguments` to handle model-specific variations in JSON payloads during validation passes.
- Updated `coding-agent` streaming and rendering components to recognize `_input` as a legacy alias for `input` across various UI paths and logic flows.
- Refactored `hashlineEditParamsSchema` to strictly enforce the `input` field while maintaining support for legacy aliases via runtime coercion rather than schema definition.
- Corrected unit tests to reflect that `_input` is rejected by the strict schema but handled gracefully by the validation layer.
This commit is contained in:
can1357
2026-07-02 23:32:23 +02:00
parent cc1990a2ad
commit 2c8daf0578
13 changed files with 169 additions and 43 deletions
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Fixed
- Improved input detection for edit tool summary and body views
## [16.3.1] - 2026-07-02
### Changed
@@ -92,7 +92,7 @@ function fileEntry(d: Record<string, unknown>): FileEntry {
}
function Summary({ args, result }: ToolRenderProps): ReactNode {
const input = str(args.input);
const input = str(args.input) ?? str(args._input);
const paths = input ? inputPaths(input) : [];
const argPath = str(args.file_path) ?? str(args.path);
if (paths.length === 0 && argPath) paths.push(argPath);
@@ -187,7 +187,7 @@ function FileSection({ entry, fallbackPath }: { entry: FileEntry; fallbackPath?:
}
function Body({ args, result }: ToolRenderProps): ReactNode {
const input = str(args.input);
const input = str(args.input) ?? str(args._input);
const details = detailsRecord(result);
const perFile: FileEntry[] = [];
if (details && Array.isArray(details.perFileResults)) {
@@ -232,7 +232,7 @@ function Body({ args, result }: ToolRenderProps): ReactNode {
</KvGrid>
)}
{input !== null && input.length > 0 && <Output text={input} variant="code" maxLines={10} title="input" />}
{input === null && args.input !== undefined && <InvalidArg what="input" />}
{input === null && (args.input !== undefined || args._input !== undefined) && <InvalidArg what="input" />}
</>
);
}