Skip to content

Commit b95d9a8

Browse files
authored
Merge pull request #1414 from QwenLM/doc/qwencode-java
Doc/qwencode java
2 parents 6f39ae1 + ad3086f commit b95d9a8

File tree

3 files changed

+317
-4
lines changed

3 files changed

+317
-4
lines changed

docs/developers/_meta.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default {
1111
type: 'separator',
1212
},
1313
'sdk-typescript': 'Typescript SDK',
14+
'sdk-java': 'Java SDK(alpha)',
1415
'Dive Into Qwen Code': {
1516
title: 'Dive Into Qwen Code',
1617
type: 'separator',

docs/developers/sdk-java.md

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
# Qwen Code Java SDK
2+
3+
The Qwen Code Java SDK is a minimum experimental SDK for programmatic access to Qwen Code functionality. It provides a Java interface to interact with the Qwen Code CLI, allowing developers to integrate Qwen Code capabilities into their Java applications.
4+
5+
## Requirements
6+
7+
- Java >= 1.8
8+
- Maven >= 3.6.0 (for building from source)
9+
- qwen-code >= 0.5.0
10+
11+
### Dependencies
12+
13+
- **Logging**: ch.qos.logback:logback-classic
14+
- **Utilities**: org.apache.commons:commons-lang3
15+
- **JSON Processing**: com.alibaba.fastjson2:fastjson2
16+
- **Testing**: JUnit 5 (org.junit.jupiter:junit-jupiter)
17+
18+
## Installation
19+
20+
Add the following dependency to your Maven `pom.xml`:
21+
22+
```xml
23+
<dependency>
24+
<groupId>com.alibaba</groupId>
25+
<artifactId>qwencode-sdk</artifactId>
26+
<version>{$version}</version>
27+
</dependency>
28+
```
29+
30+
Or if using Gradle, add to your `build.gradle`:
31+
32+
```gradle
33+
implementation 'com.alibaba:qwencode-sdk:{$version}'
34+
```
35+
36+
## Building and Running
37+
38+
### Build Commands
39+
40+
```bash
41+
# Compile the project
42+
mvn compile
43+
44+
# Run tests
45+
mvn test
46+
47+
# Package the JAR
48+
mvn package
49+
50+
# Install to local repository
51+
mvn install
52+
```
53+
54+
## Quick Start
55+
56+
The simplest way to use the SDK is through the `QwenCodeCli.simpleQuery()` method:
57+
58+
```java
59+
public static void runSimpleExample() {
60+
List<String> result = QwenCodeCli.simpleQuery("hello world");
61+
result.forEach(logger::info);
62+
}
63+
```
64+
65+
For more advanced usage with custom transport options:
66+
67+
```java
68+
public static void runTransportOptionsExample() {
69+
TransportOptions options = new TransportOptions()
70+
.setModel("qwen3-coder-flash")
71+
.setPermissionMode(PermissionMode.AUTO_EDIT)
72+
.setCwd("./")
73+
.setEnv(new HashMap<String, String>() {{put("CUSTOM_VAR", "value");}})
74+
.setIncludePartialMessages(true)
75+
.setTurnTimeout(new Timeout(120L, TimeUnit.SECONDS))
76+
.setMessageTimeout(new Timeout(90L, TimeUnit.SECONDS))
77+
.setAllowedTools(Arrays.asList("read_file", "write_file", "list_directory"));
78+
79+
List<String> result = QwenCodeCli.simpleQuery("who are you, what are your capabilities?", options);
80+
result.forEach(logger::info);
81+
}
82+
```
83+
84+
For streaming content handling with custom content consumers:
85+
86+
```java
87+
public static void runStreamingExample() {
88+
QwenCodeCli.simpleQuery("who are you, what are your capabilities?",
89+
new TransportOptions().setMessageTimeout(new Timeout(10L, TimeUnit.SECONDS)), new AssistantContentSimpleConsumers() {
90+
91+
@Override
92+
public void onText(Session session, TextAssistantContent textAssistantContent) {
93+
logger.info("Text content received: {}", textAssistantContent.getText());
94+
}
95+
96+
@Override
97+
public void onThinking(Session session, ThingkingAssistantContent thingkingAssistantContent) {
98+
logger.info("Thinking content received: {}", thingkingAssistantContent.getThinking());
99+
}
100+
101+
@Override
102+
public void onToolUse(Session session, ToolUseAssistantContent toolUseContent) {
103+
logger.info("Tool use content received: {} with arguments: {}",
104+
toolUseContent, toolUseContent.getInput());
105+
}
106+
107+
@Override
108+
public void onToolResult(Session session, ToolResultAssistantContent toolResultContent) {
109+
logger.info("Tool result content received: {}", toolResultContent.getContent());
110+
}
111+
112+
@Override
113+
public void onOtherContent(Session session, AssistantContent<?> other) {
114+
logger.info("Other content received: {}", other);
115+
}
116+
117+
@Override
118+
public void onUsage(Session session, AssistantUsage assistantUsage) {
119+
logger.info("Usage information received: Input tokens: {}, Output tokens: {}",
120+
assistantUsage.getUsage().getInputTokens(), assistantUsage.getUsage().getOutputTokens());
121+
}
122+
}.setDefaultPermissionOperation(Operation.allow));
123+
logger.info("Streaming example completed.");
124+
}
125+
```
126+
127+
other examples see src/test/java/com/alibaba/qwen/code/cli/example
128+
129+
## Architecture
130+
131+
The SDK follows a layered architecture:
132+
133+
- **API Layer**: Provides the main entry points through `QwenCodeCli` class with simple static methods for basic usage
134+
- **Session Layer**: Manages communication sessions with the Qwen Code CLI through the `Session` class
135+
- **Transport Layer**: Handles the communication mechanism between the SDK and CLI process (currently using process transport via `ProcessTransport`)
136+
- **Protocol Layer**: Defines data structures for communication based on the CLI protocol
137+
- **Utils**: Common utilities for concurrent execution, timeout handling, and error management
138+
139+
## Key Features
140+
141+
### Permission Modes
142+
143+
The SDK supports different permission modes for controlling tool execution:
144+
145+
- **`default`**: Write tools are denied unless approved via `canUseTool` callback or in `allowedTools`. Read-only tools execute without confirmation.
146+
- **`plan`**: Blocks all write tools, instructing AI to present a plan first.
147+
- **`auto-edit`**: Auto-approve edit tools (edit, write_file) while other tools require confirmation.
148+
- **`yolo`**: All tools execute automatically without confirmation.
149+
150+
### Session Event Consumers and Assistant Content Consumers
151+
152+
The SDK provides two key interfaces for handling events and content from the CLI:
153+
154+
#### SessionEventConsumers Interface
155+
156+
The `SessionEventConsumers` interface provides callbacks for different types of messages during a session:
157+
158+
- `onSystemMessage`: Handles system messages from the CLI (receives Session and SDKSystemMessage)
159+
- `onResultMessage`: Handles result messages from the CLI (receives Session and SDKResultMessage)
160+
- `onAssistantMessage`: Handles assistant messages (AI responses) (receives Session and SDKAssistantMessage)
161+
- `onPartialAssistantMessage`: Handles partial assistant messages during streaming (receives Session and SDKPartialAssistantMessage)
162+
- `onUserMessage`: Handles user messages (receives Session and SDKUserMessage)
163+
- `onOtherMessage`: Handles other types of messages (receives Session and String message)
164+
- `onControlResponse`: Handles control responses (receives Session and CLIControlResponse)
165+
- `onControlRequest`: Handles control requests (receives Session and CLIControlRequest, returns CLIControlResponse)
166+
- `onPermissionRequest`: Handles permission requests (receives Session and CLIControlRequest<CLIControlPermissionRequest>, returns Behavior)
167+
168+
#### AssistantContentConsumers Interface
169+
170+
The `AssistantContentConsumers` interface handles different types of content within assistant messages:
171+
172+
- `onText`: Handles text content (receives Session and TextAssistantContent)
173+
- `onThinking`: Handles thinking content (receives Session and ThingkingAssistantContent)
174+
- `onToolUse`: Handles tool use content (receives Session and ToolUseAssistantContent)
175+
- `onToolResult`: Handles tool result content (receives Session and ToolResultAssistantContent)
176+
- `onOtherContent`: Handles other content types (receives Session and AssistantContent)
177+
- `onUsage`: Handles usage information (receives Session and AssistantUsage)
178+
- `onPermissionRequest`: Handles permission requests (receives Session and CLIControlPermissionRequest, returns Behavior)
179+
- `onOtherControlRequest`: Handles other control requests (receives Session and ControlRequestPayload, returns ControlResponsePayload)
180+
181+
#### Relationship Between the Interfaces
182+
183+
**Important Note on Event Hierarchy:**
184+
185+
- `SessionEventConsumers` is the **high-level** event processor that handles different message types (system, assistant, user, etc.)
186+
- `AssistantContentConsumers` is the **low-level** content processor that handles different types of content within assistant messages (text, tools, thinking, etc.)
187+
188+
**Processor Relationship:**
189+
190+
- `SessionEventConsumers``AssistantContentConsumers` (SessionEventConsumers uses AssistantContentConsumers to process content within assistant messages)
191+
192+
**Event Derivation Relationships:**
193+
194+
- `onAssistantMessage``onText`, `onThinking`, `onToolUse`, `onToolResult`, `onOtherContent`, `onUsage`
195+
- `onPartialAssistantMessage``onText`, `onThinking`, `onToolUse`, `onToolResult`, `onOtherContent`
196+
- `onControlRequest``onPermissionRequest`, `onOtherControlRequest`
197+
198+
**Event Timeout Relationships:**
199+
200+
Each event handler method has a corresponding timeout method that allows customizing the timeout behavior for that specific event:
201+
202+
- `onSystemMessage``onSystemMessageTimeout`
203+
- `onResultMessage``onResultMessageTimeout`
204+
- `onAssistantMessage``onAssistantMessageTimeout`
205+
- `onPartialAssistantMessage``onPartialAssistantMessageTimeout`
206+
- `onUserMessage``onUserMessageTimeout`
207+
- `onOtherMessage``onOtherMessageTimeout`
208+
- `onControlResponse``onControlResponseTimeout`
209+
- `onControlRequest``onControlRequestTimeout`
210+
211+
For AssistantContentConsumers timeout methods:
212+
213+
- `onText``onTextTimeout`
214+
- `onThinking``onThinkingTimeout`
215+
- `onToolUse``onToolUseTimeout`
216+
- `onToolResult``onToolResultTimeout`
217+
- `onOtherContent``onOtherContentTimeout`
218+
- `onPermissionRequest``onPermissionRequestTimeout`
219+
- `onOtherControlRequest``onOtherControlRequestTimeout`
220+
221+
**Default Timeout Values:**
222+
223+
- `SessionEventSimpleConsumers` default timeout: 180 seconds (Timeout.TIMEOUT_180_SECONDS)
224+
- `AssistantContentSimpleConsumers` default timeout: 60 seconds (Timeout.TIMEOUT_60_SECONDS)
225+
226+
**Timeout Hierarchy Requirements:**
227+
228+
For proper operation, the following timeout relationships should be maintained:
229+
230+
- `onAssistantMessageTimeout` return value should be greater than `onTextTimeout`, `onThinkingTimeout`, `onToolUseTimeout`, `onToolResultTimeout`, and `onOtherContentTimeout` return values
231+
- `onControlRequestTimeout` return value should be greater than `onPermissionRequestTimeout` and `onOtherControlRequestTimeout` return values
232+
233+
### Transport Options
234+
235+
The `TransportOptions` class allows configuration of how the SDK communicates with the Qwen Code CLI:
236+
237+
- `pathToQwenExecutable`: Path to the Qwen Code CLI executable
238+
- `cwd`: Working directory for the CLI process
239+
- `model`: AI model to use for the session
240+
- `permissionMode`: Permission mode that controls tool execution
241+
- `env`: Environment variables to pass to the CLI process
242+
- `maxSessionTurns`: Limits the number of conversation turns in a session
243+
- `coreTools`: List of core tools that should be available to the AI
244+
- `excludeTools`: List of tools to exclude from being available to the AI
245+
- `allowedTools`: List of tools that are pre-approved for use without additional confirmation
246+
- `authType`: Authentication type to use for the session
247+
- `includePartialMessages`: Enables receiving partial messages during streaming responses
248+
- `skillsEnable`: Enables or disables skills functionality for the session
249+
- `turnTimeout`: Timeout for a complete turn of conversation
250+
- `messageTimeout`: Timeout for individual messages within a turn
251+
- `resumeSessionId`: ID of a previous session to resume
252+
- `otherOptions`: Additional command-line options to pass to the CLI
253+
254+
### Session Control Features
255+
256+
- **Session creation**: Use `QwenCodeCli.newSession()` to create a new session with custom options
257+
- **Session management**: The `Session` class provides methods to send prompts, handle responses, and manage session state
258+
- **Session cleanup**: Always close sessions using `session.close()` to properly terminate the CLI process
259+
- **Session resumption**: Use `setResumeSessionId()` in `TransportOptions` to resume a previous session
260+
- **Session interruption**: Use `session.interrupt()` to interrupt a currently running prompt
261+
- **Dynamic model switching**: Use `session.setModel()` to change the model during a session
262+
- **Dynamic permission mode switching**: Use `session.setPermissionMode()` to change the permission mode during a session
263+
264+
### Thread Pool Configuration
265+
266+
The SDK uses a thread pool for managing concurrent operations with the following default configuration:
267+
268+
- **Core Pool Size**: 30 threads
269+
- **Maximum Pool Size**: 100 threads
270+
- **Keep-Alive Time**: 60 seconds
271+
- **Queue Capacity**: 300 tasks (using LinkedBlockingQueue)
272+
- **Thread Naming**: "qwen_code_cli-pool-{number}"
273+
- **Daemon Threads**: false
274+
- **Rejected Execution Handler**: CallerRunsPolicy
275+
276+
## Error Handling
277+
278+
The SDK provides specific exception types for different error scenarios:
279+
280+
- `SessionControlException`: Thrown when there's an issue with session control (creation, initialization, etc.)
281+
- `SessionSendPromptException`: Thrown when there's an issue sending a prompt or receiving a response
282+
- `SessionClosedException`: Thrown when attempting to use a closed session
283+
284+
## FAQ / Troubleshooting
285+
286+
### Q: Do I need to install the Qwen CLI separately?
287+
288+
A: yes, requires Qwen CLI 0.5.5 or higher.
289+
290+
### Q: What Java versions are supported?
291+
292+
A: The SDK requires Java 1.8 or higher.
293+
294+
### Q: How do I handle long-running requests?
295+
296+
A: The SDK includes timeout utilities. You can configure timeouts using the `Timeout` class in `TransportOptions`.
297+
298+
### Q: Why are some tools not executing?
299+
300+
A: This is likely due to permission modes. Check your permission mode settings and consider using `allowedTools` to pre-approve certain tools.
301+
302+
### Q: How do I resume a previous session?
303+
304+
A: Use the `setResumeSessionId()` method in `TransportOptions` to resume a previous session.
305+
306+
### Q: Can I customize the environment for the CLI process?
307+
308+
A: Yes, use the `setEnv()` method in `TransportOptions` to pass environment variables to the CLI process.
309+
310+
## License
311+
312+
Apache-2.0 - see [LICENSE](./LICENSE) for details.

packages/sdk-java/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
<logback-classic.version>1.3.16</logback-classic.version>
3434
<fastjson2.version>2.0.60</fastjson2.version>
3535
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
36-
<central-publishing-maven-plugin.version>9</central-publishing-maven-plugin.version>
37-
<maven-source-plugin.version>2</maven-source-plugin.version>
36+
<central-publishing-maven-plugin.version>0.8.0</central-publishing-maven-plugin.version>
37+
<maven-source-plugin.version>2.2.1</maven-source-plugin.version>
3838
<maven-javadoc-plugin.version>2.9.1</maven-javadoc-plugin.version>
3939
<maven-gpg-plugin.version>1.5</maven-gpg-plugin.version>
4040
</properties>
@@ -112,7 +112,7 @@
112112
<plugin>
113113
<groupId>org.sonatype.central</groupId>
114114
<artifactId>central-publishing-maven-plugin</artifactId>
115-
<version>0.${central-publishing-maven-plugin.version}.0</version>
115+
<version>${central-publishing-maven-plugin.version}</version>
116116
<extensions>true</extensions>
117117
<configuration>
118118
<publishingServerId>central</publishingServerId>
@@ -122,7 +122,7 @@
122122
<plugin>
123123
<groupId>org.apache.maven.plugins</groupId>
124124
<artifactId>maven-source-plugin</artifactId>
125-
<version>${maven-source-plugin.version}.2.1</version>
125+
<version>${maven-source-plugin.version}</version>
126126
<executions>
127127
<execution>
128128
<id>attach-sources</id>

0 commit comments

Comments
 (0)