fix: 统一 OpenAI 消息内容块数组格式
- 将 system、user、assistant、tool 及历史上下文 content 统一为数组 - 保留 DeepSeek、GLM 专用格式规则并补充多模态与工具消息测试
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
package com.easyagents.agent.runtime.agentscope;
|
||||
|
||||
import io.agentscope.core.formatter.openai.DeepSeekFormatter;
|
||||
import io.agentscope.core.formatter.openai.dto.OpenAIMessage;
|
||||
import io.agentscope.core.message.Msg;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 保留 DeepSeek 专用规则并将全部消息 content 规范为内容块数组。
|
||||
*/
|
||||
public final class AgentDeepSeekChatFormatter extends DeepSeekFormatter {
|
||||
|
||||
/**
|
||||
* 转换 DeepSeek 消息并在供应商规则之后统一 content 格式。
|
||||
*
|
||||
* @param messages AgentScope 消息
|
||||
* @return OpenAI 请求消息
|
||||
*/
|
||||
@Override
|
||||
protected List<OpenAIMessage> doFormat(List<Msg> messages) {
|
||||
return AgentOpenAIChatFormatter.normalizeContent(super.doFormat(messages));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.easyagents.agent.runtime.agentscope;
|
||||
|
||||
import io.agentscope.core.formatter.openai.GLMFormatter;
|
||||
import io.agentscope.core.formatter.openai.dto.OpenAIMessage;
|
||||
import io.agentscope.core.message.Msg;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 保留 GLM 专用规则并将全部消息 content 规范为内容块数组。
|
||||
*/
|
||||
public final class AgentGLMChatFormatter extends GLMFormatter {
|
||||
|
||||
/**
|
||||
* 转换 GLM 消息并在供应商规则之后统一 content 格式。
|
||||
*
|
||||
* @param messages AgentScope 消息
|
||||
* @return OpenAI 请求消息
|
||||
*/
|
||||
@Override
|
||||
protected List<OpenAIMessage> doFormat(List<Msg> messages) {
|
||||
return AgentOpenAIChatFormatter.normalizeContent(super.doFormat(messages));
|
||||
}
|
||||
}
|
||||
@@ -8,22 +8,37 @@ import io.agentscope.core.message.Msg;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 为 OpenAI-compatible 模型补充 system content 内容块数组兼容能力。
|
||||
* 为 OpenAI-compatible 模型补充全部消息 content 内容块数组兼容能力。
|
||||
*/
|
||||
public final class AgentOpenAIChatFormatter extends OpenAIChatFormatter {
|
||||
|
||||
/**
|
||||
* 将 AgentScope 消息转换为 OpenAI 消息,并规范 system 文本的 content 格式。
|
||||
* 将 AgentScope 消息转换为 OpenAI 消息,并规范全部角色的 content 格式。
|
||||
*
|
||||
* @param messages AgentScope 消息
|
||||
* @return OpenAI 请求消息
|
||||
*/
|
||||
@Override
|
||||
protected List<OpenAIMessage> doFormat(List<Msg> messages) {
|
||||
List<OpenAIMessage> formattedMessages = super.doFormat(messages);
|
||||
return normalizeContent(super.doFormat(messages));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 OpenAI 消息中的 content 统一规范为内容块数组。
|
||||
*
|
||||
* @param formattedMessages 已完成供应商规则转换的 OpenAI 消息
|
||||
* @return content 已规范为数组的原消息列表
|
||||
*/
|
||||
static List<OpenAIMessage> normalizeContent(List<OpenAIMessage> formattedMessages) {
|
||||
for (OpenAIMessage message : formattedMessages) {
|
||||
if ("system".equals(message.getRole()) && message.getContent() instanceof String text) {
|
||||
Object content = message.getContent();
|
||||
if (content instanceof String text) {
|
||||
message.setContent(List.of(OpenAIContentPart.text(text)));
|
||||
} else if (content == null) {
|
||||
message.setContent(List.of(OpenAIContentPart.text("")));
|
||||
} else if (!(content instanceof List<?>)) {
|
||||
throw new IllegalStateException(
|
||||
"Unsupported OpenAI message content type: " + content.getClass().getName());
|
||||
}
|
||||
}
|
||||
return formattedMessages;
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.easyagents.agent.runtime.model.AgentHttpVersionPolicy;
|
||||
import com.easyagents.agent.runtime.model.AgentModelFactory;
|
||||
import com.easyagents.agent.runtime.model.AgentModelProviderType;
|
||||
import com.easyagents.agent.runtime.model.AgentModelSpec;
|
||||
import com.easyagents.agent.runtime.model.AgentSystemContentFormat;
|
||||
import com.easyagents.agent.runtime.model.AgentMessageContentFormat;
|
||||
import io.agentscope.core.formatter.openai.DeepSeekFormatter;
|
||||
import io.agentscope.core.formatter.openai.GLMFormatter;
|
||||
import io.agentscope.core.model.*;
|
||||
@@ -154,7 +154,7 @@ public class AgentScopeModelFactory implements AgentModelFactory<Model> {
|
||||
.stream(Boolean.TRUE.equals(options.getStream()))
|
||||
.httpTransport(httpTransportProvider.getTransport(modelSpec.getHttpVersionPolicy(), baseUrl))
|
||||
.generateOptions(options);
|
||||
if (modelSpec.getSystemContentFormat() == AgentSystemContentFormat.TEXT_PARTS) {
|
||||
if (modelSpec.getMessageContentFormat() == AgentMessageContentFormat.TEXT_PARTS) {
|
||||
builder.formatter(new AgentOpenAIChatFormatter());
|
||||
}
|
||||
return builder.build();
|
||||
@@ -210,7 +210,9 @@ public class AgentScopeModelFactory implements AgentModelFactory<Model> {
|
||||
.endpointPath(modelSpec.getEndpointPath())
|
||||
.stream(Boolean.TRUE.equals(options.getStream()))
|
||||
.httpTransport(httpTransportProvider.getTransport(modelSpec.getHttpVersionPolicy(), baseUrl))
|
||||
.formatter(new DeepSeekFormatter())
|
||||
.formatter(modelSpec.getMessageContentFormat() == AgentMessageContentFormat.TEXT_PARTS
|
||||
? new AgentDeepSeekChatFormatter()
|
||||
: new DeepSeekFormatter())
|
||||
.generateOptions(options);
|
||||
return builder.build();
|
||||
}
|
||||
@@ -231,7 +233,9 @@ public class AgentScopeModelFactory implements AgentModelFactory<Model> {
|
||||
.endpointPath(modelSpec.getEndpointPath())
|
||||
.stream(Boolean.TRUE.equals(options.getStream()))
|
||||
.httpTransport(httpTransportProvider.getTransport(modelSpec.getHttpVersionPolicy(), baseUrl))
|
||||
.formatter(new GLMFormatter())
|
||||
.formatter(modelSpec.getMessageContentFormat() == AgentMessageContentFormat.TEXT_PARTS
|
||||
? new AgentGLMChatFormatter()
|
||||
: new GLMFormatter())
|
||||
.generateOptions(options);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user