mateclaw/mateclaw-server/src/main/java/vip/mate/plugin/PluginContextImpl.java

122 lines
4.4 KiB
Java

package vip.mate.plugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.tool.ToolCallback;
import vip.mate.channel.ChannelManager;
import vip.mate.llm.service.ModelProviderService;
import vip.mate.memory.spi.MemoryManager;
import vip.mate.plugin.api.PluginContext;
import vip.mate.plugin.api.PluginException;
import vip.mate.plugin.api.PluginManifest;
import vip.mate.plugin.api.channel.PluginChannelAdapter;
import vip.mate.plugin.api.memory.PluginMemoryProvider;
import vip.mate.plugin.bridge.PluginChannelBridge;
import vip.mate.plugin.bridge.PluginMemoryBridge;
import vip.mate.tool.ToolRegistry;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.function.Supplier;
/**
* Platform-side implementation of {@link PluginContext}.
* Bridges plugin registrations to the corresponding platform services.
*
* @author MateClaw Team
*/
public class PluginContextImpl implements PluginContext {
private final LoadedPlugin loadedPlugin;
private final PluginManifest manifest;
private final ToolRegistry toolRegistry;
private final ChannelManager channelManager;
private final MemoryManager memoryManager;
private final ModelProviderService modelProviderService;
private final Map<String, Object> configMap;
private final Logger logger;
private final ObjectMapper objectMapper = new ObjectMapper();
public PluginContextImpl(LoadedPlugin loadedPlugin,
PluginManifest manifest,
ToolRegistry toolRegistry,
ChannelManager channelManager,
MemoryManager memoryManager,
ModelProviderService modelProviderService,
String configJson) {
this.loadedPlugin = loadedPlugin;
this.manifest = manifest;
this.toolRegistry = toolRegistry;
this.channelManager = channelManager;
this.memoryManager = memoryManager;
this.modelProviderService = modelProviderService;
this.logger = LoggerFactory.getLogger("plugin." + manifest.getName());
this.configMap = parseConfig(configJson);
}
@SuppressWarnings("unchecked")
private Map<String, Object> parseConfig(String configJson) {
if (configJson == null || configJson.isBlank()) {
return Map.of();
}
try {
return objectMapper.readValue(configJson, Map.class);
} catch (Exception e) {
logger.warn("Failed to parse plugin config JSON: {}", e.getMessage());
return Map.of();
}
}
@Override
public void registerTool(ToolCallback tool) {
registerTool(tool, () -> true);
}
@Override
public void registerTool(ToolCallback tool, Supplier<Boolean> availabilityCheck) {
toolRegistry.registerPluginTool(tool, availabilityCheck);
loadedPlugin.getRegisteredTools().add(tool.getToolDefinition().name());
}
@Override
public void registerProvider(String providerId, ChatModel chatModel) {
modelProviderService.registerPluginChatModel(providerId, chatModel);
loadedPlugin.setRegisteredProvider(providerId);
}
@Override
public void registerChannel(PluginChannelAdapter channel) {
PluginChannelBridge bridge = new PluginChannelBridge(channel);
channelManager.registerPluginChannel(manifest.getName(), bridge);
loadedPlugin.getRegisteredChannels().add(channel.getChannelType());
}
@Override
public void registerMemoryProvider(PluginMemoryProvider provider) {
if (memoryManager.hasExternalProvider()) {
throw new PluginException(
"Only one external memory provider allowed. Current: " +
memoryManager.getExternalProviderName());
}
PluginMemoryBridge bridge = new PluginMemoryBridge(provider);
memoryManager.registerPluginProvider(bridge);
loadedPlugin.setRegisteredMemoryProvider(provider.id());
}
@Override
@SuppressWarnings("unchecked")
public <T> T getConfig(String key, Class<T> type) {
Object value = configMap.get(key);
if (value == null) return null;
if (type.isInstance(value)) return (T) value;
return objectMapper.convertValue(value, type);
}
@Override
public Logger getLogger() {
return logger;
}
}