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
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
import com.alibaba.assistant.agent.common.enums.Language;
import com.alibaba.assistant.agent.extension.prompt.CodeactToolSignatureInjectionToolCallback;
import com.alibaba.assistant.agent.extension.prompt.PromptContributionToolCallback;
import com.alibaba.assistant.agent.start.interceptor.modelInterceptor.DashScopeMultimodalEndpointInterceptor;
import com.alibaba.cloud.ai.graph.agent.hook.Hook;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelInterceptor;
import com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -41,6 +43,7 @@
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -222,6 +225,7 @@ def calculate_sum(a, b):
@Bean
public CodeactAgent grayscaleCodeactAgent(
ChatModel chatModel,
@Autowired(required = false) Environment environment,
@Autowired(required = false) List<ReplyCodeactTool> replyCodeactTools,
@Autowired(required = false) SearchCodeactToolFactory searchCodeactToolFactory,
@Autowired(required = false) List<TriggerCodeactTool> triggerCodeactTools,
Expand Down Expand Up @@ -313,6 +317,9 @@ public CodeactAgent grayscaleCodeactAgent(
logger.info("CodeactAgentConfig#grayscaleCodeactAgent - reason=统一配置 Hooks, total={}",
allHooks != null ? allHooks.size() : 0);

List<ModelInterceptor> modelInterceptors = new ArrayList<>();
modelInterceptors.add(new DashScopeMultimodalEndpointInterceptor(environment));

CodeactAgent.CodeactAgentBuilder builder = CodeactAgent.builder()
.name("CodeactAgent")
.description("通过编写和执行 Python 代码来解决问题的代码驱动智能体")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.alibaba.assistant.agent.start.interceptor.modelInterceptor;

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelCallHandler;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelInterceptor;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelRequest;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.ai.model.tool.ToolCallingChatOptions;
import org.springframework.core.env.Environment;

/**
* 确保 Graph 传入的 {@link ModelRequest#getOptions()} 在合并后仍走 DashScope 多模态端点。
*
* <p>阿里云文档:qwen3.6-plus 等模型若用纯文本端点会报 {@code url error}。框架层可能下发
* {@code multiModel=false} 的选项并覆盖 {@code application.yml} 默认值,本拦截器在调用链最前段纠偏。
*/
public class DashScopeMultimodalEndpointInterceptor extends ModelInterceptor {

private static final Logger log = LoggerFactory.getLogger(DashScopeMultimodalEndpointInterceptor.class);

private final Environment environment;

public DashScopeMultimodalEndpointInterceptor(Environment environment) {
this.environment = environment;
}

@Override
public String getName() {
return "DashScopeMultimodalEndpointInterceptor";
}

@Override
public ModelResponse interceptModel(ModelRequest request, ModelCallHandler handler) {
if (!Boolean.parseBoolean(
environment.getProperty("spring.ai.dashscope.chat.options.multi-model", "true"))) {
return handler.call(request);
}
ToolCallingChatOptions options = request.getOptions();
if (options == null) {
return handler.call(request);
}
try {
DashScopeChatOptions dash;
if (options instanceof DashScopeChatOptions dso) {
dash = DashScopeChatOptions.fromOptions(dso);
} else {
dash = ModelOptionsUtils.copyToTarget(options, ToolCallingChatOptions.class, DashScopeChatOptions.class);
}
Boolean before = dash.getMultiModel();
if (!Boolean.TRUE.equals(before)) {
dash.setMultiModel(true);
log.debug("DashScopeMultimodalEndpointInterceptor: set multiModel true (was {})", before);
ModelRequest patched = ModelRequest.builder(request).options(dash).build();
return handler.call(patched);
}
} catch (Exception e) {
log.warn("DashScopeMultimodalEndpointInterceptor: failed to patch options, passing request through: {}",
e.toString());
}
return handler.call(request);
}
}
Loading