Skip to content

Commit 0dd75af

Browse files
committed
feat: add advanced usage documentation and getting started guide; refactor tool argument handling for improved type safety
1 parent e0b4e93 commit 0dd75af

8 files changed

Lines changed: 731 additions & 284 deletions

File tree

src/main/java/com/github/copilot/sdk/json/ToolDefinition.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,22 @@
2020
* <h2>Example Usage</h2>
2121
*
2222
* <pre>{@code
23+
* // Define a record for your tool's arguments
24+
* record WeatherArgs(String location) {
25+
* }
26+
*
2327
* var tool = ToolDefinition.create("get_weather", "Get the current weather for a location",
2428
* Map.of("type", "object", "properties",
2529
* Map.of("location", Map.of("type", "string", "description", "City name")), "required",
2630
* List.of("location")),
2731
* invocation -> {
28-
* String location = ((Map<String, Object>) invocation.getArguments()).get("location").toString();
29-
* return CompletableFuture.completedFuture(getWeatherData(location));
32+
* // Type-safe access with records (recommended)
33+
* WeatherArgs args = invocation.getArgumentsAs(WeatherArgs.class);
34+
* return CompletableFuture.completedFuture(getWeatherData(args.location()));
35+
*
36+
* // Or use Map-based access
37+
* // Map<String, Object> args = invocation.getArguments();
38+
* // String location = (String) args.get("location");
3039
* });
3140
* }</pre>
3241
*

src/main/java/com/github/copilot/sdk/json/ToolHandler.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,21 @@
1616
* <h2>Example Implementation</h2>
1717
*
1818
* <pre>{@code
19+
* // Option 1: Type-safe access with records (recommended)
20+
* record SearchArgs(String query) {
21+
* }
22+
*
1923
* ToolHandler handler = invocation -> {
20-
* Map<String, Object> args = (Map<String, Object>) invocation.getArguments();
21-
* String query = args.get("query").toString();
24+
* SearchArgs args = invocation.getArgumentsAs(SearchArgs.class);
25+
* String result = performSearch(args.query());
26+
* return CompletableFuture.completedFuture(result);
27+
* };
2228
*
23-
* // Perform the tool's action
29+
* // Option 2: Map-based access
30+
* ToolHandler handler = invocation -> {
31+
* Map<String, Object> args = invocation.getArguments();
32+
* String query = (String) args.get("query");
2433
* String result = performSearch(query);
25-
*
2634
* return CompletableFuture.completedFuture(result);
2735
* };
2836
* }</pre>

src/main/java/com/github/copilot/sdk/json/ToolInvocation.java

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@
44

55
package com.github.copilot.sdk.json;
66

7+
import java.util.Map;
8+
79
import com.fasterxml.jackson.annotation.JsonInclude;
10+
import com.fasterxml.jackson.annotation.JsonSetter;
11+
import com.fasterxml.jackson.core.type.TypeReference;
12+
import com.fasterxml.jackson.databind.JsonNode;
13+
import com.fasterxml.jackson.databind.ObjectMapper;
814

915
/**
1016
* Represents a tool invocation request from the AI assistant.
@@ -20,10 +26,14 @@
2026
@JsonInclude(JsonInclude.Include.NON_NULL)
2127
public final class ToolInvocation {
2228

29+
private static final ObjectMapper MAPPER = new ObjectMapper();
30+
private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<>() {
31+
};
32+
2333
private String sessionId;
2434
private String toolCallId;
2535
private String toolName;
26-
private Object arguments;
36+
private JsonNode argumentsNode;
2737

2838
/**
2939
* Gets the session ID where the tool was invoked.
@@ -91,26 +101,71 @@ public ToolInvocation setToolName(String toolName) {
91101
}
92102

93103
/**
94-
* Gets the arguments passed to the tool.
104+
* Gets the arguments passed to the tool as a Map.
105+
* <p>
106+
* The arguments are provided as a {@code Map<String, Object>} matching the
107+
* parameter schema defined in the tool's {@link ToolDefinition}. Values can be
108+
* accessed using standard Map operations.
109+
* <p>
110+
* For type-safe access, use {@link #getArgumentsAs(Class)} to deserialize
111+
* arguments into a record or POJO.
112+
*
113+
* @return the arguments as a Map, or null if no arguments
114+
* @see #getArgumentsAs(Class)
115+
*/
116+
public Map<String, Object> getArguments() {
117+
if (argumentsNode == null) {
118+
return null;
119+
}
120+
return MAPPER.convertValue(argumentsNode, MAP_TYPE);
121+
}
122+
123+
/**
124+
* Deserializes the tool arguments into the specified type.
95125
* <p>
96-
* This is typically a {@code Map<String, Object>} matching the parameter schema
97-
* defined in the tool's {@link ToolDefinition}.
126+
* This method provides type-safe access to tool arguments by converting the
127+
* JSON arguments into a record, POJO, or other compatible type.
98128
*
99-
* @return the arguments object
129+
* <pre>{@code
130+
* // Define a record for your tool's arguments
131+
* record WeatherArgs(String city) {
132+
* }
133+
*
134+
* // In your tool handler
135+
* WeatherArgs args = invocation.getArgumentsAs(WeatherArgs.class);
136+
* String city = args.city();
137+
* }</pre>
138+
*
139+
* @param <T>
140+
* the type to deserialize to
141+
* @param type
142+
* the class of the target type
143+
* @return the arguments deserialized as the specified type
144+
* @throws IllegalArgumentException
145+
* if deserialization fails
146+
* @since 1.0.0
100147
*/
101-
public Object getArguments() {
102-
return arguments;
148+
public <T> T getArgumentsAs(Class<T> type) {
149+
try {
150+
return MAPPER.treeToValue(argumentsNode, type);
151+
} catch (Exception e) {
152+
throw new IllegalArgumentException("Failed to deserialize arguments to " + type.getName(), e);
153+
}
103154
}
104155

105156
/**
106157
* Sets the tool arguments.
158+
* <p>
159+
* <strong>Note:</strong> This method is intended for internal SDK use and JSON
160+
* deserialization. Users typically do not need to call this method directly.
107161
*
108162
* @param arguments
109-
* the arguments object
163+
* the arguments as a JsonNode
110164
* @return this invocation for method chaining
111165
*/
112-
public ToolInvocation setArguments(Object arguments) {
113-
this.arguments = arguments;
166+
@JsonSetter("arguments")
167+
public ToolInvocation setArguments(JsonNode arguments) {
168+
this.argumentsNode = arguments;
114169
return this;
115170
}
116171
}

0 commit comments

Comments
 (0)