feat(java): implement ParamSchema + ParamCoercion internals for Param (Phase 4.3)#1877
Conversation
…s-tool-as-lambda' into copilot/edburns1810-java-tool-ergonomics-tool-as-lambda-im Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
Fixes #1841 Adds two package-private internal helper classes in com.github.copilot.tool: - ParamSchema: runtime JSON Schema generation from Param<?> metadata. buildSchema() validates duplicate names; forType() mirrors the compile-time SchemaGenerator using java.lang.reflect.Class instead of javax.lang.model. - ParamCoercion: runtime argument coercion using existing ObjectMapper policy. coerce() resolves args → default → empty-optional → required-error in order. coerceDefault() parses string defaults into declared Java types. emptyOptionalOrNull() returns empty Optional variants for optional primitives. Both classes are package-private per resolution 3.8 (no public internal helpers). coerce() takes Map<String,Object> to avoid a cyclic rpc dependency. Updates Phase 4.3 checkbox in plan file. Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Adds extracted, package-private runtime helpers in the Java SDK to (a) build JSON Schema from Param<?> descriptors and (b) coerce invocation argument maps into typed Java values, intended as internal foundations for the Param<T>-based lambda tool ergonomics work (Phase 4.3 of #1810).
Changes:
- Added
ParamSchemato build JSON SchemaMap<String, Object>structures fromParam<?>...and mapClass<?>→ schema fragments. - Added
ParamCoercionto coerceMap<String,Object>invocation args into typed values and parse validated string defaults. - Updated the internal Phase 4 checklist document to mark Phase 4.3 complete.
Show a summary per file
| File | Description |
|---|---|
| java/src/main/java/com/github/copilot/tool/ParamSchema.java | New internal schema builder and Class<?>→schema mapper for Param<?> descriptors. |
| java/src/main/java/com/github/copilot/tool/ParamCoercion.java | New internal argument/default coercion helper for Param<T> invocation. |
| 1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/1810-ignorance-reduction-for-implementation-plan.md | Marks Phase 4.3 as completed in the implementation plan. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 5
- Review effort level: Low
…oercion - Add null guard for varargs array in buildSchema() - Clarify ParamSchema class Javadoc: simplified counterpart, not full parity - Clarify forType() Javadoc: flat type mapping only, no generics resolution - Clarify coerceDefault() Javadoc: ObjectMapper fallback is safety net only Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cross-SDK Consistency Review ✅This PR adds two package-private Java classes ( Cross-SDK AlignmentThe Java
AssessmentNo cross-SDK inconsistencies introduced. The
|
be5e8cb
into
edburns/1810-java-tool-ergonomics-tool-as-lambda
… (Phase 4.3) (#1877) * Initial plan * feat(java): implement schema + coercion internals for Param (Phase 4.3) Fixes #1841 Adds two package-private internal helper classes in com.github.copilot.tool: - ParamSchema: runtime JSON Schema generation from Param<?> metadata. buildSchema() validates duplicate names; forType() mirrors the compile-time SchemaGenerator using java.lang.reflect.Class instead of javax.lang.model. - ParamCoercion: runtime argument coercion using existing ObjectMapper policy. coerce() resolves args → default → empty-optional → required-error in order. coerceDefault() parses string defaults into declared Java types. emptyOptionalOrNull() returns empty Optional variants for optional primitives. Both classes are package-private per resolution 3.8 (no public internal helpers). coerce() takes Map<String,Object> to avoid a cyclic rpc dependency. Updates Phase 4.3 checkbox in plan file. Co-authored-by: edburns <75821+edburns@users.noreply.github.com> * fix(java): address Copilot code review comments on ParamSchema/ParamCoercion - Add null guard for varargs array in buildSchema() - Clarify ParamSchema class Javadoc: simplified counterpart, not full parity - Clarify forType() Javadoc: flat type mapping only, no generics resolution - Clarify coerceDefault() Javadoc: ObjectMapper fallback is safety net only Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(java): correct ParamSchema Javadoc - arrays do produce items schema Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: edburns <75821+edburns@users.noreply.github.com> Co-authored-by: Ed Burns <edburns@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Phase 4.3 of #1810. Adds the runtime schema/coercion layer that backs
Param<T>-based lambda tool definitions, as the internal foundation consumed by theToolDefinition.from*overloads added in Phase 4.2.New classes (
com.github.copilot.tool, package-private)ParamSchemabuildSchema(toolName, mapper, params...)— produces the fullMap<String,Object>JSON Schema; validates duplicate parameter names at construction time with a clear error identifying tool name and offending nameforType(Class<?>)— maps JavaClassto JSON Schema type descriptor; runtime counterpart to the compile-timeSchemaGenerator, covering the exact same type surface (primitives, String, UUID, temporal, enums, collections, arrays, maps, POJOs/records)ParamCoercioncoerce(args, param, mapper)— resolves invocation arg → string default → empty-optional → missing-required-error; delegates complex conversion toObjectMapper.convertValuematching existing policycoerceDefault(param, mapper)— parses validated string defaults into the declared Java typeemptyOptionalOrNull(type)— returns emptyOptionalInt/OptionalLong/OptionalDoubleornullKey constraints honored
coerce()takesMap<String,Object>rather thanToolInvocationto avoid atool→rpcpackage dependencyToolDefinition, maintaining behavioral parity with the baseline contract from Phase 2