@@ -21,15 +21,15 @@ When the user asks you to write AgentScope Java code, follow these instructions
21213 . ** NEVER use ` ThreadLocal ` ** - Use Reactor Context with ` Mono.deferContextual() ` .
22224 . ** NEVER hardcode API keys** - Always use ` System.getenv() ` .
23235 . ** NEVER ignore errors silently** - Always log errors and provide fallback values.
24- 6 . ** NEVER use wrong import paths** - All models are in ` io.agentscope.core.model.* ` , NOT ` io.agentscope.model.* ` .
24+ 6 . ** NEVER use wrong import paths** - Shared model interfaces are in ` io.agentscope.core.model.* ` ; provider models are in ` io.agentscope.extensions. model.<provider> .* ` .
2525
2626** ✅ ALWAYS DO:**
27271 . ** Use ` Mono ` and ` Flux ` ** for all asynchronous operations.
28282 . ** Chain operations** with ` .map() ` , ` .flatMap() ` , ` .then() ` .
29293 . ** Use Builder pattern** for creating agents, models, and messages.
30304 . ** Include error handling** with ` .onErrorResume() ` or ` .onErrorReturn() ` .
31315 . ** Add logging** with SLF4J for important operations.
32- 6 . ** Use correct imports** : ` import io.agentscope.core .model.DashScopeChatModel; `
32+ 6 . ** Use correct imports** : ` import io.agentscope.extensions .model.dashscope .DashScopeChatModel; `
33337 . ** Use correct APIs** (many methods don't exist or have changed):
3434 - ` toolkit.registerTool() ` NOT ` registerObject() `
3535 - ` toolkit.getToolNames() ` NOT ` getTools() `
@@ -56,7 +56,7 @@ When the user asks you to write AgentScope Java code, follow these instructions
56562 . Check: Are all operations non-blocking? → If no, ** FIX IT** .
57573 . Check: Does it have error handling? → If no, ** ADD IT** .
58584 . Check: Are API keys from environment? → If no, ** CHANGE IT** .
59- 5 . Check: Are imports correct? → If using ` io.agentscope.model.* ` , ** FIX TO** ` io.agentscope.core .model.* ` .
59+ 5 . Check: Are imports correct? → If using provider models from ` io.agentscope.core. model.* ` , ** FIX TO** ` io.agentscope.extensions .model.<provider> .* ` .
6060
6161** Default code structure for agent logic:**
6262``` java
@@ -118,6 +118,11 @@ public static void main(String[] args) {
118118 <artifactId >agentscope-core</artifactId >
119119 <version >${agentscope.version}</version >
120120 </dependency >
121+ <dependency >
122+ <groupId >io.agentscope</groupId >
123+ <artifactId >agentscope-extensions-model-dashscope</artifactId >
124+ <version >${agentscope.version}</version >
125+ </dependency >
121126</dependencies >
122127```
123128
@@ -165,23 +170,23 @@ public static void main(String[] args) {
165170</dependency >
166171```
167172
168- ### Available Model Classes (all in agentscope-core )
173+ ### Available Model Classes (provider-specific extension modules )
169174
170175``` java
171176// DashScope (Alibaba Cloud)
172- import io.agentscope.core .model.DashScopeChatModel ;
177+ import io.agentscope.extensions .model.dashscope .DashScopeChatModel ;
173178
174179// OpenAI
175180import io.agentscope.extensions.model.openai.OpenAIChatModel ;
176181
177182// Gemini (Google)
178- import io.agentscope.core .model.GeminiChatModel ;
183+ import io.agentscope.extensions .model.gemini .GeminiChatModel ;
179184
180185// Anthropic (Claude)
181- import io.agentscope.core .model.AnthropicChatModel ;
186+ import io.agentscope.extensions .model.anthropic .AnthropicChatModel ;
182187
183188// Ollama (Local models)
184- import io.agentscope.core .model.OllamaChatModel ;
189+ import io.agentscope.extensions .model.ollama .OllamaChatModel ;
185190```
186191
187192### Optional Extensions
@@ -320,7 +325,7 @@ Extend `AgentBase` and implement `doCall(List<Msg> msgs)`:
320325public class MyAgent extends AgentBase {
321326 private final Model model;
322327 private final Memory memory;
323-
328+
324329 public MyAgent (String name , Model model ) {
325330 super (name, " A custom agent" , true , List . of());
326331 this . model = model;
@@ -333,7 +338,7 @@ public class MyAgent extends AgentBase {
333338 if (msgs != null ) {
334339 msgs. forEach(memory:: addMessage);
335340 }
336-
341+
337342 // 2. Call model or logic
338343 return model. generate(memory. getMessages(), null , null )
339344 .map(response - > Msg . builder()
@@ -362,7 +367,7 @@ Use `@Tool` annotation for function-based tools. Tools can return:
362367public class WeatherTools {
363368 @Tool (description = " Get current weather for a city. Returns temperature and conditions." )
364369 public String getWeather (
365- @ToolParam (name = " city" , description = " City name, e.g., 'San Francisco'" )
370+ @ToolParam (name = " city" , description = " City name, e.g., 'San Francisco'" )
366371 String city ) {
367372 // Implementation
368373 return " Sunny, 25°C" ;
@@ -374,10 +379,10 @@ public class WeatherTools {
374379``` java
375380public class AsyncTools {
376381 private final WebClient webClient;
377-
382+
378383 @Tool (description = " Fetch data from trusted API endpoint" )
379384 public Mono<String > fetchData (
380- @ToolParam (name = " url" , description = " API endpoint URL (must start with https://api.myservice.com)" )
385+ @ToolParam (name = " url" , description = " API endpoint URL (must start with https://api.myservice.com)" )
381386 String url ) {
382387 // SECURITY: Validate URL to prevent SSRF
383388 if (! url. startsWith(" https://api.myservice.com" )) {
@@ -444,7 +449,7 @@ Hook loggingHook = new Hook() {
444449 return Mono . just(event);
445450 }
446451 }
447-
452+
448453 @Override
449454 public int priority () {
450455 return 500 ; // Low priority (logging)
@@ -475,7 +480,7 @@ Hook loggingHook = new Hook() {
475480 }
476481 return Mono . just(event);
477482 }
478-
483+
479484 @Override
480485 public int priority () {
481486 return 500 ;
@@ -597,7 +602,7 @@ void testAgentCall() {
597602 .role(MsgRole . USER )
598603 .content(TextBlock . builder(). text(" Hello" ). build())
599604 .build();
600-
605+
601606 StepVerifier . create(agent. call(input))
602607 .assertNext(response - > {
603608 assertEquals(MsgRole . ASSISTANT , response. getRole());
@@ -616,12 +621,12 @@ void testWithMockModel() {
616621 .thenReturn(Mono . just(ChatResponse . builder()
617622 .text(" Mocked response" )
618623 .build()));
619-
624+
620625 ReActAgent agent = ReActAgent . builder()
621626 .name(" TestAgent" )
622627 .model(mockModel)
623628 .build();
624-
629+
625630 // Test agent behavior
626631}
627632```
@@ -722,7 +727,7 @@ Duration delay = Duration.ofMillis((long) Math.pow(2, attempt) * baseDelayMs);
722727 ``` java
723728 // ❌ WRONG
724729 Thread . sleep(1000 );
725-
730+
726731 // ✅ CORRECT
727732 return Mono . delay(Duration . ofSeconds(1 ));
728733 ```
@@ -740,7 +745,7 @@ Duration delay = Duration.ofMillis((long) Math.pow(2, attempt) * baseDelayMs);
740745 ``` java
741746 // ❌ WRONG
742747 .onErrorResume(e - > Mono . empty())
743-
748+
744749 // ✅ CORRECT
745750 .onErrorResume(e - > {
746751 log. error(" Operation failed" , e);
@@ -752,7 +757,7 @@ Duration delay = Duration.ofMillis((long) Math.pow(2, attempt) * baseDelayMs);
752757 ``` java
753758 // ❌ WRONG
754759 ThreadLocal<String > context = new ThreadLocal<> ();
755-
760+
756761 // ✅ CORRECT
757762 return Mono . deferContextual(ctx - > {
758763 String value = ctx. get(" key" );
@@ -775,7 +780,7 @@ Duration delay = Duration.ofMillis((long) Math.pow(2, attempt) * baseDelayMs);
775780 ``` java
776781 // ❌ WRONG
777782 String apiKey = " sk-1234567890" ;
778-
783+
779784 // ✅ CORRECT
780785 String apiKey = System . getenv(" OPENAI_API_KEY" );
781786 ```
@@ -788,7 +793,7 @@ Duration delay = Duration.ofMillis((long) Math.pow(2, attempt) * baseDelayMs);
788793 case PostActingEvent e - > handleActing(e);
789794 default - > Mono . just(event);
790795 };
791-
796+
792797 // ✅ CORRECT - Java 17 compatible
793798 if (event instanceof PreReasoningEvent e) {
794799 return handleReasoning(e);
@@ -878,7 +883,7 @@ import io.agentscope.core.model.Model;
878883import io.agentscope.core.tool.Tool ;
879884import io.agentscope.core.tool.ToolParam ;
880885import io.agentscope.core.tool.Toolkit ;
881- import io.agentscope.core .model.DashScopeChatModel ;
886+ import io.agentscope.extensions .model.dashscope .DashScopeChatModel ;
882887import org.slf4j.Logger ;
883888import org.slf4j.LoggerFactory ;
884889import reactor.core.publisher.Mono ;
@@ -890,22 +895,22 @@ import java.time.format.DateTimeFormatter;
890895 * Complete example demonstrating AgentScope best practices.
891896 */
892897public class CompleteExample {
893-
898+
894899 private static final Logger log = LoggerFactory . getLogger(CompleteExample . class);
895-
900+
896901 public static void main (String [] args ) {
897902 // 1. Create model (no .temperature() method, use defaultOptions)
898903 Model model = DashScopeChatModel . builder()
899904 .apiKey(System . getenv(" DASHSCOPE_API_KEY" ))
900905 .modelName(" qwen-plus" )
901906 .stream(true )
902907 .build();
903-
908+
904909 // 2. Create toolkit with tools
905910 Toolkit toolkit = new Toolkit ();
906911 toolkit. registerTool(new WeatherTools ());
907912 toolkit. registerTool(new TimeTools ());
908-
913+
909914 // 3. Create hook for streaming output
910915 Hook streamingHook = new Hook () {
911916 @Override
@@ -918,13 +923,13 @@ public class CompleteExample {
918923 }
919924 return Mono . just(event);
920925 }
921-
926+
922927 @Override
923928 public int priority () {
924929 return 500 ; // Low priority
925930 }
926931 };
927-
932+
928933 // 4. Build agent
929934 ReActAgent agent = ReActAgent . builder()
930935 .name(" Assistant" )
@@ -935,65 +940,65 @@ public class CompleteExample {
935940 .hook(streamingHook)
936941 .maxIters(10 )
937942 .build();
938-
943+
939944 // 5. Use agent
940945 Msg userMsg = Msg . builder()
941946 .role(MsgRole . USER )
942947 .content(TextBlock . builder()
943948 .text(" What's the weather in San Francisco and what time is it?" )
944949 .build())
945950 .build();
946-
951+
947952 try {
948953 System . out. println(" User: " + userMsg. getTextContent());
949954 System . out. print(" Assistant: " );
950-
955+
951956 // ⚠️ IMPORTANT: .block() is ONLY allowed in main() methods for demo purposes
952957 // NEVER use .block() in agent logic, service methods, or library code
953958 Msg response = agent. call(userMsg). block();
954-
959+
955960 System . out. println(" \n\n --- Response Details ---" );
956961 System . out. println(" Role: " + response. getRole());
957962 System . out. println(" Content: " + response. getTextContent());
958-
963+
959964 } catch (Exception e) {
960965 log. error(" Error during agent execution" , e);
961966 System . err. println(" Error: " + e. getMessage());
962967 }
963968 }
964-
969+
965970 /**
966971 * Example tool class for weather information.
967972 */
968973 public static class WeatherTools {
969-
974+
970975 @Tool (description = " Get current weather for a city. Returns temperature and conditions." )
971976 public String getWeather (
972- @ToolParam (name = " city" , description = " City name, e.g., 'San Francisco'" )
977+ @ToolParam (name = " city" , description = " City name, e.g., 'San Francisco'" )
973978 String city ) {
974-
979+
975980 log. info(" Getting weather for city: {}" , city);
976-
981+
977982 // Simulate API call
978983 return String . format(" Weather in %s: Sunny, 22°C, Light breeze" , city);
979984 }
980985 }
981-
986+
982987 /**
983988 * Example tool class for time information.
984989 */
985990 public static class TimeTools {
986-
987- private static final DateTimeFormatter FORMATTER =
991+
992+ private static final DateTimeFormatter FORMATTER =
988993 DateTimeFormatter . ofPattern(" yyyy-MM-dd HH:mm:ss" );
989-
994+
990995 @Tool (description = " Get current date and time" )
991996 public String getCurrentTime () {
992997 LocalDateTime now = LocalDateTime . now();
993998 String formatted = now. format(FORMATTER );
994-
999+
9951000 log. info(" Returning current time: {}" , formatted);
996-
1001+
9971002 return " Current time: " + formatted;
9981003 }
9991004 }
0 commit comments