mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-01-22 00:36:19 +00:00
Compare commits
3 Commits
feat/javas
...
doc/qwenco
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad3086f7dd | ||
|
|
8f3bbef575 | ||
|
|
c6ae0a8be7 |
@@ -11,6 +11,7 @@ export default {
|
|||||||
type: 'separator',
|
type: 'separator',
|
||||||
},
|
},
|
||||||
'sdk-typescript': 'Typescript SDK',
|
'sdk-typescript': 'Typescript SDK',
|
||||||
|
'sdk-java': 'Java SDK(alpha)',
|
||||||
'Dive Into Qwen Code': {
|
'Dive Into Qwen Code': {
|
||||||
title: 'Dive Into Qwen Code',
|
title: 'Dive Into Qwen Code',
|
||||||
type: 'separator',
|
type: 'separator',
|
||||||
|
|||||||
312
docs/developers/sdk-java.md
Normal file
312
docs/developers/sdk-java.md
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
# Qwen Code Java SDK
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Java >= 1.8
|
||||||
|
- Maven >= 3.6.0 (for building from source)
|
||||||
|
- qwen-code >= 0.5.0
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- **Logging**: ch.qos.logback:logback-classic
|
||||||
|
- **Utilities**: org.apache.commons:commons-lang3
|
||||||
|
- **JSON Processing**: com.alibaba.fastjson2:fastjson2
|
||||||
|
- **Testing**: JUnit 5 (org.junit.jupiter:junit-jupiter)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Add the following dependency to your Maven `pom.xml`:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>qwencode-sdk</artifactId>
|
||||||
|
<version>{$version}</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
Or if using Gradle, add to your `build.gradle`:
|
||||||
|
|
||||||
|
```gradle
|
||||||
|
implementation 'com.alibaba:qwencode-sdk:{$version}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building and Running
|
||||||
|
|
||||||
|
### Build Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Compile the project
|
||||||
|
mvn compile
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
mvn test
|
||||||
|
|
||||||
|
# Package the JAR
|
||||||
|
mvn package
|
||||||
|
|
||||||
|
# Install to local repository
|
||||||
|
mvn install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
The simplest way to use the SDK is through the `QwenCodeCli.simpleQuery()` method:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static void runSimpleExample() {
|
||||||
|
List<String> result = QwenCodeCli.simpleQuery("hello world");
|
||||||
|
result.forEach(logger::info);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For more advanced usage with custom transport options:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static void runTransportOptionsExample() {
|
||||||
|
TransportOptions options = new TransportOptions()
|
||||||
|
.setModel("qwen3-coder-flash")
|
||||||
|
.setPermissionMode(PermissionMode.AUTO_EDIT)
|
||||||
|
.setCwd("./")
|
||||||
|
.setEnv(new HashMap<String, String>() {{put("CUSTOM_VAR", "value");}})
|
||||||
|
.setIncludePartialMessages(true)
|
||||||
|
.setTurnTimeout(new Timeout(120L, TimeUnit.SECONDS))
|
||||||
|
.setMessageTimeout(new Timeout(90L, TimeUnit.SECONDS))
|
||||||
|
.setAllowedTools(Arrays.asList("read_file", "write_file", "list_directory"));
|
||||||
|
|
||||||
|
List<String> result = QwenCodeCli.simpleQuery("who are you, what are your capabilities?", options);
|
||||||
|
result.forEach(logger::info);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For streaming content handling with custom content consumers:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static void runStreamingExample() {
|
||||||
|
QwenCodeCli.simpleQuery("who are you, what are your capabilities?",
|
||||||
|
new TransportOptions().setMessageTimeout(new Timeout(10L, TimeUnit.SECONDS)), new AssistantContentSimpleConsumers() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onText(Session session, TextAssistantContent textAssistantContent) {
|
||||||
|
logger.info("Text content received: {}", textAssistantContent.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onThinking(Session session, ThingkingAssistantContent thingkingAssistantContent) {
|
||||||
|
logger.info("Thinking content received: {}", thingkingAssistantContent.getThinking());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onToolUse(Session session, ToolUseAssistantContent toolUseContent) {
|
||||||
|
logger.info("Tool use content received: {} with arguments: {}",
|
||||||
|
toolUseContent, toolUseContent.getInput());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onToolResult(Session session, ToolResultAssistantContent toolResultContent) {
|
||||||
|
logger.info("Tool result content received: {}", toolResultContent.getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOtherContent(Session session, AssistantContent<?> other) {
|
||||||
|
logger.info("Other content received: {}", other);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUsage(Session session, AssistantUsage assistantUsage) {
|
||||||
|
logger.info("Usage information received: Input tokens: {}, Output tokens: {}",
|
||||||
|
assistantUsage.getUsage().getInputTokens(), assistantUsage.getUsage().getOutputTokens());
|
||||||
|
}
|
||||||
|
}.setDefaultPermissionOperation(Operation.allow));
|
||||||
|
logger.info("Streaming example completed.");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
other examples see src/test/java/com/alibaba/qwen/code/cli/example
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
The SDK follows a layered architecture:
|
||||||
|
|
||||||
|
- **API Layer**: Provides the main entry points through `QwenCodeCli` class with simple static methods for basic usage
|
||||||
|
- **Session Layer**: Manages communication sessions with the Qwen Code CLI through the `Session` class
|
||||||
|
- **Transport Layer**: Handles the communication mechanism between the SDK and CLI process (currently using process transport via `ProcessTransport`)
|
||||||
|
- **Protocol Layer**: Defines data structures for communication based on the CLI protocol
|
||||||
|
- **Utils**: Common utilities for concurrent execution, timeout handling, and error management
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
|
### Permission Modes
|
||||||
|
|
||||||
|
The SDK supports different permission modes for controlling tool execution:
|
||||||
|
|
||||||
|
- **`default`**: Write tools are denied unless approved via `canUseTool` callback or in `allowedTools`. Read-only tools execute without confirmation.
|
||||||
|
- **`plan`**: Blocks all write tools, instructing AI to present a plan first.
|
||||||
|
- **`auto-edit`**: Auto-approve edit tools (edit, write_file) while other tools require confirmation.
|
||||||
|
- **`yolo`**: All tools execute automatically without confirmation.
|
||||||
|
|
||||||
|
### Session Event Consumers and Assistant Content Consumers
|
||||||
|
|
||||||
|
The SDK provides two key interfaces for handling events and content from the CLI:
|
||||||
|
|
||||||
|
#### SessionEventConsumers Interface
|
||||||
|
|
||||||
|
The `SessionEventConsumers` interface provides callbacks for different types of messages during a session:
|
||||||
|
|
||||||
|
- `onSystemMessage`: Handles system messages from the CLI (receives Session and SDKSystemMessage)
|
||||||
|
- `onResultMessage`: Handles result messages from the CLI (receives Session and SDKResultMessage)
|
||||||
|
- `onAssistantMessage`: Handles assistant messages (AI responses) (receives Session and SDKAssistantMessage)
|
||||||
|
- `onPartialAssistantMessage`: Handles partial assistant messages during streaming (receives Session and SDKPartialAssistantMessage)
|
||||||
|
- `onUserMessage`: Handles user messages (receives Session and SDKUserMessage)
|
||||||
|
- `onOtherMessage`: Handles other types of messages (receives Session and String message)
|
||||||
|
- `onControlResponse`: Handles control responses (receives Session and CLIControlResponse)
|
||||||
|
- `onControlRequest`: Handles control requests (receives Session and CLIControlRequest, returns CLIControlResponse)
|
||||||
|
- `onPermissionRequest`: Handles permission requests (receives Session and CLIControlRequest<CLIControlPermissionRequest>, returns Behavior)
|
||||||
|
|
||||||
|
#### AssistantContentConsumers Interface
|
||||||
|
|
||||||
|
The `AssistantContentConsumers` interface handles different types of content within assistant messages:
|
||||||
|
|
||||||
|
- `onText`: Handles text content (receives Session and TextAssistantContent)
|
||||||
|
- `onThinking`: Handles thinking content (receives Session and ThingkingAssistantContent)
|
||||||
|
- `onToolUse`: Handles tool use content (receives Session and ToolUseAssistantContent)
|
||||||
|
- `onToolResult`: Handles tool result content (receives Session and ToolResultAssistantContent)
|
||||||
|
- `onOtherContent`: Handles other content types (receives Session and AssistantContent)
|
||||||
|
- `onUsage`: Handles usage information (receives Session and AssistantUsage)
|
||||||
|
- `onPermissionRequest`: Handles permission requests (receives Session and CLIControlPermissionRequest, returns Behavior)
|
||||||
|
- `onOtherControlRequest`: Handles other control requests (receives Session and ControlRequestPayload, returns ControlResponsePayload)
|
||||||
|
|
||||||
|
#### Relationship Between the Interfaces
|
||||||
|
|
||||||
|
**Important Note on Event Hierarchy:**
|
||||||
|
|
||||||
|
- `SessionEventConsumers` is the **high-level** event processor that handles different message types (system, assistant, user, etc.)
|
||||||
|
- `AssistantContentConsumers` is the **low-level** content processor that handles different types of content within assistant messages (text, tools, thinking, etc.)
|
||||||
|
|
||||||
|
**Processor Relationship:**
|
||||||
|
|
||||||
|
- `SessionEventConsumers` → `AssistantContentConsumers` (SessionEventConsumers uses AssistantContentConsumers to process content within assistant messages)
|
||||||
|
|
||||||
|
**Event Derivation Relationships:**
|
||||||
|
|
||||||
|
- `onAssistantMessage` → `onText`, `onThinking`, `onToolUse`, `onToolResult`, `onOtherContent`, `onUsage`
|
||||||
|
- `onPartialAssistantMessage` → `onText`, `onThinking`, `onToolUse`, `onToolResult`, `onOtherContent`
|
||||||
|
- `onControlRequest` → `onPermissionRequest`, `onOtherControlRequest`
|
||||||
|
|
||||||
|
**Event Timeout Relationships:**
|
||||||
|
|
||||||
|
Each event handler method has a corresponding timeout method that allows customizing the timeout behavior for that specific event:
|
||||||
|
|
||||||
|
- `onSystemMessage` ↔ `onSystemMessageTimeout`
|
||||||
|
- `onResultMessage` ↔ `onResultMessageTimeout`
|
||||||
|
- `onAssistantMessage` ↔ `onAssistantMessageTimeout`
|
||||||
|
- `onPartialAssistantMessage` ↔ `onPartialAssistantMessageTimeout`
|
||||||
|
- `onUserMessage` ↔ `onUserMessageTimeout`
|
||||||
|
- `onOtherMessage` ↔ `onOtherMessageTimeout`
|
||||||
|
- `onControlResponse` ↔ `onControlResponseTimeout`
|
||||||
|
- `onControlRequest` ↔ `onControlRequestTimeout`
|
||||||
|
|
||||||
|
For AssistantContentConsumers timeout methods:
|
||||||
|
|
||||||
|
- `onText` ↔ `onTextTimeout`
|
||||||
|
- `onThinking` ↔ `onThinkingTimeout`
|
||||||
|
- `onToolUse` ↔ `onToolUseTimeout`
|
||||||
|
- `onToolResult` ↔ `onToolResultTimeout`
|
||||||
|
- `onOtherContent` ↔ `onOtherContentTimeout`
|
||||||
|
- `onPermissionRequest` ↔ `onPermissionRequestTimeout`
|
||||||
|
- `onOtherControlRequest` ↔ `onOtherControlRequestTimeout`
|
||||||
|
|
||||||
|
**Default Timeout Values:**
|
||||||
|
|
||||||
|
- `SessionEventSimpleConsumers` default timeout: 180 seconds (Timeout.TIMEOUT_180_SECONDS)
|
||||||
|
- `AssistantContentSimpleConsumers` default timeout: 60 seconds (Timeout.TIMEOUT_60_SECONDS)
|
||||||
|
|
||||||
|
**Timeout Hierarchy Requirements:**
|
||||||
|
|
||||||
|
For proper operation, the following timeout relationships should be maintained:
|
||||||
|
|
||||||
|
- `onAssistantMessageTimeout` return value should be greater than `onTextTimeout`, `onThinkingTimeout`, `onToolUseTimeout`, `onToolResultTimeout`, and `onOtherContentTimeout` return values
|
||||||
|
- `onControlRequestTimeout` return value should be greater than `onPermissionRequestTimeout` and `onOtherControlRequestTimeout` return values
|
||||||
|
|
||||||
|
### Transport Options
|
||||||
|
|
||||||
|
The `TransportOptions` class allows configuration of how the SDK communicates with the Qwen Code CLI:
|
||||||
|
|
||||||
|
- `pathToQwenExecutable`: Path to the Qwen Code CLI executable
|
||||||
|
- `cwd`: Working directory for the CLI process
|
||||||
|
- `model`: AI model to use for the session
|
||||||
|
- `permissionMode`: Permission mode that controls tool execution
|
||||||
|
- `env`: Environment variables to pass to the CLI process
|
||||||
|
- `maxSessionTurns`: Limits the number of conversation turns in a session
|
||||||
|
- `coreTools`: List of core tools that should be available to the AI
|
||||||
|
- `excludeTools`: List of tools to exclude from being available to the AI
|
||||||
|
- `allowedTools`: List of tools that are pre-approved for use without additional confirmation
|
||||||
|
- `authType`: Authentication type to use for the session
|
||||||
|
- `includePartialMessages`: Enables receiving partial messages during streaming responses
|
||||||
|
- `skillsEnable`: Enables or disables skills functionality for the session
|
||||||
|
- `turnTimeout`: Timeout for a complete turn of conversation
|
||||||
|
- `messageTimeout`: Timeout for individual messages within a turn
|
||||||
|
- `resumeSessionId`: ID of a previous session to resume
|
||||||
|
- `otherOptions`: Additional command-line options to pass to the CLI
|
||||||
|
|
||||||
|
### Session Control Features
|
||||||
|
|
||||||
|
- **Session creation**: Use `QwenCodeCli.newSession()` to create a new session with custom options
|
||||||
|
- **Session management**: The `Session` class provides methods to send prompts, handle responses, and manage session state
|
||||||
|
- **Session cleanup**: Always close sessions using `session.close()` to properly terminate the CLI process
|
||||||
|
- **Session resumption**: Use `setResumeSessionId()` in `TransportOptions` to resume a previous session
|
||||||
|
- **Session interruption**: Use `session.interrupt()` to interrupt a currently running prompt
|
||||||
|
- **Dynamic model switching**: Use `session.setModel()` to change the model during a session
|
||||||
|
- **Dynamic permission mode switching**: Use `session.setPermissionMode()` to change the permission mode during a session
|
||||||
|
|
||||||
|
### Thread Pool Configuration
|
||||||
|
|
||||||
|
The SDK uses a thread pool for managing concurrent operations with the following default configuration:
|
||||||
|
|
||||||
|
- **Core Pool Size**: 30 threads
|
||||||
|
- **Maximum Pool Size**: 100 threads
|
||||||
|
- **Keep-Alive Time**: 60 seconds
|
||||||
|
- **Queue Capacity**: 300 tasks (using LinkedBlockingQueue)
|
||||||
|
- **Thread Naming**: "qwen_code_cli-pool-{number}"
|
||||||
|
- **Daemon Threads**: false
|
||||||
|
- **Rejected Execution Handler**: CallerRunsPolicy
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
The SDK provides specific exception types for different error scenarios:
|
||||||
|
|
||||||
|
- `SessionControlException`: Thrown when there's an issue with session control (creation, initialization, etc.)
|
||||||
|
- `SessionSendPromptException`: Thrown when there's an issue sending a prompt or receiving a response
|
||||||
|
- `SessionClosedException`: Thrown when attempting to use a closed session
|
||||||
|
|
||||||
|
## FAQ / Troubleshooting
|
||||||
|
|
||||||
|
### Q: Do I need to install the Qwen CLI separately?
|
||||||
|
|
||||||
|
A: yes, requires Qwen CLI 0.5.5 or higher.
|
||||||
|
|
||||||
|
### Q: What Java versions are supported?
|
||||||
|
|
||||||
|
A: The SDK requires Java 1.8 or higher.
|
||||||
|
|
||||||
|
### Q: How do I handle long-running requests?
|
||||||
|
|
||||||
|
A: The SDK includes timeout utilities. You can configure timeouts using the `Timeout` class in `TransportOptions`.
|
||||||
|
|
||||||
|
### Q: Why are some tools not executing?
|
||||||
|
|
||||||
|
A: This is likely due to permission modes. Check your permission mode settings and consider using `allowedTools` to pre-approve certain tools.
|
||||||
|
|
||||||
|
### Q: How do I resume a previous session?
|
||||||
|
|
||||||
|
A: Use the `setResumeSessionId()` method in `TransportOptions` to resume a previous session.
|
||||||
|
|
||||||
|
### Q: Can I customize the environment for the CLI process?
|
||||||
|
|
||||||
|
A: Yes, use the `setEnv()` method in `TransportOptions` to pass environment variables to the CLI process.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Apache-2.0 - see [LICENSE](./LICENSE) for details.
|
||||||
@@ -204,7 +204,7 @@ The `SessionEventConsumers` interface provides callbacks for different types of
|
|||||||
The `AssistantContentConsumers` interface handles different types of content within assistant messages:
|
The `AssistantContentConsumers` interface handles different types of content within assistant messages:
|
||||||
|
|
||||||
- `onText`: Handles text content (receives Session and TextAssistantContent)
|
- `onText`: Handles text content (receives Session and TextAssistantContent)
|
||||||
- `onThinking`: Handles thinking content (receives Session and ThinkingAssistantContent)
|
- `onThinking`: Handles thinking content (receives Session and ThingkingAssistantContent)
|
||||||
- `onToolUse`: Handles tool use content (receives Session and ToolUseAssistantContent)
|
- `onToolUse`: Handles tool use content (receives Session and ToolUseAssistantContent)
|
||||||
- `onToolResult`: Handles tool result content (receives Session and ToolResultAssistantContent)
|
- `onToolResult`: Handles tool result content (receives Session and ToolResultAssistantContent)
|
||||||
- `onOtherContent`: Handles other content types (receives Session and AssistantContent)
|
- `onOtherContent`: Handles other content types (receives Session and AssistantContent)
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public static void runStreamingExample() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onThinking(Session session, ThinkingAssistantContent thingkingAssistantContent) {
|
public void onThinking(Session session, ThingkingAssistantContent thingkingAssistantContent) {
|
||||||
logger.info("Thinking content received: {}", thingkingAssistantContent.getThinking());
|
logger.info("Thinking content received: {}", thingkingAssistantContent.getThinking());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ The `SessionEventConsumers` interface provides callbacks for different types of
|
|||||||
The `AssistantContentConsumers` interface handles different types of content within assistant messages:
|
The `AssistantContentConsumers` interface handles different types of content within assistant messages:
|
||||||
|
|
||||||
- `onText`: Handles text content (receives Session and TextAssistantContent)
|
- `onText`: Handles text content (receives Session and TextAssistantContent)
|
||||||
- `onThinking`: Handles thinking content (receives Session and ThinkingAssistantContent)
|
- `onThinking`: Handles thinking content (receives Session and ThingkingAssistantContent)
|
||||||
- `onToolUse`: Handles tool use content (receives Session and ToolUseAssistantContent)
|
- `onToolUse`: Handles tool use content (receives Session and ToolUseAssistantContent)
|
||||||
- `onToolResult`: Handles tool result content (receives Session and ToolResultAssistantContent)
|
- `onToolResult`: Handles tool result content (receives Session and ToolResultAssistantContent)
|
||||||
- `onOtherContent`: Handles other content types (receives Session and AssistantContent)
|
- `onOtherContent`: Handles other content types (receives Session and AssistantContent)
|
||||||
|
|||||||
@@ -33,8 +33,8 @@
|
|||||||
<logback-classic.version>1.3.16</logback-classic.version>
|
<logback-classic.version>1.3.16</logback-classic.version>
|
||||||
<fastjson2.version>2.0.60</fastjson2.version>
|
<fastjson2.version>2.0.60</fastjson2.version>
|
||||||
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
|
||||||
<central-publishing-maven-plugin.version>9</central-publishing-maven-plugin.version>
|
<central-publishing-maven-plugin.version>0.8.0</central-publishing-maven-plugin.version>
|
||||||
<maven-source-plugin.version>2</maven-source-plugin.version>
|
<maven-source-plugin.version>2.2.1</maven-source-plugin.version>
|
||||||
<maven-javadoc-plugin.version>2.9.1</maven-javadoc-plugin.version>
|
<maven-javadoc-plugin.version>2.9.1</maven-javadoc-plugin.version>
|
||||||
<maven-gpg-plugin.version>1.5</maven-gpg-plugin.version>
|
<maven-gpg-plugin.version>1.5</maven-gpg-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.sonatype.central</groupId>
|
<groupId>org.sonatype.central</groupId>
|
||||||
<artifactId>central-publishing-maven-plugin</artifactId>
|
<artifactId>central-publishing-maven-plugin</artifactId>
|
||||||
<version>0.${central-publishing-maven-plugin.version}.0</version>
|
<version>${central-publishing-maven-plugin.version}</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<publishingServerId>central</publishingServerId>
|
<publishingServerId>central</publishingServerId>
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
<version>${maven-source-plugin.version}.2.1</version>
|
<version>${maven-source-plugin.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>attach-sources</id>
|
<id>attach-sources</id>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import com.alibaba.fastjson2.JSON;
|
|||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThinkingAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThingkingAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.behavior.Behavior.Operation;
|
import com.alibaba.qwen.code.cli.protocol.data.behavior.Behavior.Operation;
|
||||||
@@ -59,7 +59,7 @@ public class QwenCodeCli {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onThinking(Session session, ThinkingAssistantContent thingkingAssistantContent) {
|
public void onThinking(Session session, ThingkingAssistantContent thingkingAssistantContent) {
|
||||||
response.add(thingkingAssistantContent.getThinking());
|
response.add(thingkingAssistantContent.getThinking());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public interface AssistantContent<C> {
|
|||||||
/**
|
/**
|
||||||
* Represents thinking content from the assistant.
|
* Represents thinking content from the assistant.
|
||||||
*/
|
*/
|
||||||
interface ThinkingAssistantContent extends AssistantContent<String> {
|
interface ThingkingAssistantContent extends AssistantContent<String> {
|
||||||
/**
|
/**
|
||||||
* Gets the thinking content.
|
* Gets the thinking content.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.alibaba.qwen.code.cli.protocol.message.assistant.block;
|
package com.alibaba.qwen.code.cli.protocol.message.assistant.block;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONType;
|
import com.alibaba.fastjson2.annotation.JSONType;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThinkingAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThingkingAssistantContent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a thinking content block.
|
* Represents a thinking content block.
|
||||||
@@ -10,7 +10,7 @@ import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThinkingAssistan
|
|||||||
* @version $Id: 0.0.1
|
* @version $Id: 0.0.1
|
||||||
*/
|
*/
|
||||||
@JSONType(typeKey = "type", typeName = "thinking")
|
@JSONType(typeKey = "type", typeName = "thinking")
|
||||||
public class ThinkingBlock extends ContentBlock<String> implements ThinkingAssistantContent {
|
public class ThinkingBlock extends ContentBlock<String> implements ThingkingAssistantContent {
|
||||||
/**
|
/**
|
||||||
* The thinking content.
|
* The thinking content.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.alibaba.fastjson2.annotation.JSONField;
|
|||||||
import com.alibaba.fastjson2.annotation.JSONType;
|
import com.alibaba.fastjson2.annotation.JSONType;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThinkingAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThingkingAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,7 +152,7 @@ public class ContentBlockDeltaEvent extends StreamEvent {
|
|||||||
* Represents a thinking delta.
|
* Represents a thinking delta.
|
||||||
*/
|
*/
|
||||||
@JSONType(typeKey = "type", typeName = "thinking_delta")
|
@JSONType(typeKey = "type", typeName = "thinking_delta")
|
||||||
public static class ContentBlockDeltaThinking extends ContentBlockDelta<String> implements ThinkingAssistantContent {
|
public static class ContentBlockDeltaThinking extends ContentBlockDelta<String> implements ThingkingAssistantContent {
|
||||||
/**
|
/**
|
||||||
* The thinking content.
|
* The thinking content.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.alibaba.qwen.code.cli.session.event.consumers;
|
|||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThinkingAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThingkingAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.behavior.Behavior;
|
import com.alibaba.qwen.code.cli.protocol.data.behavior.Behavior;
|
||||||
@@ -35,7 +35,7 @@ public interface AssistantContentConsumers {
|
|||||||
* @param session The session
|
* @param session The session
|
||||||
* @param thingkingAssistantContent The thinking content from the assistant
|
* @param thingkingAssistantContent The thinking content from the assistant
|
||||||
*/
|
*/
|
||||||
void onThinking(Session session, ThinkingAssistantContent thingkingAssistantContent);
|
void onThinking(Session session, ThingkingAssistantContent thingkingAssistantContent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles tool use content from the assistant.
|
* Handles tool use content from the assistant.
|
||||||
@@ -128,7 +128,7 @@ public interface AssistantContentConsumers {
|
|||||||
* @param thingkingAssistantContent The thinking content from the assistant
|
* @param thingkingAssistantContent The thinking content from the assistant
|
||||||
* @return The timeout for thinking handling
|
* @return The timeout for thinking handling
|
||||||
*/
|
*/
|
||||||
Timeout onThinkingTimeout(Session session, ThinkingAssistantContent thingkingAssistantContent);
|
Timeout onThinkingTimeout(Session session, ThingkingAssistantContent thingkingAssistantContent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets timeout for tool use handling.
|
* Gets timeout for tool use handling.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.alibaba.qwen.code.cli.session.event.consumers;
|
|||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThinkingAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThingkingAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.behavior.Allow;
|
import com.alibaba.qwen.code.cli.protocol.data.behavior.Allow;
|
||||||
@@ -38,7 +38,7 @@ public class AssistantContentSimpleConsumers implements AssistantContentConsumer
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onThinking(Session session, ThinkingAssistantContent thingkingAssistantContent) {
|
public void onThinking(Session session, ThingkingAssistantContent thingkingAssistantContent) {
|
||||||
log.debug("Received thingkingAssistantContent {}", thingkingAssistantContent.getThinking());
|
log.debug("Received thingkingAssistantContent {}", thingkingAssistantContent.getThinking());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ public class AssistantContentSimpleConsumers implements AssistantContentConsumer
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Timeout onThinkingTimeout(Session session, ThinkingAssistantContent thingkingAssistantContent) {
|
public Timeout onThinkingTimeout(Session session, ThingkingAssistantContent thingkingAssistantContent) {
|
||||||
return defaultEventTimeout;
|
return defaultEventTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import java.util.Optional;
|
|||||||
|
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThinkingAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThingkingAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
||||||
@@ -99,9 +99,9 @@ public class SessionEventSimpleConsumers implements SessionEventConsumers {
|
|||||||
MyConcurrentUtils.runAndWait(() -> assistantContentConsumers.onText(session, (TextAssistantContent) assistantContent),
|
MyConcurrentUtils.runAndWait(() -> assistantContentConsumers.onText(session, (TextAssistantContent) assistantContent),
|
||||||
Optional.ofNullable(assistantContentConsumers.onTextTimeout(session, (TextAssistantContent) assistantContent))
|
Optional.ofNullable(assistantContentConsumers.onTextTimeout(session, (TextAssistantContent) assistantContent))
|
||||||
.orElse(defaultEventTimeout));
|
.orElse(defaultEventTimeout));
|
||||||
} else if (assistantContent instanceof ThinkingAssistantContent) {
|
} else if (assistantContent instanceof ThingkingAssistantContent) {
|
||||||
MyConcurrentUtils.runAndWait(() -> assistantContentConsumers.onThinking(session, (ThinkingAssistantContent) assistantContent),
|
MyConcurrentUtils.runAndWait(() -> assistantContentConsumers.onThinking(session, (ThingkingAssistantContent) assistantContent),
|
||||||
Optional.ofNullable(assistantContentConsumers.onThinkingTimeout(session, (ThinkingAssistantContent) assistantContent))
|
Optional.ofNullable(assistantContentConsumers.onThinkingTimeout(session, (ThingkingAssistantContent) assistantContent))
|
||||||
.orElse(defaultEventTimeout));
|
.orElse(defaultEventTimeout));
|
||||||
} else if (assistantContent instanceof ToolUseAssistantContent) {
|
} else if (assistantContent instanceof ToolUseAssistantContent) {
|
||||||
MyConcurrentUtils.runAndWait(() -> assistantContentConsumers.onToolUse(session, (ToolUseAssistantContent) assistantContent),
|
MyConcurrentUtils.runAndWait(() -> assistantContentConsumers.onToolUse(session, (ToolUseAssistantContent) assistantContent),
|
||||||
|
|||||||
@@ -64,5 +64,5 @@ public class Timeout {
|
|||||||
/**
|
/**
|
||||||
* A timeout of 30 minutes.
|
* A timeout of 30 minutes.
|
||||||
*/
|
*/
|
||||||
public static final Timeout TIMEOUT_30_MINUTES = new Timeout(30L, TimeUnit.MINUTES);
|
public static final Timeout TIMEOUT_30_MINUTES = new Timeout(60L, TimeUnit.MINUTES);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.alibaba.qwen.code.cli.example;
|
|||||||
import com.alibaba.qwen.code.cli.QwenCodeCli;
|
import com.alibaba.qwen.code.cli.QwenCodeCli;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThinkingAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThingkingAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
||||||
@@ -78,7 +78,7 @@ public class QuickStartExample {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onThinking(Session session, ThinkingAssistantContent thingkingAssistantContent) {
|
public void onThinking(Session session, ThingkingAssistantContent thingkingAssistantContent) {
|
||||||
logger.info("Thinking content received: {}", thingkingAssistantContent.getThinking());
|
logger.info("Thinking content received: {}", thingkingAssistantContent.getThinking());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import com.alibaba.fastjson2.JSON;
|
|||||||
import com.alibaba.qwen.code.cli.QwenCodeCli;
|
import com.alibaba.qwen.code.cli.QwenCodeCli;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThinkingAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThingkingAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
||||||
@@ -219,7 +219,7 @@ public class SessionExample {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onThinking(Session session, ThinkingAssistantContent thingkingAssistantContent) {
|
public void onThinking(Session session, ThingkingAssistantContent thingkingAssistantContent) {
|
||||||
logger.info("Received thingkingAssistantContent {}", thingkingAssistantContent.getThinking());
|
logger.info("Received thingkingAssistantContent {}", thingkingAssistantContent.getThinking());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.alibaba.qwen.code.cli.protocol.data.AssistantUsage;
|
|||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.PermissionMode;
|
import com.alibaba.qwen.code.cli.protocol.data.PermissionMode;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.TextAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThinkingAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ThingkingAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolResultAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
import com.alibaba.qwen.code.cli.protocol.data.AssistantContent.ToolUseAssistantContent;
|
||||||
import com.alibaba.qwen.code.cli.protocol.data.behavior.Behavior.Operation;
|
import com.alibaba.qwen.code.cli.protocol.data.behavior.Behavior.Operation;
|
||||||
@@ -44,7 +44,7 @@ class SessionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onThinking(Session session, ThinkingAssistantContent thingkingAssistantContent) {
|
public void onThinking(Session session, ThingkingAssistantContent thingkingAssistantContent) {
|
||||||
log.info("receive thingkingAssistantContent {}", thingkingAssistantContent);
|
log.info("receive thingkingAssistantContent {}", thingkingAssistantContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user