Skip to content

Edburns/1810 java tool ergonomics tool as lambda seeking review#1895

Open
edburns wants to merge 56 commits into
mainfrom
edburns/1810-java-tool-ergonomics-tool-as-lambda-seeking-review
Open

Edburns/1810 java tool ergonomics tool as lambda seeking review#1895
edburns wants to merge 56 commits into
mainfrom
edburns/1810-java-tool-ergonomics-tool-as-lambda-seeking-review

Conversation

@edburns

@edburns edburns commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes: #1894

ADR-006: Inline tool definition with lambdas

Context and problem statement

ADR-005 introduced an ergonomic Java tools API based on @CopilotTool method annotations, @CopilotToolParam parameter annotations, and ToolDefinition.fromObject(...) for reflection-based tool registration. That model works well when teams define tools as methods on a class.

The next ergonomics goal is an inline style comparable to C# CopilotTool.DefineTool(...), where developers can define a tool at the call site without creating a separate tool container class.

For this decision, we evaluated two alternatives:

  • Method-reference registration (ToolDefinition.from(tools::setCurrentPhase))
  • Inline lambda registration (ToolDefinition.from(..., phase -> ...))

The key factor is metadata quality: tool name, description, parameter names, parameter descriptions, required/default semantics, and schema stability.

Considered options

Option 1: Method-reference API

Example:

ToolDefinition setPhase = ToolDefinition.from(tools::setCurrentPhase);

In this model, metadata is sourced from existing method-level annotations (@CopilotTool, @Param) on the referenced method.

Advantages:

  • Closest Java analog to C# method-group ergonomics
  • High-quality metadata with minimal additional API surface
  • Reuses ADR-005 metadata and invocation behavior directly

Drawbacks:

  • Not truly inline: still requires a declared method (and usually annotations) elsewhere
  • Does not solve the "define the whole tool at the call site" use case
  • Method-reference resolution adds runtime/reflection complexity

Option 2: Inline lambda API with explicit metadata

Example:

ToolDefinition setPhase = ToolDefinition.from(
        "set_current_phase",
        "Sets the current phase of the agent",
        Param.of(String.class, "phase", "The phase to transition to"),
        (String phase) -> {
            currentPhase = phase;
            return "Phase set to " + phase;
        });

In this model, handler logic is inline, and metadata is provided explicitly through Param.of(...) parameter definitions.

Advantages:

  • True inline authoring at the session construction site
  • No dependence on lambda parameter-name reflection or -parameters
  • Deterministic metadata and schema generation
  • Independent from annotation processing and generated companion classes

Drawbacks:

  • Slightly more verbose than method-reference style because metadata is explicit
  • Introduces new public API types for parameter definitions and typed lambda overloads
  • Requires careful API design to stay concise for common one-parameter tools

Decision outcome

Chosen: Option 2 for ADR-006 scope — inline lambda API with explicit metadata.

Rationale:

  1. The primary requirement for this ADR is inline definition. Option 2 satisfies it directly; Option 1 does not.
  2. Metadata quality is the critical requirement. Option 2 keeps metadata explicit and stable, instead of relying on fragile lambda introspection.
  3. Option 2 can ship independently of method-reference support and without changes to annotation processing.
  4. Option 2 preserves behavior parity with existing tool execution by delegating to ToolDefinition construction and current invocation semantics.

Option 1 remains valuable and can be added independently as a separate ergonomic layer. It is not blocked by this decision.

Design constraints and non-goals

Constraints for the inline lambda API:

  • Require explicit tool name and description.
  • Require explicit parameter metadata (at minimum name and type, with optional description/required/default).
  • Support both sync and async handlers (R and CompletableFuture<R>).
  • Keep result semantics aligned with existing behavior (String passthrough, void maps to "Success", non-string objects serialized to JSON).
  • Keep override/permission/defer flags available through options, consistent with existing ToolDefinition fields.

Non-goals for this ADR:

  • Replacing @CopilotTool/fromObject APIs.
  • Defining method-reference registration behavior in detail.
  • Introducing compile-time code generation for lambda metadata.

Consequences

The SDK now provides an explicit inline path for developers who prefer to keep tool declarations at session creation while preserving high-quality schema metadata. Implemented API families include:

  • ToolDefinition.from(name, description, [params...], handler) — sync handlers
  • ToolDefinition.fromAsync(name, description, [params...], asyncHandler) — async handlers returning CompletableFuture<R>
  • ToolDefinition.fromWithToolInvocation(...) — sync with ToolInvocation context injection
  • ToolDefinition.fromAsyncWithToolInvocation(...) — async with ToolInvocation context injection

Parameter metadata is defined using Param.of(type, name, description) for required parameters and Param.of(type, name, description, required, defaultValue) for optional parameters with defaults.

Fluent option modifiers (.skipPermission(boolean), .defer(ToolDefer), .overridesBuiltInTool(boolean)) allow post-construction customization.

The annotation-driven API from ADR-005 remains the recommended path for larger tool surfaces where co-locating metadata with method implementations improves maintainability. For usage examples and complete API coverage, see the Java SDK README.

Related work items

edburns and others added 30 commits July 2, 2026 12:13
Your branch is up to date with 'upstream/edburns/1810-java-tool-ergonomics-tool-as-lambda'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/1810-ignorance-reduction-for-implementation-plan.md
	modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260628-prompts.md
	new file:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260629-prompts.md

Signed-off-by: Ed Burns <edburns@microsoft.com>
…Phase 03.

modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/1810-ignorance-reduction-for-implementation-plan.md
modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260629-prompts.md

Signed-off-by: Ed Burns <edburns@microsoft.com>
modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/1810-ignorance-reduction-for-implementation-plan.md

- Check off the things already done.

modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260629-prompts.md

- GUTDODP
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Introduce `com.github.copilot.tool.Param<T>` — an immutable, fluent
runtime parameter metadata class for inline/lambda tool definitions.

Validation behavior:
- Rejects blank name/description
- Rejects required=true with non-empty defaultValue
- Validates default values against declared Class<T>

Includes comprehensive unit tests (ParamTest, 24 cases).
Updates Phase 4.1 checkbox in the implementation plan.
Automates the lifecycle of a child Task issue from 'assigned to Copilot'
through CI approval and review-agent feedback resolution, stopping just
before marking the PR as Ready for Review.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On branch edburns/1810-java-tool-ergonomics-tool-as-lambda
modified:   .github/skills/shepherd-task-to-ready/SKILL.md
modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260630-prompts.md

Signed-off-by: Ed Burns <edburns@microsoft.com>
…ix base branch

- Use 'gh run rerun' instead of fork-only approve API endpoint
- Ignore expected 'Block remove-before-merge paths' workflow failure
- Verify and fix PR base branch after creation (Copilot may target main)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Avoids race condition where Copilot targets main instead of the
specified base branch. Instruction is added to issue body before
assignment; base branch verification remains as fallback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The model should not mark checklist items as complete — that is the
human DRI's responsibility.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…to-ready

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On branch edburns/1810-java-tool-ergonomics-tool-as-lambda
modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260630-prompts.md

Signed-off-by: Ed Burns <edburns@microsoft.com>
Follow-up skill that takes a PR from Ready for Review through Copilot
code review comment resolution (done locally) and merge to the
specified base branch. Max 20 iterations.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…2) (#1857)

* Initial plan

* feat(java): implement ToolDefinition.from* overloads for lambda-defined tools (Phase 4.2)

Co-authored-by: edburns <75821+edburns@users.noreply.github.com>

* Fix review comments: typed defaults, array items schema, primitive cast

- buildSchemaFromParams: parse default values to declared type before
  placing in JSON schema (avoids String defaults for numeric/boolean)
- schemaForClass: emit items schema for Java array types using
  getComponentType() for schema fidelity
- coerceDefaultValue: use boxed valueOf() instead of type.cast() for
  primitive types to avoid ClassCastException

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix review round 3: ToolResultObject passthrough, Optional* schema

- formatResult: pass ToolResultObject through directly instead of
  JSON-serializing, preserving structured result semantics
- schemaForClass: add OptionalInt/OptionalLong/OptionalDouble support
  to match compile-time SchemaGenerator behavior

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix review round 4: Optional* coercion in coerceArg

- Return OptionalInt.empty()/OptionalLong.empty()/OptionalDouble.empty()
  for missing non-required params instead of null
- Construct Optional*.of(...) from Number when value is present
- Avoids NPE and aligns with annotation-processor behavior

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix review round 5: null-future guards, Optional* cast safety, @SInCE tags

- All async fromAsync*/fromAsyncWithToolInvocation handlers now check
  for null future and return failedFuture with clear NPE message
- Optional* coercion catches ClassCastException for non-numeric values
  and throws IllegalArgumentException with diagnostic message
- Fixed @SInCE 1.0.2 -> 1.0.6 on all new API entries (15 in
  ToolDefinition, 1 in Param)

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>
edburns and others added 23 commits July 2, 2026 12:13
modified:   .github/skills/shepherd-task-from-ready-to-merged-to-base/SKILL.md

- Instruct the agent to close the issue after merging.

modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260630-prompts.md

- GUTDODP

Signed-off-by: Ed Burns <edburns@microsoft.com>
Invokes shepherd-task-from-assignment-to-ready then
shepherd-task-from-ready-to-merged-to-base in sequence.
Only proceeds to Phase 2 if Phase 1 succeeds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
modified:   .github/skills/shepherd-task/SKILL.md

- Tell the agent to mark the task as complete.

modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260630-prompts.md

- GUTDODP

Signed-off-by: Ed Burns <edburns@microsoft.com>
…to issue body

The previous approach using inline --body with shell variable interpolation
stripped newlines from the original issue body, causing the Copilot cloud agent
to receive a wall of unformatted text and misinterpret the assignment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Skip the issue body prepend if it already starts with '**Base branch:**',
preventing double-prepending on retries after partial failures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reduces context window usage before entering the review-iteration-heavy
Phase 2, retaining only essential state (PR number, branch, inputs).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… (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>
The shepherd skill's PR polling only matched by title/branch regex,
which fails when Copilot uses descriptive names without the issue number.

Now uses three strategies per iteration:
A) Issue timeline API for cross-referenced PRs (most reliable)
B) PR body search for 'Fixes #N' references
C) Title/branch regex match (original fallback)

Also increased timeout from 10 to 15 minutes since Copilot can take
5-12 minutes to produce a PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Orchestrates two separate copilot --yolo sessions for Phase 1 and Phase 2,
with gh CLI verification between phases. Avoids context window exhaustion
by using independent copilot instances instead of /compact.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tion (#1879)

* Initial plan

* Phase 4.4: Add ToolDefinitionLambdaTest – unit tests for lambda tool API behavior and validation

Co-authored-by: edburns <75821+edburns@users.noreply.github.com>

* Address Copilot review: tighten test assertions

- requiredParam test: assert IllegalArgumentException directly (not
  generic Exception via .get()) and verify message mentions param name
- resultFormatting test: parse result as JSON and assert specific fields
  instead of loose string contains check

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>
GitHub's baseRefName API never includes the remote prefix (e.g., upstream/),
so normalize BaseBranch before comparison to avoid false failures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
new file:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260701-prompts.md
modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/1810-ignorance-reduction-for-implementation-plan.md

- When writing the new E2E test, rely on the existing skill.

Signed-off-by: Ed Burns <edburns@microsoft.com>
…1881)

* Initial plan

* Add Java lambda-based E2E tool definition coverage

Co-authored-by: edburns <75821+edburns@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>
Extract Steps 4-5 (approve pending workflow runs and wait for completion)
from shepherd-task-from-assignment-to-ready into a new standalone skill:
shepherd-task-approve-workflows-and-wait-for-completion.

The original skill now invokes the sub-skill by reference.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Insert invocations of shepherd-task-approve-workflows-and-wait-for-completion
before gathering review comments (Step 5), before re-requesting review
(Step 11), and before final checks (Step 14). Renumber all steps
sequentially (0-21).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260701-prompts.md

- GUTDODP

Signed-off-by: Ed Burns <edburns@microsoft.com>
Replace the body-prepend workaround with the REST API's
agent_assignment.base_branch field when assigning issues to Copilot.
This is the programmatic equivalent of selecting the branch in the
GitHub UI and guarantees Copilot creates its topic branch from
BASE_BRANCH instead of defaulting to main.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add three layers of reinforcement to ensure Copilot uses the correct
base branch:

1. More prominent body prepend using GitHub IMPORTANT callout syntax
   with explicit DO NOT instructions
2. Reinforcing comment posted immediately after assignment
3. Stronger fallback: if PR targets wrong base, fix it AND request
   Copilot rebase with a changes-requested review

This is critical because issue descriptions reference plan files that
only exist on the feature branch, not on main.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Your branch is up to date with 'upstream/edburns/1810-java-tool-ergonomics-tool-as-lambda'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260701-prompts.md

no changes added to commit (use "git add" and/or "git commit -a")

Signed-off-by: Ed Burns <edburns@microsoft.com>
)

* Initial plan

* [Java] Align inline tool docs with final lambda API and ADR links

- README: Added inline lambda tool authoring section with ToolDefinition.from(...) examples
- Documented Param.of(...) required/default behavior and fluent modifiers
- ADR-006: Updated to reflect final API (Param.of vs Params.of/ParamDef)
- ADR-006: Added ADR-005 cross-reference and README coverage note
- Plan: Marked Phase 4.6 as complete

Fixes #1884

Co-authored-by: edburns <75821+edburns@users.noreply.github.com>

* fix: add CompletableFuture import to async snippet and remove invalid ToolDefer.ALWAYS

- Added missing import statement to make the async handler code example
  self-contained and compilable.
- Removed ALWAYS from ToolDefer values list; enum only has NONE, AUTO, NEVER.

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>
Skills:

• `.github/skills/shepherd-task-approve-workflows-and-wait-for-completion/SKILL.md`
• `.github/skills/shepherd-task-from-assignment-to-ready/SKILL.md`
• `.github/skills/shepherd-task-from-ready-to-merged-to-base/SKILL.md`
• `.github/skills/shepherd-task/SKILL.md`

Scripts:

• `1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/shepherd-task.ps1`
• `1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/shepherd-task.sh`

This work is now being tracked in **Feature** #1893.
Copilot AI review requested due to automatic review settings July 2, 2026 16:19
@edburns edburns requested a review from a team as a code owner July 2, 2026 16:19

Copilot AI 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.

Pull request overview

This PR adds a new experimental Java “inline tool definition” API so callers can define Copilot tools at the call site using typed lambdas while providing explicit, stable metadata (tool name/description + parameter metadata), aligning with ADR-006’s decision to avoid fragile lambda introspection.

Changes:

  • Introduces com.github.copilot.tool.Param<T> for runtime parameter metadata (name/type/description/required/default).
  • Adds ToolDefinition.from* lambda factories (sync/async and ToolInvocation-injecting variants) plus fluent copy-style option modifiers (skipPermission, defer, overridesBuiltInTool).
  • Adds unit tests, an E2E integration test, and documentation/ADR updates describing the new API.
Show a summary per file
File Description
java/src/main/java/com/github/copilot/rpc/ToolDefinition.java Adds lambda-based tool factory overloads, result formatting, argument coercion, schema generation, and fluent option modifiers.
java/src/main/java/com/github/copilot/tool/Param.java New public experimental parameter-metadata type for inline lambda tools.
java/src/main/java/com/github/copilot/tool/ParamSchema.java New internal helper intended to map Param → JSON Schema (currently appears unused).
java/src/main/java/com/github/copilot/tool/ParamCoercion.java New internal helper intended to coerce args/defaults using ObjectMapper (currently appears unused).
java/src/test/java/com/github/copilot/tool/ParamTest.java Unit tests covering Param validation and immutability behavior.
java/src/test/java/com/github/copilot/rpc/ToolDefinitionLambdaTest.java Unit tests covering lambda-tool factories, schema/default semantics, modifiers, coercion, and result formatting.
java/src/test/java/com/github/copilot/e2e/ErgonomicToolDefinitionIT.java Adds an E2E scenario exercising the lambda-defined tool path.
java/README.md Documents the new inline lambda tool API and links ADR-006.
java/docs/adr/adr-006-tool-definition-inline.md Adds ADR-006 documenting the decision and constraints for inline tool definition with lambdas.
1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260628-prompts.md Adds iteration/prompt log artifact (directory name indicates it should not be merged).
1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/20260626-prompts.md Adds iteration/prompt log artifact (directory name indicates it should not be merged).
1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/1810-ignorance-reduction-for-implementation-plan.md Adds planning artifact for issue #1810 (directory name indicates it should not be merged).

Review details

  • Files reviewed: 9/9 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment on lines +19 to +36
/**
* Internal runtime helper: maps {@link Param} metadata to JSON Schema
* {@code Map} objects.
*
* <p>
* This class is a simplified runtime counterpart to the compile-time
* {@link SchemaGenerator}. It operates on {@code java.lang.reflect.Class}
* values instead of {@code javax.lang.model} mirrors, and produces {@link Map}
* instances rather than Java source-code literals. Unlike
* {@code SchemaGenerator}, it does not inspect generics or object members
* (records/POJOs) and therefore produces flat type mappings only (no
* {@code additionalProperties} or nested object {@code properties}). It does
* produce {@code items} for plain Java arrays via component-type recursion.
*
* <p>
* Package-private: not part of the public API.
*/
class ParamSchema {
Comment on lines +363 to +367
ToolHandler toolHandler = invocation -> {
T1 arg1 = coerceArg(invocation, p1, getConfiguredMapper());
R result = handler.apply(arg1);
return CompletableFuture.completedFuture(formatResult(result, getConfiguredMapper()));
};
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review ✅

This PR adds inline lambda-style tool definitions to the Java SDK, achieving parity with all other language implementations. No consistency gaps were found.

SDK Tool Definition API Map

SDK Inline Lambda API
Java (this PR) ToolDefinition.from(name, desc, params..., handler) / fromAsync(...)
.NET CopilotTool.DefineTool(delegate, CopilotToolOptions)
Node.js defineTool(name, { description, parameters, handler, ... })
Python @define_tool(...) / define_tool(name, description=..., handler=..., params_type=...)
Go DefineTool[T, U](name, description, handler)
Rust define_tool(name, description, handler) (derive feature)

All six SDKs now provide an inline closure/lambda/delegate style for tool definition. ✅

Shared Options — All Consistent

The three tool options also exist across all SDKs (using language-idiomatic naming):

Concept Java .NET Node.js Python Go Rust
Override built-in .overridesBuiltInTool(bool) OverridesBuiltInTool overridesBuiltInTool overrides_built_in_tool OverridesBuiltInTool overrides_built_in_tool
Skip permission .skipPermission(bool) SkipPermission skipPermission skip_permission SkipPermission skip_permission
Defer mode .defer(ToolDefer) Defer (Auto/Never) defer ("auto"/"never") defer ("auto"/"never") Defer (ToolDeferAuto/ToolDeferNever) field on Tool struct

The Java ToolDefer.AUTO / ToolDefer.NEVER enum values follow Java idiom and wire-serialize to the same "auto" / "never" string values used by the other SDKs — consistent. ✅

This PR closes the last gap in the inline tool definition feature surface across all language SDKs.

Generated by SDK Consistency Review Agent for issue #1895 · sonnet46 1.3M ·

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.

Seeking review: tool-as-lambda

3 participants