From 63801e8054fd022252e5367e07286ecc9144897c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Jul 2026 01:01:39 +0000 Subject: [PATCH 1/3] Initial plan From 6c5d86c81e16e320def76aa3f4e43c43b6f18aa0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Jul 2026 01:35:26 +0000 Subject: [PATCH 2/3] [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> --- ...rance-reduction-for-implementation-plan.md | 2 +- java/README.md | 65 +++++++++++++++++++ .../adr/adr-006-tool-definition-inline.md | 19 ++++-- 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/1810-ignorance-reduction-for-implementation-plan.md b/1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/1810-ignorance-reduction-for-implementation-plan.md index c546cb45f..25f5bb70f 100644 --- a/1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/1810-ignorance-reduction-for-implementation-plan.md +++ b/1810-java-tool-ergonomics-tool-as-lambda-remove-before-merge/1810-ignorance-reduction-for-implementation-plan.md @@ -634,7 +634,7 @@ After Phase 3 is resolved, implement in this order. - [X] 4.3 — Implement schema and coercion internals ([#1841](https://github.com/github/copilot-sdk/issues/1841)) - [X] 4.4 — Unit tests for API behavior and validation ([#1842](https://github.com/github/copilot-sdk/issues/1842)) - [X] 4.5 — E2E integration test ([#1843](https://github.com/github/copilot-sdk/issues/1843)) -- [ ] 4.6 — Documentation updates ([#1844](https://github.com/github/copilot-sdk/issues/1844)) +- [X] 4.6 — Documentation updates ([#1844](https://github.com/github/copilot-sdk/issues/1844)) ### 4.1 — Add public API types diff --git a/java/README.md b/java/README.md index 22824747b..44bfd41b1 100644 --- a/java/README.md +++ b/java/README.md @@ -165,6 +165,71 @@ public String onlyContext(ToolInvocation invocation) { ... } public String report(@CopilotToolParam("Phase") String phase, ToolInvocation invocation, @CopilotToolParam("Limit") int limit) { ... } ``` +## Inline lambda tool definitions (experimental) + +For inline tool authoring at the session construction site, use `ToolDefinition.from(...)` with explicit parameter metadata: + +```java +import com.github.copilot.rpc.ToolDefinition; +import com.github.copilot.rpc.ToolDefer; +import com.github.copilot.tool.Param; + +ToolDefinition search = ToolDefinition + .from( + "search_items", + "Searches indexed items by keyword", + Param.of(String.class, "keyword", "Search keyword"), + keyword -> "Searching for: " + keyword) + .skipPermission(true) + .defer(ToolDefer.AUTO); +``` + +### Parameter metadata with `Param.of(...)` + +`Param.of(type, name, description)` creates a required parameter. For optional parameters with defaults: + +```java +Param limit = Param.of(Integer.class, "limit", "Max results", false, "10"); +``` + +### Async handlers + +Use `fromAsync` for asynchronous tool handlers: + +```java +ToolDefinition fetchData = ToolDefinition.fromAsync( + "fetch_data", + "Fetches data from remote source", + Param.of(String.class, "url", "Data source URL"), + url -> CompletableFuture.supplyAsync(() -> fetchRemote(url)) +); +``` + +### ToolInvocation context injection + +Inline tools can access `ToolInvocation` runtime context using `fromWithToolInvocation`: + +```java +ToolDefinition reportPhase = ToolDefinition.fromWithToolInvocation( + "report_phase", + "Reports the current phase with invocation context", + Param.of(String.class, "phase", "The current phase"), + (phase, invocation) -> "phase=" + phase + ", toolCallId=" + invocation.getToolCallId() +); +``` + +For async with `ToolInvocation`, use `fromAsyncWithToolInvocation`. + +### Fluent option modifiers + +Chain fluent modifiers to set tool options: + +- `.skipPermission(boolean)` — bypass permission prompts +- `.defer(ToolDefer)` — control deferred execution (`AUTO`, `ALWAYS`, `NEVER`) +- `.overridesBuiltInTool(boolean)` — shadow built-in tools + +For design context and decision rationale, see [ADR-006](docs/adr/adr-006-tool-definition-inline.md). + ## Memory Sessions can opt into persistent memory, allowing the agent to read and write memory across turns. Memory is configured per session and applies to both `createSession` and `resumeSession`. diff --git a/java/docs/adr/adr-006-tool-definition-inline.md b/java/docs/adr/adr-006-tool-definition-inline.md index fb2b9bf8b..ad48527c1 100644 --- a/java/docs/adr/adr-006-tool-definition-inline.md +++ b/java/docs/adr/adr-006-tool-definition-inline.md @@ -2,7 +2,7 @@ ## Context and problem statement -ADR-005 introduced an ergonomic Java tools API based on `@CopilotTool` and `ToolDefinition.fromObject(...)`. That model works well when teams define tools as methods on a class. +[ADR-005](adr-005-tool-definition.md) 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. @@ -45,14 +45,14 @@ Example: ToolDefinition setPhase = ToolDefinition.from( "set_current_phase", "Sets the current phase of the agent", - Params.of(ParamDef.string("phase", "The phase to transition to")), + 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 a small parameter-definition DSL. +In this model, handler logic is inline, and metadata is provided explicitly through `Param.of(...)` parameter definitions. Advantages: @@ -98,9 +98,18 @@ Non-goals for this ADR: ## Consequences -If implemented, the SDK gains an explicit inline path for developers who prefer to keep tool declarations at session creation while preserving high-quality schema metadata. +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: -The annotation-driven API from ADR-005 remains the recommended path for larger tool surfaces where co-locating metadata with method implementations improves maintainability. +- `ToolDefinition.from(name, description, [params...], handler)` — sync handlers +- `ToolDefinition.fromAsync(name, description, [params...], asyncHandler)` — async handlers returning `CompletableFuture` +- `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](adr-005-tool-definition.md) 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 From aaa934b7d517336ef4397902b4d3483256aa8649 Mon Sep 17 00:00:00 2001 From: Ed Burns Date: Wed, 1 Jul 2026 21:43:10 -0400 Subject: [PATCH 3/3] 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> --- java/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/README.md b/java/README.md index 44bfd41b1..47d1f481e 100644 --- a/java/README.md +++ b/java/README.md @@ -197,6 +197,8 @@ Param limit = Param.of(Integer.class, "limit", "Max results", false, "1 Use `fromAsync` for asynchronous tool handlers: ```java +import java.util.concurrent.CompletableFuture; + ToolDefinition fetchData = ToolDefinition.fromAsync( "fetch_data", "Fetches data from remote source", @@ -225,7 +227,7 @@ For async with `ToolInvocation`, use `fromAsyncWithToolInvocation`. Chain fluent modifiers to set tool options: - `.skipPermission(boolean)` — bypass permission prompts -- `.defer(ToolDefer)` — control deferred execution (`AUTO`, `ALWAYS`, `NEVER`) +- `.defer(ToolDefer)` — control deferred execution (`AUTO`, `NEVER`) - `.overridesBuiltInTool(boolean)` — shadow built-in tools For design context and decision rationale, see [ADR-006](docs/adr/adr-006-tool-definition-inline.md).