diff --git a/README.md b/README.md index 8b187ef..e814e06 100644 --- a/README.md +++ b/README.md @@ -222,6 +222,8 @@ public class Main { .build(); try { + // A workspace id is required: pass it here (new DecisionModel("your-workspace-id")) + // or set the DASHSCOPE_WORKSPACE environment variable before running. DecisionModel decisionModel = new DecisionModel(); DecisionModelResult result = decisionModel.call(param); System.out.println(JsonUtils.toJson(result)); @@ -232,4 +234,8 @@ public class Main { } ``` -The `call` method accepts a `DecisionModelParam`, and returns a `DecisionModelResult` whose `answers` are keyed by question id. Streaming is not supported. The API key is read from the `DASHSCOPE_API_KEY` environment variable by default, or set explicitly with `apiKey(...)`; the request url defaults to `https://maas.qianwenaiapi.com/compatible-mode/v1/systemone`, override it with `new DecisionModel(baseUrl)` or the `DASHSCOPE_HTTP_BASE_URL` environment variable. +The `call` method accepts a `DecisionModelParam`, and returns a `DecisionModelResult` whose `answers` are keyed by question id. Streaming is not supported. The API key is read from the `DASHSCOPE_API_KEY` environment variable by default, or set explicitly with `apiKey(...)`. + +The endpoint is workspace-scoped: the base URL is composed as `https://{workspace}.{region}.maas.aliyuncs.com/compatible-mode/v1` (the `systemone` path is appended automatically). A workspace id is **required** — pass it to the constructor (`new DecisionModel(workspace)` or `new DecisionModel(workspace, region)`) or set the `DASHSCOPE_WORKSPACE` environment variable; otherwise constructing the client throws `IllegalArgumentException`. The region defaults to `cn-beijing` and can be set via `DASHSCOPE_API_REGION`. + +To target a fully custom endpoint (for example the Token Plan gateway), use the static factory `DecisionModel.withBaseUrl(baseUrl)`. Note that `new DecisionModel(String)` treats its argument as a **workspace id**, not a base URL. You can also override the entire base URL with the `DASHSCOPE_DECISION_BASE_URL` environment variable; the SDK-wide `DASHSCOPE_HTTP_BASE_URL` is intentionally not read here. diff --git a/README_zh.md b/README_zh.md index 43a1741..a552caf 100644 --- a/README_zh.md +++ b/README_zh.md @@ -222,6 +222,8 @@ public class Main { .build(); try { + // 必须提供 workspace:可在此传入(new DecisionModel("你的-workspace-id")), + // 或在运行前设置 DASHSCOPE_WORKSPACE 环境变量。 DecisionModel decisionModel = new DecisionModel(); DecisionModelResult result = decisionModel.call(param); System.out.println(JsonUtils.toJson(result)); @@ -232,4 +234,8 @@ public class Main { } ``` -`call` 方法接受 `DecisionModelParam`,并返回 `DecisionModelResult`,其中 `answers` 按问题 id 给出答案,不支持流式输出。API Key 默认从环境变量 `DASHSCOPE_API_KEY` 获取,也可以通过 `apiKey(...)` 指定;请求地址默认为 `https://maas.qianwenaiapi.com/compatible-mode/v1/systemone`,可通过 `new DecisionModel(baseUrl)` 或环境变量 `DASHSCOPE_HTTP_BASE_URL` 覆盖。 \ No newline at end of file +`call` 方法接受 `DecisionModelParam`,并返回 `DecisionModelResult`,其中 `answers` 按问题 id 给出答案,不支持流式输出。API Key 默认从环境变量 `DASHSCOPE_API_KEY` 获取,也可以通过 `apiKey(...)` 指定。 + +请求地址是 workspace 作用域的:base URL 由 `https://{workspace}.{region}.maas.aliyuncs.com/compatible-mode/v1` 拼接而成(`systemone` 路径会自动追加)。**必须**提供 workspace id——通过构造函数传入(`new DecisionModel(workspace)` 或 `new DecisionModel(workspace, region)`),或设置环境变量 `DASHSCOPE_WORKSPACE`;否则构造客户端时会抛出 `IllegalArgumentException`。region 默认为 `cn-beijing`,可通过环境变量 `DASHSCOPE_API_REGION` 设置。 + +若要指向完全自定义的端点(例如 Token Plan 网关),请使用静态工厂方法 `DecisionModel.withBaseUrl(baseUrl)`。注意 `new DecisionModel(String)` 会把参数当作 **workspace id**,而不是 base URL。你也可以用环境变量 `DASHSCOPE_DECISION_BASE_URL` 覆盖整个 base URL;此处的实现有意不读取全局的 `DASHSCOPE_HTTP_BASE_URL`。 \ No newline at end of file diff --git a/samples/DecisionModelUsage.java b/samples/DecisionModelUsage.java index 2a289cd..31c14cc 100644 --- a/samples/DecisionModelUsage.java +++ b/samples/DecisionModelUsage.java @@ -40,6 +40,9 @@ public static void main(String[] args) throws Exception { .questions(questions) .build(); + // A workspace id is required: pass it here (new DecisionModel("your-workspace-id")) + // or set the DASHSCOPE_WORKSPACE environment variable before running. + // For a fully custom endpoint, use DecisionModel.withBaseUrl(baseUrl) instead. DecisionModel decisionModel = new DecisionModel(); DecisionModelResult result = decisionModel.call(param); System.out.println(JsonUtils.toJson(result)); diff --git a/src/main/java/com/alibaba/dashscope/aigc/imagesynthesis/ImageSynthesis.java b/src/main/java/com/alibaba/dashscope/aigc/imagesynthesis/ImageSynthesis.java index 68256bb..ecdd908 100644 --- a/src/main/java/com/alibaba/dashscope/aigc/imagesynthesis/ImageSynthesis.java +++ b/src/main/java/com/alibaba/dashscope/aigc/imagesynthesis/ImageSynthesis.java @@ -33,6 +33,30 @@ public static class Models { public static final String WANX_2_1_IMAGEEDIT = "wanx2.1-imageedit"; } + /** + * Model prefixes that are only served on the multimodal-generation endpoint. The legacy + * text2image endpoint used by this class rejects them with a 400 "url error", so they must be + * called through {@link com.alibaba.dashscope.aigc.imagegeneration.ImageGeneration} instead. + */ + private static final String[] MULTIMODAL_MODEL_PREFIXES = {"wan2.6-t2i", "wan2.6-image"}; + + private static void checkMultimodalModel(String model) { + if (model == null) { + return; + } + for (String prefix : MULTIMODAL_MODEL_PREFIXES) { + if (model.startsWith(prefix)) { + throw new IllegalArgumentException( + String.format( + "Model '%s' is only served on the multimodal-generation endpoint and is not " + + "supported by ImageSynthesis. Use " + + "com.alibaba.dashscope.aigc.imagegeneration.ImageGeneration " + + "(ImageGeneration.call/asyncCall/streamCall) for this model.", + model)); + } + } + } + /** Image edit function */ public static class ImageEditFunction { public static final String STYLIZATION_ALL = "stylization_all"; @@ -112,6 +136,7 @@ public ImageSynthesis(String task, String baseUrl) { public ImageSynthesisResult asyncCall(ImageSynthesisParam param) throws ApiException, NoApiKeyException { + checkMultimodalModel(param.getModel()); // add local file support try { param.checkAndUpload(); @@ -126,11 +151,15 @@ public ImageSynthesisResult asyncCall(ImageSynthesisParam param) } /** - * Note: This method currently now only supports wan2.2-t2i-flash and wan2.2-t2i-plus. Using other - * models will result in an error,More raw image models may be added for use later + * Synchronously generate images on the legacy text2image endpoint. + * + *

Multimodal-generation models (wan2.6-t2i / wan2.6-image) are not served here; use {@link + * com.alibaba.dashscope.aigc.imagegeneration.ImageGeneration#call} for those. Calling this method + * with such a model throws {@link IllegalArgumentException}. */ public ImageSynthesisResult syncCall(ImageSynthesisParam param) throws ApiException, NoApiKeyException { + checkMultimodalModel(param.getModel()); // add local file support try { param.checkAndUpload(); @@ -152,6 +181,7 @@ public ImageSynthesisResult syncCall(ImageSynthesisParam param) */ public ImageSynthesisResult call(ImageSynthesisParam param) throws ApiException, NoApiKeyException { + checkMultimodalModel(param.getModel()); // add local file support try { param.checkAndUpload(); diff --git a/src/test/java/com/alibaba/dashscope/TestImageSynthesis.java b/src/test/java/com/alibaba/dashscope/TestImageSynthesis.java index 7741cea..a6d3bfe 100644 --- a/src/test/java/com/alibaba/dashscope/TestImageSynthesis.java +++ b/src/test/java/com/alibaba/dashscope/TestImageSynthesis.java @@ -201,4 +201,20 @@ public void testImageSynthesisWithPromptExtendAndWatermark() assertEquals(true, requestBody.contains("\"prompt_extend\":true")); assertEquals(true, requestBody.contains("\"watermark\":false")); } + + @Test + public void testSyncCallRejectsMultimodalModel() { + int port = server.getPort(); + Constants.baseHttpApiUrl = String.format("http://127.0.0.1:%s", port); + ImageSynthesis is = new ImageSynthesis(); + ImageSynthesisParam param = + ImageSynthesisParam.builder().model("wan2.6-t2i").prompt("a cat").build(); + IllegalArgumentException ex = + org.junit.jupiter.api.Assertions.assertThrows( + IllegalArgumentException.class, () -> is.syncCall(param)); + org.junit.jupiter.api.Assertions.assertTrue( + ex.getMessage().contains("ImageGeneration"), ex.getMessage()); + // no request should have reached the legacy endpoint + assertEquals(0, server.getRequestCount()); + } }