Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions samples/AgentStudioSimple.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import com.alibaba.dashscope.agentstudio.AgentStudioClient;
import com.alibaba.dashscope.agentstudio.message.ClientEvents;
import com.alibaba.dashscope.agentstudio.message.ContentBlock;
import com.alibaba.dashscope.agentstudio.message.Message;
import com.alibaba.dashscope.agentstudio.model.Agent;
import com.alibaba.dashscope.agentstudio.model.Session;
import com.alibaba.dashscope.agentstudio.param.AgentCreateParam;
import com.alibaba.dashscope.agentstudio.param.SessionCreateParam;
import com.alibaba.dashscope.agentstudio.resource.AgentStudioEventStream;
import java.util.Collections;

/**
* AgentStudio quick start: create agent, session, send message, stream reply.
*
* <p>Prerequisites: set DASHSCOPE_API_KEY env var, and either DASHSCOPE_WORKSPACE env var or pass
* workspace to the constructor.
*
* <pre>
* export DASHSCOPE_API_KEY=sk-xxx
* export DASHSCOPE_WORKSPACE=ws_xxxxxxxxxxxx
* </pre>
*/
public class AgentStudioSimple {

public static void main(String[] args) throws Exception {
// Option 1: apiKey + workspace (production)
AgentStudioClient client = new AgentStudioClient("sk-xxx", "ws_xxxxxxxxxxxx");

// Option 2: all from env vars (DASHSCOPE_API_KEY + DASHSCOPE_WORKSPACE)
// AgentStudioClient client = new AgentStudioClient();

// Option 3: custom base URL
// AgentStudioClient client = AgentStudioClient.builder()
// .apiKey("sk-xxx")
// .baseUrl("https://your-custom-host/api/v1/agentstudio")
// .build();

// 1. Create Agent
Agent agent =
client
.agents()
.create(
AgentCreateParam.builder()
.name("demo-agent")
.model("qwen-plus")
.systemPrompt("你是一个简洁的助手。")
.build());
System.out.println("Agent: " + agent.getId());

// 2. Create Session
Session session =
client.sessions().create(SessionCreateParam.builder().agent(agent.getId()).build());
System.out.println("Session: " + session.getId());

// 3. Send message
client
.sessions()
.events()
.send(session.getId(), Collections.singletonList(ClientEvents.userMessage("你好")));

// 4. Stream reply
try (AgentStudioEventStream stream = client.sessions().events().stream(session.getId())) {
for (Message event : stream) {
if ("message".equals(event.getType()) && event.getContent() != null) {
for (ContentBlock block : event.getContent()) {
if (block instanceof ContentBlock.Text) {
System.out.print(((ContentBlock.Text) block).getText());
}
}
} else if ("session_status".equals(event.getType())) {
Session.StopReason stopReason = event.getStopReason();
if (stopReason != null) {
System.out.println("\nstop_reason: " + stopReason.getType());
}
break;
}
}
}

// Cleanup
client.sessions().delete(session.getId());
client.agents().archive(agent.getId());
client.close();
}
}
144 changes: 144 additions & 0 deletions src/main/java/com/alibaba/dashscope/agentstudio/AgentStudioClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Copyright (c) Alibaba, Inc. and its affiliates.
package com.alibaba.dashscope.agentstudio;

import com.alibaba.dashscope.agentstudio.resource.Agents;
import com.alibaba.dashscope.agentstudio.resource.Environments;
import com.alibaba.dashscope.agentstudio.resource.Files;
import com.alibaba.dashscope.agentstudio.resource.Sessions;
import com.alibaba.dashscope.agentstudio.resource.Skills;
import com.alibaba.dashscope.agentstudio.resource.Vaults;
import com.alibaba.dashscope.protocol.ConnectionOptions;
import java.io.Closeable;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

public class AgentStudioClient implements Closeable {
private final Agents agents;
private final Sessions sessions;
private final Environments environments;
private final Skills skills;
private final Vaults vaults;
private final Files files;
private final String baseUrl;

public AgentStudioClient() {
this(null, null, null, null, null);
}

public AgentStudioClient(String workspace) {
this(null, null, workspace, null, null);
}

public AgentStudioClient(String apiKey, String workspace) {
this(apiKey, null, workspace, null, null);
}

public AgentStudioClient(
String apiKey,
String baseUrl,
String workspace,
String region,
ConnectionOptions connectionOptions) {
this.baseUrl = resolveBaseUrl(baseUrl, workspace, region);
this.agents = new Agents(this.baseUrl, connectionOptions, apiKey);
this.sessions = new Sessions(this.baseUrl, connectionOptions, apiKey);
this.environments = new Environments(this.baseUrl, connectionOptions, apiKey);
this.files = new Files(this.baseUrl, connectionOptions, apiKey);
this.skills = new Skills(this.baseUrl, connectionOptions, apiKey, this.files);
this.vaults = new Vaults(this.baseUrl, connectionOptions, apiKey);
}

public static Builder builder() {
return new Builder();
}

public static class Builder {
private String apiKey;
private String baseUrl;
private String workspace;
private String region;
private ConnectionOptions connectionOptions;

public Builder apiKey(String apiKey) {
this.apiKey = apiKey;
return this;
}

public Builder baseUrl(String baseUrl) {
this.baseUrl = baseUrl;
return this;
}

public Builder workspace(String workspace) {
this.workspace = workspace;
return this;
}

public Builder region(String region) {
this.region = region;
return this;
}

public Builder connectionOptions(ConnectionOptions connectionOptions) {
this.connectionOptions = connectionOptions;
return this;
}

public AgentStudioClient build() {
return new AgentStudioClient(apiKey, baseUrl, workspace, region, connectionOptions);
}
}

public Agents agents() {
return agents;
}

public Sessions sessions() {
return sessions;
}

public Environments environments() {
return environments;
}

public Skills skills() {
return skills;
}

public Vaults vaults() {
return vaults;
}

public Files files() {
return files;
}

public String getBaseUrl() {
return baseUrl;
}

public <T> CompletableFuture<T> async(Supplier<T> supplier) {
return CompletableFuture.supplyAsync(supplier);
}

@Override
public void close() {
sessions.events().close();
skills.close();
files.close();
}

private static String resolveBaseUrl(String explicitUrl, String workspace, String region) {
if (explicitUrl != null && !explicitUrl.isEmpty()) {
return explicitUrl;
}
String envUrl = System.getenv(AgentStudioConstants.ENV_BASE_URL);
if (envUrl == null || envUrl.isEmpty()) {
envUrl = System.getenv(AgentStudioConstants.ENV_BASE_URL_ALT);
}
if (envUrl != null && !envUrl.isEmpty()) {
return envUrl;
}
return AgentStudioConstants.resolveBaseUrl(workspace, region);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Copyright (c) Alibaba, Inc. and its affiliates.
package com.alibaba.dashscope.agentstudio;

import com.alibaba.dashscope.base.HalfDuplexParamBase;
import com.alibaba.dashscope.protocol.GeneralServiceOption;
import com.alibaba.dashscope.protocol.HttpMethod;
import com.alibaba.dashscope.protocol.Protocol;
import com.alibaba.dashscope.protocol.StreamingMode;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public final class AgentStudioConstants {
public static final String BASE_URL_TEMPLATE =
"https://%s.%s.maas.aliyuncs.com/api/v1/agentstudio";
public static final String DEFAULT_REGION = "cn-beijing";
public static final int DEFAULT_TIMEOUT_MS = 600_000;
public static final int DEFAULT_CONNECT_TIMEOUT_MS = 10_000;
public static final String ENV_BASE_URL = "DASHSCOPE_AGENTSTUDIO_URL";
public static final String ENV_BASE_URL_ALT = "AGENTSTUDIO_URL";
public static final String ENV_WORKSPACE = "DASHSCOPE_WORKSPACE";
public static final String ENV_REGION = "DASHSCOPE_API_REGION";

private AgentStudioConstants() {}

public static final class SSEEventType {
public static final String MESSAGE = "message";
public static final String INTERRUPT = "interrupt";
public static final String TOOL_CONFIRMATION = "tool_confirmation";
public static final String FUNCTION_CALL_OUTPUT = "function_call_output";
public static final String TOOL_CALL_OUTPUT = "tool_call_output";
public static final String DEFINE_OUTCOME = "define_outcome";
public static final String FUNCTION_CALL = "function_call";
public static final String TOOL_CALL = "tool_call";
public static final String REASONING = "reasoning";
public static final String MCP_CALL = "mcp_call";
public static final String MCP_CALL_OUTPUT = "mcp_call_output";
public static final String SESSION_STATUS = "session_status";
public static final String ERROR = "error";
public static final String SESSION_UPDATED = "session_updated";
public static final String OUTCOME_EVALUATION = "outcome_evaluation";

private SSEEventType() {}
}

public static final class MessageRole {
public static final String USER = "user";
public static final String ASSISTANT = "assistant";
public static final String TOOL = "tool";

private MessageRole() {}
}

public static final class BlockType {
public static final String TEXT = "text";
public static final String IMAGE = "image";
public static final String AUDIO = "audio";
public static final String DATA = "data";
public static final String FILE = "file";
public static final String REFUSAL = "refusal";
public static final String ERROR = "error";

private BlockType() {}
}

public static final class SessionStatusValue {
public static final String IDLE = "idle";
public static final String RUNNING = "running";
public static final String RESCHEDULING = "rescheduling";
public static final String TERMINATED = "terminated";

private SessionStatusValue() {}
}

public static String resolveBaseUrl(String workspace, String region) {
String ws = workspace;
if (ws == null || ws.isEmpty()) {
ws = System.getenv(ENV_WORKSPACE);
}
if (ws == null || ws.isEmpty()) {
throw new IllegalArgumentException(
"workspace is required. Pass it to the constructor, "
+ "set DASHSCOPE_WORKSPACE env var, or set DASHSCOPE_AGENTSTUDIO_URL.");
}
String r = region;
if (r == null || r.isEmpty()) {
r = System.getenv(ENV_REGION);
}
if (r == null || r.isEmpty()) {
r = DEFAULT_REGION;
}
return String.format(BASE_URL_TEMPLATE, ws, r);
}

/**
* Build a {@link GeneralServiceOption} for an agentstudio endpoint. When {@code baseUrl} is
* non-null it overrides the global default; otherwise the request falls back to {@code
* Constants.baseHttpApiUrl} via {@code GeneralApi}.
*/
public static GeneralServiceOption newServiceOption(
HttpMethod method, String path, String baseUrl) {
GeneralServiceOption opt =
GeneralServiceOption.builder()
.protocol(Protocol.HTTP)
.httpMethod(method)
.streamingMode(StreamingMode.OUT)
.path(path)
.build();
if (baseUrl != null) {
opt.setBaseHttpUrl(baseUrl);
}
return opt;
}

/**
* Stamp the client's instance apiKey onto a param if the caller didn't set one. The global
* fallback chain in {@link com.alibaba.dashscope.utils.ApiKey#getApiKey} still applies when
* {@code apiKey} is null.
*/
public static <P extends HalfDuplexParamBase> P withApiKey(String apiKey, P param) {
if (apiKey != null && param.getApiKey() == null) {
param.setApiKey(apiKey);
}
return param;
}

/**
* Append {@code key=value} (URL-encoded) to {@code sb} if value is non-null. Joins with {@literal
* &}.
*/
public static void appendParam(StringBuilder sb, String key, Object value) {
if (value == null) {
return;
}
if (sb.length() > 0) {
sb.append("&");
}
try {
sb.append(key).append("=").append(URLEncoder.encode(value.toString(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
sb.append(key).append("=").append(value);
}
}
}
Loading
Loading