diff --git a/.gitignore b/.gitignore index 196c0269..92fdc547 100644 --- a/.gitignore +++ b/.gitignore @@ -55,8 +55,6 @@ build/ /data/ /generated-classes/ /.idea/copilot.data.migration.ask2agent.xml -.idea/copilot.data.migration.agent.xml -.gitignore -.idea/copilot.data.migration.edit.xml -.gitignore -.idea/copilot.data.migration.ask.xml +/Partner-Main/data/ +/AGENTS.md +/.serena/ diff --git a/.idea/copilot.data.migration.agent.xml b/.idea/copilot.data.migration.agent.xml new file mode 100644 index 00000000..4ea72a91 --- /dev/null +++ b/.idea/copilot.data.migration.agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask.xml b/.idea/copilot.data.migration.ask.xml new file mode 100644 index 00000000..7ef04e2e --- /dev/null +++ b/.idea/copilot.data.migration.ask.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.edit.xml b/.idea/copilot.data.migration.edit.xml new file mode 100644 index 00000000..8648f940 --- /dev/null +++ b/.idea/copilot.data.migration.edit.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml index e47da802..154a876a 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -3,10 +3,13 @@ + + + diff --git a/.idea/misc.xml b/.idea/misc.xml index a0b4e20a..3a7b2ead 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,6 @@ - - + @@ -11,11 +10,12 @@ - - - - - + + + + + + @@ -27,6 +27,7 @@ diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/ActivateModel.java b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/ActivateModel.java index 2b8a222d..022876f6 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/ActivateModel.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/agent/runtime/interaction/flow/abstracts/ActivateModel.java @@ -23,7 +23,7 @@ public interface ActivateModel { ModelConfig modelConfig = AgentConfigManager.INSTANCE.loadModelConfig(modelKey()); model.setBaseMessages(withBasicPrompt() ? loadSpecificPromptAndBasicPrompt(modelKey()) : loadSpecificPrompt(modelKey())); model.setChatClient(new ChatClient(modelConfig.getBaseUrl(), modelConfig.getApikey(), modelConfig.getModel())); - ((Module) this).setModel(model); + setModel(model); } default void updateModelSettings(ChatClient newChatClient) { diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/chat/ChatClient.java b/Partner-Api/src/main/java/work/slhaf/partner/api/chat/ChatClient.java index ac23418e..30cdee08 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/chat/ChatClient.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/chat/ChatClient.java @@ -1,10 +1,12 @@ package work.slhaf.partner.api.chat; +import cn.hutool.core.io.IORuntimeException; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONUtil; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; import work.slhaf.partner.api.chat.constant.ChatConstant; import work.slhaf.partner.api.chat.pojo.ChatBody; import work.slhaf.partner.api.chat.pojo.ChatResponse; @@ -13,6 +15,7 @@ import work.slhaf.partner.api.chat.pojo.PrimaryChatResponse; import java.util.List; +@Slf4j @Data @NoArgsConstructor public class ChatClient { @@ -34,6 +37,8 @@ public class ChatClient { public ChatResponse runChat(List messages) { HttpRequest request = HttpRequest.post(url); + request.setConnectionTimeout(2000); + request.setReadTimeout(15000); request.header("Content-Type", "application/json"); request.header("Authorization", "Bearer " + apikey); @@ -53,17 +58,26 @@ public class ChatClient { .build(); } - HttpResponse response = request.body(JSONUtil.toJsonStr(body)).execute(); ChatResponse finalResponse; - PrimaryChatResponse primaryChatResponse = JSONUtil.toBean(response.body(), PrimaryChatResponse.class); - finalResponse = ChatResponse.builder() - .type(ChatConstant.Response.SUCCESS) - .message(primaryChatResponse.getChoices().get(0).getMessage().getContent()) - .usageBean(primaryChatResponse.getUsage()) - .build(); + try { + HttpResponse response = request.body(JSONUtil.toJsonStr(body)).execute(); + PrimaryChatResponse primaryChatResponse = JSONUtil.toBean(response.body(), PrimaryChatResponse.class); + finalResponse = ChatResponse.builder() + .status(ChatConstant.ResponseStatus.SUCCESS) + .message(primaryChatResponse.getChoices().get(0).getMessage().getContent()) + .usageBean(primaryChatResponse.getUsage()) + .build(); - response.close(); + response.close(); + } catch (IORuntimeException e) { + log.error("请求超时", e); + finalResponse = ChatResponse.builder() + .message("连接超时") + .status(ChatConstant.ResponseStatus.FAILED) + .usageBean(null) + .build(); + } return finalResponse; } diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/chat/constant/ChatConstant.java b/Partner-Api/src/main/java/work/slhaf/partner/api/chat/constant/ChatConstant.java index eaa3be2d..c805e40b 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/chat/constant/ChatConstant.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/chat/constant/ChatConstant.java @@ -8,8 +8,7 @@ public class ChatConstant { public static final String ASSISTANT = "assistant"; } - public static class Response { - public static final String SUCCESS = "success"; - public static final String ERROR = "error"; + public enum ResponseStatus { + SUCCESS, FAILED } } diff --git a/Partner-Api/src/main/java/work/slhaf/partner/api/chat/pojo/ChatResponse.java b/Partner-Api/src/main/java/work/slhaf/partner/api/chat/pojo/ChatResponse.java index 42f12106..77183f91 100644 --- a/Partner-Api/src/main/java/work/slhaf/partner/api/chat/pojo/ChatResponse.java +++ b/Partner-Api/src/main/java/work/slhaf/partner/api/chat/pojo/ChatResponse.java @@ -4,13 +4,14 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import work.slhaf.partner.api.chat.constant.ChatConstant; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class ChatResponse { - private String type; + private ChatConstant.ResponseStatus status; private String message; private PrimaryChatResponse.UsageBean usageBean; } diff --git a/Partner-Common/pom.xml b/Partner-Common/pom.xml new file mode 100644 index 00000000..1639ab13 --- /dev/null +++ b/Partner-Common/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + work.slhaf + Partner + 0.5.0 + + + Partner-Common + + + + + io.modelcontextprotocol.sdk + mcp + 0.17.0 + + + + 21 + 21 + UTF-8 + + + \ No newline at end of file diff --git a/Partner-Common/src/main/java/work/slhaf/partner/common/mcp/InProcessMcpTransport.java b/Partner-Common/src/main/java/work/slhaf/partner/common/mcp/InProcessMcpTransport.java new file mode 100644 index 00000000..fd37dc53 --- /dev/null +++ b/Partner-Common/src/main/java/work/slhaf/partner/common/mcp/InProcessMcpTransport.java @@ -0,0 +1,155 @@ +package work.slhaf.partner.common.mcp; + +import io.modelcontextprotocol.common.McpTransportContext; +import io.modelcontextprotocol.json.McpJsonMapper; +import io.modelcontextprotocol.json.TypeRef; +import io.modelcontextprotocol.server.McpStatelessServerHandler; +import io.modelcontextprotocol.spec.McpClientTransport; +import io.modelcontextprotocol.spec.McpSchema; +import io.modelcontextprotocol.spec.McpStatelessServerTransport; +import reactor.core.publisher.Mono; +import reactor.core.publisher.Sinks; + +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.function.Function; + +public final class InProcessMcpTransport implements McpClientTransport, McpStatelessServerTransport { + + // 每个 transport 只处理一条 inbound 流 + private final Sinks.Many inbound = + Sinks.many().unicast().onBackpressureBuffer(); + + private final AtomicBoolean clientConnected = new AtomicBoolean(false); + private final AtomicBoolean serverConnected = new AtomicBoolean(false); + + /** + * 对端 + */ + private volatile InProcessMcpTransport peer; + + private volatile McpStatelessServerHandler serverHandler; + + public record Pair(InProcessMcpTransport clientSide, InProcessMcpTransport serverSide) { + } + + public static Pair pair() { + InProcessMcpTransport client = new InProcessMcpTransport(); + InProcessMcpTransport server = new InProcessMcpTransport(); + + client.peer = server; + server.peer = client; + + return new Pair(client, server); + } + + /* ====================================================== + * Internal receive: peer.sendMessage -> this.receive + * ====================================================== */ + private void receive(McpSchema.JSONRPCMessage message) { + if (inbound.tryEmitNext(message).isFailure()) { + throw new RuntimeException("Failed to receive message: " + message); + } + } + + /* ====================================================== + * Client → Server sendMessage + * ====================================================== */ + @Override + public Mono sendMessage(McpSchema.JSONRPCMessage message) { + InProcessMcpTransport p = this.peer; + if (p == null) { + return Mono.error(new IllegalStateException("Transport is not linked")); + } + return Mono.fromRunnable(() -> p.receive(message)); + } + + /* ====================================================== + * Client connect(handler) 处理 server → client 消息 + * ====================================================== */ + @Override + public Mono connect(Function, Mono> handler) { + if (!clientConnected.compareAndSet(false, true)) { + return Mono.error(new IllegalStateException("Client already connected")); + } + + return inbound.asFlux() + .concatMap(msg -> + handler.apply(Mono.just(msg)) + // handler may emit response message → send back to server + .flatMap(resp -> resp != null ? sendMessage(resp) : Mono.empty()) + ) + .doFinally(sig -> clientConnected.set(false)) + .then(); + } + + @Override + public void setExceptionHandler(Consumer handler) { + McpClientTransport.super.setExceptionHandler(handler); + } + + /* ====================================================== + * Server: bind stateless handler = process client → server inbound + * ====================================================== */ + @Override + public void setMcpHandler(McpStatelessServerHandler handler) { + this.serverHandler = handler; + + if (!serverConnected.compareAndSet(false, true)) { + throw new IllegalStateException("Server already connected"); + } + + // 订阅 client → server 消息 + inbound.asFlux() + .concatMap(this::handleServerMessage) + .doFinally(sig -> serverConnected.set(false)) + .subscribe(); + } + + /** + * Server 端处理 JSONRPCMessage + */ + private Mono handleServerMessage(McpSchema.JSONRPCMessage msg) { + // 创建 transport context(简单实现即可) + McpTransportContext ctx = key -> null; + + if (msg instanceof McpSchema.JSONRPCRequest req) { + return serverHandler.handleRequest(ctx, req) + .flatMap(this::sendMessage); + } + + if (msg instanceof McpSchema.JSONRPCNotification noti) { + return serverHandler.handleNotification(ctx, noti); + } + + return Mono.empty(); + } + + /* ====================================================== + * other boilerplate + * ====================================================== */ + + @Override + public void close() { + McpClientTransport.super.close(); + } + + @Override + public Mono closeGracefully() { + inbound.tryEmitComplete(); + clientConnected.set(false); + serverConnected.set(false); + return Mono.empty(); + } + + @Override + public T unmarshalFrom(Object data, TypeRef typeRef) { + return McpJsonMapper.getDefault().convertValue(data, typeRef); + } + + @Override + public List protocolVersions() { + return McpClientTransport.super.protocolVersions(); + } +} diff --git a/Partner-Main/data/log/partner.log b/Partner-Main/data/log/partner.log deleted file mode 100644 index cf72c2ab..00000000 --- a/Partner-Main/data/log/partner.log +++ /dev/null @@ -1,111 +0,0 @@ -2025-10-16 18:48:10 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 18:48:10 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:48:10 [main] INFO a.d.h.tokenizers.jni.LibUtils - Extracting native/lib/linux-x86_64/cpu/libtokenizers.so to cache ... -2025-10-16 18:48:10 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:48:10 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 18:49:01 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 18:49:01 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:49:01 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:49:01 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 18:49:57 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 18:49:57 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:49:57 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:49:57 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 18:49:57 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 18:50:08 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 18:50:08 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:50:08 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:50:08 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 18:50:08 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 18:51:15 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 18:51:15 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:51:15 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:51:15 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 18:51:15 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 18:52:08 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 18:52:08 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:52:08 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:52:08 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 18:52:08 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 18:53:22 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 18:53:22 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:53:22 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 18:53:22 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 18:53:22 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 19:10:11 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 19:10:11 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:10:11 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:10:11 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 19:10:11 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 19:12:10 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 19:12:10 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:12:10 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:12:10 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 19:12:10 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 19:15:32 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 19:15:32 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:15:32 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:15:32 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 19:15:32 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 19:15:50 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 19:15:50 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:15:50 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:15:50 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 19:15:50 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 19:18:36 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 19:18:36 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:18:36 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:18:36 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 19:18:36 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 19:19:35 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 19:19:35 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:19:35 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:19:35 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 19:19:35 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 19:28:19 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 19:28:19 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:28:19 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:28:19 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 19:28:19 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 19:28:19 [main] INFO OnnxTest - [0.51123345, 0.43754324, 0.22250144, -0.49621642, -0.59625536, -0.24450612, 0.5863322, 0.46978277, 0.5778739, 0.6761688, -0.0854191, 0.36117497, -0.24092007, -0.19524571, -0.7976704, -0.044580948, -0.53635055, -0.11370213, -1.1403378, 0.2129236, -0.34120926, 0.001864681, -1.3665671, -0.22030343, -0.830733, 0.099989876, 0.4966247, -0.066141784, 0.41148925, 0.729914, -0.29459542, 0.29208705, -0.3367949, -1.0972055, -0.024628287, -0.6583721, 1.253141, -0.61462474, -0.518246, -0.53295904, 0.12913027, 0.04108283, 0.55130756, -0.8039789, -1.2061563, -0.34272343, 0.27257943, -0.13096467, 0.18428354, 0.2605311, 0.057498857, 0.7461083, 0.1835212, 0.021440782, -0.20071763, 0.04362084, -1.3614484, -0.1095237, -1.0870106, 0.40957803, 0.7201999, 0.98604536, 0.39732328, -1.3224756, 0.40671548, 0.406975, 0.50348455, 0.22034347, 0.5530567, 0.25672144, -0.6594347, 0.96159023, 0.07775575, -0.7792945, -1.0163779, 0.36998796, 0.5171132, 0.79771215, -0.5552498, 0.80050594, 0.14805704, 0.2997373, 0.26703542, 0.08637628, -1.4002664, -0.813782, 0.25788978, 0.5414073, -0.46593362, -0.027594358, 0.29689378, 0.65353656, -0.31033817, 0.08076967, 0.76214606, 0.8415609, -0.3084258, -0.32594687, -0.72558767, -0.3289697, 1.0932022, 0.87115157, -0.89196694, -0.18925445, -0.9785898, -0.2336246, -0.9026102, 0.088704094, -0.7258216, -0.6594782, 0.09606822, 1.0850618, 0.0013394654, 0.38363743, -0.3874976, 0.20100841, -0.4128504, 0.74124134, -0.6654147, -0.5718573, 0.27072686, -0.046442233, -0.2115764, -0.7070531, -0.9749727, -0.4404279, -1.3043284, 0.93771523, 0.30211914, -0.59651214, 0.12527934, 0.089207426, 0.51316845, 0.8074455, -0.5485792, 0.07305289, 0.10457601, 0.24046482, 0.5214334, -1.1262523, 0.16574118, 0.01661903, -0.72924286, 1.7897038, 0.7391656, 0.26545036, -0.24889244, 0.019522466, -0.38037547, 0.9288784, -0.90373176, -0.2429637, 0.13991763, 0.4122005, -0.6420515, -0.045609288, -0.055985063, 0.121364415, 0.28139967, -0.0052891895, -0.106420964, 0.56713265, -0.46813145, 0.19711205, -0.58464926, 0.3698026, -0.2838148, 0.12638272, 0.01481974, -0.2993888, 0.14940853, -0.4162319, -0.045515813, -0.07729791, 0.47421545, 0.46603337, 0.62959045, 0.1828863, 0.2002228, 0.07522717, -0.50393486, 0.37032261, -0.35638678, 0.8902856, -0.033868957, 0.100021124, 0.43048963, 0.3153236, -0.6283139, -0.24138638, 0.81751156, 0.2257601, -1.2130985, 0.44707552, 0.0037308559, 0.5666142, -0.8444263, 1.204924, -0.65543765, -1.9701289, -0.8207577, 0.08641613, -0.4112931, -0.20802015, 0.87505317, -0.13793634, 0.07145847, 0.31840786, -0.092020944, -0.80500084, 0.58076894, 0.117715076, -0.67379886, 0.45848575, 0.4390001, -0.7055742, -0.712911, 0.33785975, 0.42191327, 0.121282555, 0.13419384, 0.17775199, 0.5506595, 0.67962146, 0.4780363, -0.03222577, -0.8667363, 0.8303137, -0.541459, 0.062450707, 0.03477095, 0.49735057, -0.3892, 0.8767689, -0.06756614, 0.35541242, 0.94193155, 0.8131012, 0.58299375, 0.1854296, -0.60147816, 0.4282838, 0.5299751, 0.7330451, -0.3257398, -0.58661395, 0.5521986, -0.606695, 0.44539154, 0.41345364, -0.023682468, 1.0244411, 0.8901564, -0.025144015, -0.6341725, -0.4240578, 0.31344998, 1.0556707, -0.7415066, -0.32343262, 0.1841922, 0.36124998, 0.5530684, 0.29907, -0.02951768, 0.19808297, 0.08838599, 0.05037989, -0.049141884, -1.1747736, 0.03532947, 0.07290274, -0.7062243, -0.027512219, -0.5645471, -0.034089435, 0.4769841, -0.5791185, -0.062474817, -0.5574461, -0.07675014, -0.58530134, 0.5648111, 0.7009718, 0.19080682, -0.37462634, -0.38008162, -0.8266342, -0.56594104, 0.6085925, -0.8169755, 0.2305794, 0.022104293, -0.32453218, 0.029340252, 0.12966694, -0.35197243, 1.0937076, -0.08106287, -0.630723, -0.07665277, 0.09807674, -0.15652439, -0.032777905, -0.59978753, 0.7365465, 0.8591844, -0.16815796, 0.8361499, 0.27674484, -0.3099411, 0.60480386, 0.23437774, -0.7338224, -0.9829839, 0.67439365, 0.742201, 0.42505273, -0.68957865, -0.47552192, -0.5682225, -0.5110189, -0.28437212, -0.565194, -0.19356139, 0.63973606, -0.014390081, -1.646161, 0.2918704, -0.4594489, -0.8228203, -0.16133638, 0.07148346, 0.9419251, -0.019150853, -0.4403408, -0.56392926, 0.12463045, 0.24700657, -0.19791731, 0.6058087, -0.5370069, -0.051276788, 0.9354616, -0.055462413, 0.050041005, -0.6077635, -0.68125796, -0.13532986, 0.36517376, -0.019653555, -0.03586552, -0.1600579, 0.67996794, -0.25741813, 0.9547673, -0.910809, -0.009982694, 0.7332152, -0.20394151, -0.09925252, 0.5988749, 0.10125684, -0.2892084, 0.09639569, -0.9270706, -0.14898436, 0.23913115, 0.7453801, -1.0168681, 0.80838275, -0.27111107, -0.14699328, -0.68104225, 0.19166322, -0.79916215, 0.43923154, 0.16553934, 0.33551145, -0.5704513, -0.070023894, -0.3918103, -0.17701462, 1.6619401, 0.674843, 0.23895527, 0.80687135, -0.01851894, -0.34060583, -0.58362544, -0.96381485, -0.19843449, 1.6370385, -0.44541967, -0.13564552, -1.7383175, 0.94101083, 0.4386875, 0.8844557, 0.7002662, -0.72894764, -0.6103935, -0.32648364, 0.054746274, -0.6872155, 0.18739484, -1.0520368, 0.6648933, -0.2648567, -0.06654116, -1.3043286, 0.22864798, -0.10361338, 0.594177, 0.5787685, 0.1750473, -0.0105097145, 0.91527426, 0.25346497, -0.27341178, -1.1472199, -0.31140554, -0.49403697, -0.13216135, 0.7429359, -0.57663065, -0.5814875, -0.46789917, 0.62059444, 1.0459176, 0.105841815, -0.8354111, -0.09153462, -0.4892223, -0.9736461, 0.03827665, 0.6993418, -0.5639835, 0.3098794, -0.8142145, 0.047523424, -0.21321937, -0.034833632, -0.010952409, -0.041929975, -0.28044957, 0.060209088, 0.50224316, -0.046635136, -0.85428065, 0.73049414, -1.4654225, 0.11870827, -0.66137636, 0.27924734, -0.7339802, -0.42894232, 0.17209588, 1.1703713, -0.1511008, -0.27938917, -0.13280374, 0.86497086, -0.4407706, -0.3784376, 1.2453586, -0.21126446, -0.15996158, 0.48933926, -0.27048388, -0.2984165, 0.7081715, 0.58110875, -0.06946933, -0.27087092, -0.23854852, 0.36320952, 0.3962092, 0.11321919, 0.10443739, -0.56340504, 0.49124345, 0.6088691, -0.70054543, -0.09448326, -1.4692224, 0.24175254, -0.18142638, 0.3656459, 0.3561722, 0.39745298, 0.35550624, -0.25403917, -0.8084114, -0.3391734, -0.14518976, -0.31460696, -0.8502122, -0.20892489, 0.040290922, 0.36273193, -0.76562995, -0.80031925, 0.060696647, -0.15262939, -0.061190173, -0.09423466, 0.6150074, -0.5358167, 0.3251421, 0.28123394, 0.7587028, -0.4789124, -0.10876167, -0.18576714, 0.49481302, -0.09939133, 0.20352225, -0.5852573, 0.6395335, -0.3011577, -0.8522485, -0.31254715, 0.5950347, -0.26513442, 0.70972127, 0.43091288, -0.041825093, -0.2292053, -0.6451991, -0.34200215, -0.41545817, -0.2689111, -0.9946734, -0.25178003, 0.6669945, 0.17163065, -0.15006264, -0.9421287, -0.019158833, -0.6975499, 0.438868, -0.6849216, 0.03262051, -0.44509438, 0.64882565, -0.5953382, 1.1495787, -0.8011461, 0.20847918, 0.1251037, 0.32168102, -0.21917565, 1.0629005, -0.92278206, -0.37890035, 0.4195118, -0.21815889, 0.2514746, 0.6282729, -0.14128427, 0.050928507, -0.35163182, -0.06737878, -0.9663225, -0.4687798, -0.59459, 0.21002933, 0.048163563, 0.48905462, 0.14316124, 0.028260775, 1.2529061, 0.14390653, -0.21695222, -0.7194682, -0.66993797, -0.70739895, -0.5410352, 0.8340246, -0.2935943, -0.23657572, -0.4150082, 0.20044121, 0.6332451, -0.4892323, -0.016682208, 1.8937812, 0.7091852, 0.14414868, -0.9804469, 1.2162073, 0.17216161, -0.50498605, -0.34003568, 0.16963801, -0.33994526, 0.0731189, -0.41613013, -0.94484633, -0.815923, -0.5739614, 0.94484705, 0.31987455, 0.14467219, -0.14761059, -0.7047535, -1.0639687, 0.40880874, 1.3001518, -0.23591296, 1.0019474, 0.69951487, 0.33188945, 1.2750803, -0.47983044, 0.033220377, 0.12004468, 0.9492074, 0.9103111, -0.052080557, 0.58394325, 0.8401497, -1.830512, -1.4265813, -0.17748688, -0.061487965, -0.1359964, -0.88339686, -0.37029758, -0.13061845, -0.2954845, 0.2814227, 0.25465572, -0.19771555, 0.09913704, -0.15107808, 0.011260349, -0.14225599, -0.11415321, 1.0593241, -0.7078028, 0.5747197, -0.4055798, -0.18129641, -0.47820956, 0.1952592, 0.22990699, 0.5002197, 0.10373032, 0.628042, 0.06865163, 1.0157357, -0.6903584, -0.15411828, 0.6126792, -1.4284332, -1.3705213, -0.07465902, -0.11910443, -0.13134138, 0.41676903, -0.21215296, -0.028965306, 0.3505228, 0.047843248, 0.30888152, -1.1421498, -0.08647778, -1.1076055, -0.78975534, -0.05059923, 0.058172554, 0.27877957, 0.3418617, 0.27528864, -0.0043393373, -0.425253, 0.21216352, 0.02201505, 0.46995455, -0.35277224, 1.1497868, -0.7000632, -0.49699458, -0.36768207, -0.08427355, -0.106513396, -0.15144402, -0.6940467, -0.6297557, 0.4525672, 1.2141936, -0.12161607, 0.24308786, -0.1425119, -0.38016897, 0.91598785, -0.41090524, 0.14860485, 0.28929144, 0.21543092, -0.84538454, 0.0807224, -0.2773164, 0.5301908, -0.7331233, 0.49941978, 0.5512182, -0.5476493, -0.18183059, -0.77233905, -0.15702356, -1.1651708, -0.21300837, 0.018835044, 0.32697025, 0.34967226, 0.51722765, 0.09109617, 0.61710453, 0.062239163, 0.056631085, 0.06611446, 0.46277747, 0.13079983, 0.08349137, -0.17646214, 0.26698142, 0.046738572, 0.6847735, 0.38814327, 0.014033079, -0.04680039, 0.292931, -0.8164349, 0.3852389, 0.19666976, 0.37969127, -0.23450008, 0.45247716, 0.4581556, -0.9366612, 0.5417323, -0.055298187, -0.6215795, 1.218463, -1.3511043, -0.7937524, 0.008464169, -0.9959098, 0.7161945, -0.25348237, -0.68490624, 0.39310396, 0.3586596, -0.7416965, -0.18592128, 0.30235815, 0.63015443, -0.33157557, -0.89634436, -0.5073603, 0.27419057, 0.112835586, 0.471214, -0.9042775, -0.41822886, 0.71185523, 0.6571464, 0.33782732, 0.15355957, -0.1364721, -1.0384371, 0.64586115, 0.5162391, 0.52103496, -1.1132919, 0.1564614, -0.35837764, 0.7777977, -0.5688318, -0.19020915, 0.12580645, 0.23848471, 0.050079808, 1.4870666, 0.74930036, 0.11167382, 0.51369834, 0.0912603, 0.03457948, 0.97924113, -0.2526727, -0.6790167, 1.0118998, 0.17009932, 0.59963554, 0.38631436, 0.5874571, 0.35385707, -0.49165446, -0.43353337, 0.29959297, 0.90330774, 0.008084901, 0.19826728, 0.035730332, -0.26280853, 0.49997848, -0.3445545, 0.25782338, -0.29269776, -0.7271916, -1.1451478, -0.3687011, 1.2749437, 0.28989944, -0.010594554, 0.20570764, -0.039815754, 0.7760036, 0.83210295, -0.37314057, 0.34827492, 0.33832714, 0.2549089, 0.3180246, 0.15750375, 0.37374565, 0.29076517, -1.084236, -0.2536879, 0.09893724, 0.167326, -0.42620236, -0.06183477, -0.85039747, 0.7655713, 0.5407811, 0.135566, 0.61822957, -0.658225, 0.060597345, -1.0510322, 0.29207668, -0.40406957, -0.06383139, 0.8471315, -0.3460373, 0.0568925, 0.42080507, 0.50762975, 0.29434744, -0.07577321, 0.5478096, 0.31866163, 0.77027106, 0.5869493, -0.4031725, 0.34900978, 0.03501825, -0.60266703, -0.12610222, 0.48031133, -0.843012, 0.4924527, -0.8623877, -0.6477808, 0.22316428, 0.52191186, -0.42713517, -0.4163384, 0.02406159, 0.19311489, -0.8280169, 0.7257932, 0.5891742, 0.6126962, -0.107232764, -0.07629745, -0.50356364, 0.6316943, 0.1606891, -0.70639515, -0.12811224, -0.4105088, -0.08755256, -0.40668, -0.5366433, -0.30879006, 0.10060625, 0.28111058, -0.71532774, -0.3630196, 0.59962934, 0.15385062, 0.36727977, -0.45993006, 0.22452451, -0.23574719, 1.6684455, -0.043385856, 1.6276766, -0.16736466, -0.12352954, 1.0252162, -0.27102458, 0.59440255, 0.26338896, -0.2930035, -0.61721444, 0.6569015, -0.34776017, -0.38311705, -0.4351132, 0.751855, -0.44927332, 0.28445652, -1.4778186, -0.5496483, -0.834149, -1.1146356, -0.8802563, 1.0398924, -0.14450291, -0.022082053, -0.009103067, -0.8312893, 3.564548, 0.31639445, 0.43401474, 0.63638914, 0.048858773, -0.24585214, 0.42760444, -0.627559, 0.36051834, -0.75384, 0.3967399, 0.078143656, 0.12599553, 0.86665404, 0.050567865, 0.92432106, -1.5632179, 0.19709128, 0.12208514, -0.078961484, -0.91890043, 0.23671533, 0.47289363, 0.19900943, 0.7240069, 0.16399404, 1.1182141, -1.0169126, -0.1350502, -0.46091932, 1.2807544, 0.35965964, 0.21481083, -0.3007364, -0.39301196, 0.9101389, 0.1932972, 0.15104347, 0.14832743, 0.27131686, -0.067170985, -0.6418764, 0.50354594, 0.25878644, -0.0033070669, 0.70426977, -0.6287618, 0.31597823, 0.45087764, -0.04529953, 0.8379618, -0.3591785, 0.56057227, -0.5669976, -0.84720474, -0.052068297, -0.16401154, 0.30864736, -0.8251212, 0.22997884, -0.28843462, 0.20421404, -0.10270865, 0.12777951, -0.34080166, 0.28729475, 0.63097245, 0.62922233, -0.23039082, -0.9737556, -0.37730604, 0.021021312, -0.18025522, -1.0727465, 0.0019658804, 1.0562756, -1.0607209, 0.55097324, -0.095470026, -0.16923568, 0.29799882, 0.13360816, -0.015510071, -0.3002998, 0.29892552, 0.5038376, 0.07581481, -0.25795814, -0.26878086, -0.018943973, 1.1134932, 0.84816736, 0.07172927, -0.119864315, 0.16197601, 0.55967194, -0.1490119, 0.35443506, -0.12817872, -0.7264169, 0.35164982, 0.5088061, 0.36944637, 0.75947386, 0.22153465, -0.0902444, 0.35916293, -0.22257099, -0.6245021, -0.66597265, -0.2242328, -0.47101194, -0.09299229, -1.0377257, -0.21733049, -0.32486138, -0.23556301, -0.9277732, 0.023987524, -0.5385696, -0.002912309, 0.6834146, 0.06879748, 0.26568368, 1.1300062, -0.17972237, 0.1250636, -0.06957579, -0.9457501, -0.10762876, -0.7763465, 1.5165349, -0.51138073, -0.53803205, -0.7513938, -0.16054633, -0.057135716, 0.56398803, -0.7251428, -0.9011231, -1.1330264, -0.009565931, -0.46391025, -0.3945485, -0.019825712, -0.214825, 0.662374, 0.4089401, -0.25013703, -0.11175172, -0.3359659, -0.73787993, -0.44064045, -0.95422965, 0.24658713, 0.5482323, 0.44154587, 0.15066868, -0.90368706, 0.16147381, 0.23279902, 0.41150323, -0.14870353, 0.4448821, 0.3361582, -0.5416869, 0.66956925, 9.3244016E-4, -0.58035725, -0.9133776, -0.21026349, 0.47709528, 0.559402, -0.096517116, 0.34964085, 0.021026324, -0.052352354, 0.2260392, 0.083108045, -0.82103014, -0.49560097, 0.13991357, 0.72335935, -0.22744378, -0.17416112, -0.06924981, 0.1720519, -0.056980915, -0.0040308535, 0.4777559, 0.34662804, -0.6132766, -0.1805803, -0.58219105, -0.5035861, 0.743928, 0.62252325, -0.43229088, 0.42164406, -0.7834892, 0.19773507, -0.68034565, 0.15410969, -0.46971694, -0.5955516, 0.23321742, 0.61164176, -0.10516539, 0.581982, -0.7406695, 0.31757313, -0.69854766, 0.9880034, -0.84722793, -0.7633326, 0.4578721, 0.10518447, 0.16203061, -0.6790652, -0.47155732, -0.38882074, -0.9170391, 1.0266749, -0.17550212, -0.4792506, -0.0668991, 0.39064267, 0.0947658, 0.8043089, -0.22434905, -0.313821, 0.052670494, -0.048851267, 0.32592362, -0.860603, 0.2698992, 0.3433336, -0.21785763, 1.5819844, 0.88469046, 0.07691138, 0.09752565, -0.42556408, -0.04519853, 0.87291956, -0.6176682, -0.2865502, 0.20136131, 0.36512914, -0.3311012, -0.30614272, -0.26107365, 0.1894452, 0.32637066, 0.35523584, -0.06667226, 0.10347664, -0.11940256, -0.10296476, -0.38421103, 0.6074242, 0.18352178, 0.015820663, -0.14712866, -0.20719282, 0.6038181, -0.15472703, -0.039784297, 0.059039198, 0.4398168, 0.68517715, 0.592921, -0.48001018, 0.29964036, 0.059656337, -0.36691985, -0.11802984, -0.16027823, 0.8514473, 0.061800294, -0.24240336, -0.00616711, -0.2318474, -0.27456677, -0.20014185, 0.39548382, 0.08403352, -0.6075959, 0.7013164, -0.24715367, 0.7730584, -0.5263237, 0.6818461, -0.4345966, -1.9885256, -0.57651246, 0.3897464, -0.22896479, 0.029132985, 0.62822366, -0.3221436, -0.24454945, -0.13972506, 0.07538301, -0.43282226, 0.29167226, 0.26169014, -0.22840403, 0.12716646, 0.5241455, -0.67354554, -0.23412356, 0.1583346, 0.09397203, -0.6005605, -0.062070902, 0.519738, 0.56230676, 0.19490737, 0.09140409, 0.2827071, -0.7554103, 0.9776802, -0.28762445, -0.16992666, -0.27326876, 0.5205804, -0.39026648, 0.8100204, 0.2251311, 0.3743077, 0.41226578, 0.28279757, 0.10248689, 0.78833973, -0.39051318, -0.035605595, 0.6300383, 0.67743725, -0.18472652, -0.3580135, 0.14300483, -0.36656314, 0.09548992, 0.6840508, 0.53377825, 1.0797411, 1.0701865, -0.14112248, -0.1359908, -0.52505445, 0.2282274, 0.8130599, 0.10876868, -0.5497892, -0.06409781, -0.12850465, -0.08437914, -0.348632, -0.55334604, -0.057698317, -0.020369263, 0.0053720847, 0.16307293, -0.8254809, -0.10885659, -0.54735035, -0.9688062, -0.2985726, -0.051860273, -0.13334262, 0.35509858, -0.8054574, -0.28351018, -0.68802255, 0.17037089, -0.7018103, 0.8101351, 0.96281683, -0.053284153, -0.42187208, -0.41856027, -0.7051473, -0.43084157, 0.46245623, -0.6828755, 0.13075721, -0.12911314, -0.28247756, 0.683695, 0.07331526, 0.008655533, 1.0331321, 0.41872248, -0.43458146, 0.11952154, 0.4864054, -0.4770374, -0.672267, -0.7951411, 0.90124786, 0.38761422, -0.06815794, 0.4979946, 0.3519773, -0.51443356, 0.47134402, 0.32008561, -0.52492595, -0.5968779, 0.91214985, 0.62872326, 0.25207788, -0.78720355, -0.65435094, -0.3022893, -0.026059672, 0.03250689, -0.4841232, -0.21127056, 0.94293606, -0.31384826, -1.024962, 0.4258807, -0.5591192, -0.85103065, 0.07572705, -0.029542465, 0.9386782, -0.01834616, -0.41138232, -0.41427138, 0.080845095, -0.021675527, -0.25335732, 0.85154873, -0.83299226, 0.010143421, 0.7232927, 0.60553235, 0.1309088, -0.3839781, -0.5941144, -0.45264992, 0.38672507, 0.21139218, 0.34125578, -0.30670395, 0.5510206, 0.19656421, 0.7967939, -0.61074483, 0.032774314, 0.4495337, -0.4416033, 0.04436638, 0.19213377, 0.25077653, -0.1421333, -0.07981576, -0.80517834, -0.44514215, 0.12253037, 0.5937313, -0.7326427, 0.7710463, -0.47982028, -0.026294831, -0.27366686, 0.59971505, -0.88799405, 0.34242895, 0.011235021, 0.68797493, -0.31184798, -0.2491819, -0.39411223, -0.37572742, 1.597634, 0.5555229, 0.53293955, 0.85264903, -0.014117359, -0.04914263, -0.32758757, -0.42537898, 0.016268618, 1.7822325, 0.014657244, -0.33223224, -1.4506384, 0.8279289, 0.63178736, 0.70278394, 0.16083482, -0.11632228, -0.42550898, 0.2825111, 0.050327733, -0.62059164, 0.24553949, -0.84764546, 0.5793387, -0.19014005, 0.18559122, -0.60808384, -0.22480549, -0.10949272, 0.4119357, 0.48874575, 0.10797066, 0.14826402, 0.95159596, 0.1007035, -0.28172037, -0.78677756, -0.2911378, -0.39184836, 0.18129729, 0.14663315, -0.6903422, -0.6197286, -0.22756599, 0.4553, 0.7559648, -0.19024116, -0.7333675, -0.22558317, -0.10755519, -0.8364387, -0.24587573, 0.61560297, -0.116256624, 0.09515799, -0.61133057, -0.60270244, 0.11373564, -0.478234, 0.054566797, 0.21379222, -0.20055366, 0.4200289, 0.38137415, 0.57250637, -0.8365286, 0.46541566, -1.5011121, 0.007360235, -0.7604555, 0.0025998056, -0.5833547, -0.07466688, 0.39678958, 0.96836436, -0.2345093, -0.18433093, 0.3012629, 0.2799663, -0.70134974, -0.48911846, 0.7690916, -0.06511322, -0.49618146, 0.3662134, -0.6264914, -0.22856562, 0.24773872, 0.3183567, 0.13739681, 0.07009312, 0.23409715, 0.34881467, -0.33139125, 0.28852808, -0.095444344, -0.51926076, 0.51465845, 0.2062692, -0.5242261, -0.46329415, -0.9741153, 0.06456158, 0.030457906, 0.14805505, 0.17728561, 0.27969873, 0.4174524, -0.53553534, -0.050896656, -0.7748257, 0.07999295, -0.064726844, -0.6482009, -0.16539901, 0.52794135, 0.2680578, -0.54837555, -0.846483, -0.1018344, 0.2759287, 0.01647371, -0.30559725, 0.77830505, -0.42698085, 0.22914001, 0.29629123, 0.9014104, -0.6857988, -0.02880317, -0.27855328, 0.5116826, -0.09280562, -0.026375346, -0.82933587, 0.29830056, 0.10016385, -0.9599105, 0.06670639, 0.32166743, -0.12561196, 1.15202, 0.17707397, -0.08005495, -0.039337177, -0.2968356, -0.12169429, -0.36883074, 0.2049313, -0.6679535, 0.031608433, 0.52695143, 0.007821337, -0.1485552, -0.62809414, 0.13040474, -0.15451281, 0.54773754, -0.4706813, 0.24263154, -0.1301415, 0.67641205, -0.62720996, 0.8313544, -0.7381075, -0.14358105, 0.3762475, 0.62239164, -0.045437563, 0.9459873, -0.8233303, -0.7147683, 0.46758357, -0.52135533, 0.06063361, 0.56855184, -0.507306, -0.036665827, -0.6302179, 0.07766994, -0.942735, -0.5909925, -0.2635432, 0.5478883, -0.07890162, 0.32488316, 0.26487243, 0.46853012, 1.1034807, -0.06512659, 0.33847657, -0.61609834, 0.06321365, -0.22743702, -0.87944865, 0.37845594, -0.020726902, -0.59833187, -0.42895967, -0.11077006, 1.0032699, -0.1725022, 0.32639518, 1.6419518, 0.21870343, 0.1484011, -0.7495263, 0.5773338, 0.1948407, -0.26478645, 0.31931522, -0.02530934, -0.18381046, 0.039240766, -0.3821348, -0.880036, -0.40542898, -0.5050127, 1.0508015, 0.6978597, 0.27783167, 0.43318307, -0.686163, -0.95909375, 0.39126918, 0.736118, 0.010625005, 0.4478026, 0.5347271, -0.28854454, 0.7788674, -0.65132344, 0.028316252, -0.24979532, 0.3684371, 0.8357179, -0.35869396, 0.24370271, 0.33024335, -1.4370449, -1.2778331, 0.19882585, -0.017336432, -0.4316948, -1.2735684, -0.26503587, -0.015060261, -0.6085152, 0.22704697, 0.26457584, -0.42646304, 0.03879311, -0.19615118, 0.44677356, -0.32433823, -0.084605284, 1.198679, -0.51367915, 0.36138633, -0.26781407, -0.25285503, 0.10098021, -0.24817827, -0.18135414, -0.17848538, 0.35427713, 0.521286, -0.02674108, 0.4217017, -0.08987662, 0.25608358, 0.50207585, -0.98633564, -1.0628304, -0.3846806, 0.022207262, -0.1283618, 0.37523708, -0.24025467, 0.5153696, 0.46323073, 0.13989824, 0.1561494, -0.77944976, -0.44046345, -0.63301426, -0.34989792, 0.13549271, 0.006190121, 0.24559984, 0.31742877, 0.1545193, -0.44265345, -0.08644013, 0.28001422, 0.15021466, 0.85503155, -0.76575583, 0.86318636, -0.55829847, -0.25753778, -0.7185067, -0.085994214, -0.18091784, 0.446105, -0.77112305, -0.4430915, 0.2551184, 1.1472955, -0.40047967, 0.35478163, -0.4045759, -0.48856065, 0.7408055, -0.13986495, 0.09953445, 0.2774477, 0.2467106, -0.42283788, 0.21039721, 0.10461013, 0.31418386, -0.6786972, 0.964533, 0.6333979, -0.42829648, -0.2897507, -0.9437793, 0.067182526, -0.99148446, -0.31607157, -0.5791597, 0.04460093, 0.2817655, 0.21890405, -0.0091788955, 0.614969, 0.21509607, 0.26194388, -0.028229192, 0.6323737, 0.3229837, -5.941242E-4, 0.1451681, 0.3452308, 0.26828063, 0.82891965, 0.6615142, 0.15845887, -0.1930975, 0.32330292, -0.49461275, 0.33965734, 0.5015075, 0.22370936, -0.038758203, 0.33031383, 0.64308834, -0.22973657, 0.40101275, 0.1735294, -0.62445706, 0.63983095, -1.0835669, -0.59931755, -0.25685513, -1.0129862, 0.148363, -0.3387562, -0.7876695, 0.36497584, 0.4875883, -0.46318775, -0.30246222, 0.24639976, 0.3614344, -0.4353444, -0.7491151, 0.03876262, 0.014877375, 0.5000705, 0.48863775, -0.5708522, -0.29530814, 0.39000627, 0.18866692, 0.13831648, -0.38619447, -0.5484635, -1.1455809, 0.14575654, 0.41666955, 0.17747879, -0.8406549, 0.13223548, -0.45904288, 1.1353003, -0.26693252, -0.12810816, 0.37510347, -0.29213232, -0.43941584, 0.9184803, 0.6855956, 0.2599459, 0.6948795, -0.0708392, -0.12901774, 0.55323, -0.5387498, -0.716477, 0.42386472, 0.12503567, 0.6216118, 0.10394464, 0.8343109, 0.65234077, -0.41163832, -0.39263293, -0.108594045, 0.4115751, 0.16237709, 0.28965876, -0.07473482, -0.23911166, 0.2871039, -0.6131977, 0.513528, -0.11655871, -0.6466727, -1.1273916, -0.19115873, 1.4469596, -0.020101145, -0.11192806, 0.01993516, 0.26601622, 1.1657052, 1.008147, -0.6360585, 0.12956598, 0.9011077, 0.26741764, 0.13538633, -0.082566485, 0.21531783, 0.26441088, -1.1124214, -0.27627683, 0.34551474, 0.15321879, -0.21587288, -0.29057226, -0.5665258, 1.2804754, 0.5072227, 0.2061311, 0.39224344, -0.48967192, 0.2075164, -1.2929554, 0.22832677, -1.1763334, 0.05883432, 0.5320689, -0.19186282, -0.067902, 0.5984157, 0.33769348, 0.24878782, 0.11002658, 0.33792466, 0.547646, 0.7538705, 0.59686947, -0.19582872, 0.39902282, -0.3311249, -0.74637324, -0.14266883, 0.43165115, -0.6139184, 0.29811418, -0.7535113, -0.30266273, 0.53370935, 0.36760342, -0.5749821, -0.68662786, -0.2779321, 0.37260574, -1.1336465, 0.6302474, 0.47815326, 0.9866135, -0.14947067, -0.033082485, -0.2046695, 0.20482336, -0.21032988, -0.52653766, 0.0245497, -0.47625363, -0.12423223, -0.12356821, -0.32638925, -0.0979994, 0.0010491088, 0.29562947, -0.6457077, -0.10971795, 0.06126561, 0.8076332, 0.2573005, -0.21695858, 0.46280462, -0.5214897, 1.3339914, 0.23493724, 1.6153331, 0.18739215, -0.35449666, 0.6756968, -0.35441598, 0.49293745, -0.08351409, -0.24639843, -0.57777464, 0.98248875, 0.0011553783, -0.68022805, -0.1735664, 0.5991789, -0.5056995, 0.28030026, -1.3956647, -0.29886672, -1.040315, -0.6200091, -0.55999726, 0.4394985, 0.25020325, -0.030757431, 0.41339186, -0.99428976, 4.134183, 0.21829394, 0.2768517, 0.24642767, 0.027245255, 0.22640549, 0.47818106, -0.79617405, 0.4751648, -0.4929724, 0.5096883, 0.14533526, 0.087542474, 0.42481625, -0.26212215, 0.94900197, -0.995192, 0.37323165, 0.48663512, 0.16938138, -0.9202455, 0.32618392, 0.3355089, -0.12735334, 0.39952835, -0.4738593, 0.17960149, -0.8438873, -0.15847224, -0.28993642, 1.529727, -0.06471403, 0.040852357, 0.038847372, -0.25056893, 1.0816733, -0.30027992, 0.33796108, 0.057108454, 0.27828, -0.07463636, -0.7907264, 0.89314646, 0.11971448, -0.2797623, 0.56961, -0.5983841, 0.07197225, 0.6231197, -0.16240701, 0.8118333, -0.10884293, 0.36955264, -0.30067077, -0.54466736, 0.23035151, -0.11903405, 0.15843613, -0.9551723, -0.008313894, -0.09104793, -0.34124452, 0.019560076, 0.22333694, -0.46288738, -0.06519584, 0.8732297, 0.4417033, -0.3591715, -0.79684395, -0.18898311, -0.00398656, -0.32608062, -0.624982, -0.43221474, 0.7961611, -1.0244153, 0.6864666, -0.38873324, -0.66227776, 0.18808874, -0.2118657, 0.12453443, -0.20756744, 0.2250452, 0.5361353, -0.38134813, -0.12358688, -0.50916564, 0.06882605, 0.5491102, 0.6088567, 0.043271434, 0.034038477, -0.14568043, 0.34731272, 0.27437162, 0.4291449, -0.5072562, -0.6460547, -0.17843097, 0.4998613, 0.4862506, 0.48174888, 0.43009067, -0.07885784, 0.25953156, -0.44193333, -0.2746965, -0.72802746, -0.24735373, -0.46056688, -0.08113882, -1.2671432, 0.05059053, -0.43514493, 0.09988372, -1.3890023, -0.5439976, -0.5726784, 0.042483523, 0.45590004, -0.12616622, 0.629282, 0.96405625, -0.42434147, 0.29803038, -0.16519342, -0.9395849, -0.230326, -0.83917814, 1.4581625, -0.57237923, -0.5016961, -0.5101177, 0.03989938, -0.16089517, 0.91115934, -0.69840354, -1.4957484, -0.25355923, 0.24498278, -0.03987664, 0.28695616, 0.33610544, 0.42031482, 0.26267177, 0.26665464, -0.036663882, -0.3205201, 0.08044999, -1.3707422, -0.10242602, -1.2773657, 0.44744903, 0.4707493, 1.1146326, 0.52519447, -1.0453299, 0.22108254, 0.3916083, 0.51568663, 0.2354028, 0.50902164, 0.15007426, -0.6983879, 1.0460291, 0.11031413, -0.68165857, -0.867732, 0.08759557, 0.32828143, 0.90392447, -0.74337864, 0.6990192, 0.12273654, 0.1353184, 0.41217592, 0.24795906, -1.3185968, -0.7651147, 0.103916384, 0.6086596, -0.29084563, 0.022982366, 0.28086853, 0.55208766, -0.31949097, -0.01541844, 0.81749123, 0.83401155, -0.14799729, -0.33081663, -0.8713344, -0.20599653, 1.2038018, 0.81881714, -0.62137777, -0.08521465, -0.9437865, -0.19047725, -0.9235109, 0.07554969, -0.54554856, -0.72309697, 0.10257645, 1.2262453, 0.11698446, 0.5399791, -0.6098297, 0.077516764, -0.1635267, 0.7329004, -0.6491352, -0.43532693, 0.13268438, -0.062738866, -0.037672497, -0.6150539, -0.792422, -0.32316244, -1.1831503, 0.8048623, 0.43596715, -0.80266297, 0.20404984, 0.040005, 0.51196873, 0.61864376, -0.3671871, 0.039022297, 0.08777553, 0.34561458, 0.48366174, -1.1842922, 0.108419, 0.09672105, -0.4544338, 1.6715314, 0.8024864, 0.38295293, 0.11245011, -0.13004047, -0.25588313, 0.9442645, -1.106852, -0.3146361, 0.17383303, 0.26125604, -0.836142, -0.2676666, 0.09179972, -0.11250311, 0.35692418, -0.074471295, -0.117300734, 0.47520566, -0.5543069, 0.32387045, -0.66126156, 0.395984, -0.23777974, 0.31760883, -6.269303E-5, -0.42587698, 0.3092674, -0.26971295, 0.12728855, -0.09048116, 0.3214799, 0.6557833, 0.40655518, -0.043354645, 0.23725055, 0.05158411, -0.5487681, 0.47276476, -0.42214486, 0.96318287, 0.101917736, 0.04613815, 0.37172058, 0.35901445, -0.55353534, -0.28215954, 0.646838, 0.055748854, -0.94629276, 0.52053577, -0.096165426, 0.68151516, -0.86083305, 1.2210809, -0.61603034, -1.8547043, -0.70553493, 0.08560893, -0.32475078, -0.07537295, 0.9242262, -0.3031748, -0.039215017, 0.48975095, 0.07386944, -0.635114, 0.5792452, 0.11396569, -0.79614615, 0.47500247, 0.22382374, -0.7640738, -0.7832393, 0.32251167, 0.2957459, 0.19379763, 0.1966333, 0.19957598, 0.47575438, 0.72345144, 0.2891014, -0.07611428, -0.7970295, 0.68839777, -0.65931904, 0.18129885, -0.1070019, 0.4440913, -0.3229485, 0.87062204, 0.0016378155, 0.34254807, 1.0556462, 0.9242675, 0.3841158, 0.19424327, -0.5399717, 0.45922905, 0.4348209, 0.7463028, -0.23992652, -0.60218215, 0.26373464, -0.48176405, 0.3577192, 0.30109936, 0.18007952, 0.97340673, 0.8311445, -0.091018654, -0.43556908, -0.47817314, 0.24427673, 0.86847204, -0.63367134, -0.1392084, 0.20880738, 0.29605484, 0.5102095, 0.0539689, 0.025343515, 0.24565774, 0.20760463, -0.14849266, 0.07748646, -1.0975155, -0.2468316, 0.049564585, -0.81448174, 0.07844066, -0.5533479, -0.12086342, 0.34281364, -0.47970983, 0.012860723, -0.20691025, -0.09066814, -0.6537314, 0.488608, 0.72847027, 0.43217465, -0.3573188, -0.2835165, -0.7994006, -0.60978246, 0.6759259, -0.74162185, 0.021587722, 0.2148367, -0.31782195, 0.15477072, 0.073249355, -0.2504549, 0.9304441, -0.109614864, -0.39431396, -0.13444294, 0.113385625, -0.17943051, -0.13110475, -0.6351985, 0.8168083, 0.7287063, 0.046382003, 0.78491753, 0.12041721, -0.44125587, 0.65859365, 0.1417125, -0.62944174, -0.8578431, 0.5297364, 0.5970799, 0.32134923, -0.6988253, -0.3988505, -0.53683966, -0.5645854, -0.26411146, -0.54879487, -0.08550332, 0.5523895, 0.09527285, -1.4829303, 0.42620313, -0.32207206, -0.80331665, -0.14081834, 0.14321318, 1.0547477, -0.014484324, -0.3733287, -0.6547246, -0.22136927, 0.23872378, -0.114890546, 0.52663624, -0.36137518, -0.10336557, 0.84902483, 0.24802007, 0.2428974, -0.55062777, -0.898774, -0.086360104, 0.42273575, 0.01069665, 0.03268071, -0.22184242, 0.68654114, -0.31356922, 0.99203634, -0.8053663, 0.024493441, 0.52120054, -0.14788416, 0.16501157, 0.71239144, 0.10519813, -0.23112617, -0.30074418, -0.7945606, -0.32828715, 0.1546241, 0.71328896, -0.8631298, 0.6879144, -0.25349656, -0.15505737, -0.52401733, 0.026135508, -0.91197675, 0.4897887, 0.2553321, 0.38357615, -0.5817329, 0.10147074, -0.14365219, -0.07878406, 1.460639, 0.76415765, 0.44990405, 0.9951974, -0.10996676, -0.43003532, -0.6043866, -0.97104216, -0.10857196, 1.7999303, -0.2487742, -0.23330228, -1.9624965, 0.8282924, 0.3562973, 0.99590814, 0.710325, -0.74927074, -0.47313, -0.23652235, 0.17110118, -0.64118886, 0.18618682, -1.0815334, 0.4417191, -0.27619588, 0.13438608, -1.2182668, 0.09222232, -0.046028994, 0.5128414, 0.6309838, 0.17811278, 0.08257908, 0.82218415, 0.24052832, -0.3043413, -1.1845739, -0.31409425, -0.5495012, -0.102475435, 0.6949858, -0.60669345, -0.5356563, -0.12042385, 0.51972234, 0.9788067, 0.27975333, -0.6509743, 0.08709107, -0.3396774, -1.0324789, 0.21493271, 0.64101464, -0.4424937, 0.35320687, -0.8626394, 0.018576376, -0.14504273, 0.0675314, -0.09590454, 0.14231923, -0.32527098, 0.15347226, 0.50280917, -0.12097482, -0.93272054, 0.6082158, -1.5437937, -0.07995024, -0.6858374, 0.39547303, -0.5739462, -0.52489924, 0.041147597, 1.3033543, -0.17370999, -0.22331943, -0.12098679, 0.7863538, -0.6103873, -0.3908378, 1.0210451, -0.33337703, -0.335317, 0.679813, -0.03252794, -0.46655637, 0.58323187, 0.526237, -0.17061844, -0.47416002, -0.35893548, 0.4063307, 0.32042253, -0.0637602, 0.13230446, -0.44979116, 0.5168601, 0.33988982, -0.7665607, 0.0853706, -1.2825401, 0.35769534, -0.21235913, 0.25373393, 0.2737563, 0.4383112, 0.26156312, -0.18157701, -0.82445776, -0.54746836, -0.19033858, -0.14472756, -0.8237075, -0.20849845, 0.09290561, 0.45805925, -0.60196894, -0.9694583, 0.22632071, -0.15821098, -0.07559876, -0.13461533, 0.6933839, -0.32768452, 0.3443336, 0.31391212, 0.9203925, -0.36575687, -0.20933554, -0.31347826, 0.5546571, -0.016795274, -0.092404574, -0.5469727, 0.6365913, -0.43841305, -0.8389967, -0.036488578, 0.61133695, -0.3538103, 0.76916534, 0.2602567, 0.04585594, -0.20960002, -0.69782466, -0.073778585, -0.4628681, -0.31100827, -1.194452, -0.15880762, 0.61074346, 0.01697435, 0.08602919, -1.0204202, -0.1064734, -0.5719034, 0.3842537, -0.61645734, 0.005817363, -0.5069963, 0.73048353, -0.58076227, 1.1014149, -1.002687, 0.26485753, 0.001325082, 0.23775855, -0.1090179, 0.8222375, -0.8824368, -0.60530984, 0.38780227, -0.18472426, 0.18662238, 0.6539168, -0.08568022, 0.0025433525, -0.35558033, 0.019322174, -0.88901633, -0.6802375, -0.69873244, 0.29876226, 0.03279008, 0.41753015, 0.15544944, 0.136213, 1.1869895, 0.13588208, -0.24654882, -0.68050987, -0.6760854, -0.6779837, -0.68511623, 0.96097136, -0.5064433, 0.005498264, -0.47417802, 0.14546248, 0.7594362, -0.367512, -0.098296344, 1.961263, 0.35767633, 0.03230954, -0.69004714, 1.1331533, 0.27895185, -0.49140096, -0.07016089, 0.16740261, -0.34845498, 0.25857598, -0.37114236, -0.92653924, -0.78350365, -0.41225216, 0.69445866, 0.34486955, 0.093205795, -0.066756755, -0.64549917, -1.1127244, 0.37053987, 1.1387469, -0.23592287, 0.80528295, 0.63944227, 0.54414797, 1.0815576, -0.5668222, 0.089382716, 0.13776606, 0.9200868, 0.8992326, -0.27931058, 0.48805022, 0.82883877, -1.7794003, -1.3662231, -0.16744435, 0.084341876, -0.107593, -1.017171, -0.3791846, -0.14377698, -0.27979684, 0.51328593, 0.26247755, -0.27690327, 0.076862276, 0.0780327, -0.07342488, -0.061520025, 0.0024008472, 0.8332128, -0.6966219, 0.4901986, -0.24039306, -0.14298935, -0.24950793, 0.12527625, 0.29839414, 0.7389395, 0.15047178, 0.58706343, 0.12560952, 1.0310695, -0.5962883, -0.18943071, 0.6150714, -1.2840291, -1.3595079, -0.15191634, -0.25942472, -0.17627351, 0.3720213, -0.10289232, 0.056950808, 0.3213657, 0.3321522, 0.053539947, -1.0371126, -0.052774735, -0.87331986, -0.7267541, 0.051209338, 0.1441378, 0.31906247, 0.46871975, 0.18395185, -0.0692848, -0.42856544, 0.01773473, -0.1260064, 0.71401536, -0.27404174, 1.3056145, -0.61608034, -0.3932829, -0.24632904, 0.010613654, -0.21523128, -0.08095754, -0.4983497, -0.626685, 0.64032483, 1.0719864, -0.35518745, 0.31677714, -0.09860298, -0.29361737, 0.98726356, -0.28703505, 0.37888417, 0.2140752, 0.36996755, -0.71319747, 0.2214708, -0.3875488, 0.37793255, -0.7721462, 0.6461019, 0.6115026, -0.5304169, -0.17443098, -0.70448905, -0.021181267, -1.0428503, -0.34047216, -0.06293756, 0.17875059, 0.28179625, 0.44505474, 0.16711755, 0.6964868, 0.2429418, -0.048931554, 0.101600535, 0.29270682, 0.14754868, 0.040776677, -0.2830106, 0.24993977, 0.18217126, 0.5031197, 0.6458861, 0.08088947, -0.06821887, 0.2294434, -0.6025328, 0.4214955, 0.02959657, 0.31607035, 0.048564933, 0.36561626, 0.4328048, -1.0279614, 0.5526877, -0.3101868, -0.7041938, 1.2670145, -1.0038794, -0.7538339, -0.051289015, -0.99725854, 0.54648906, -0.11038782, -0.8033994, 0.31729695, 0.11359299, -0.5800839, -0.29594612, 0.130738, 0.6961497, -0.31145877, -0.6745281, -0.3327659, 0.3130085, 0.12843235, 0.3653333, -0.8100079, -0.22264737, 0.5917342, 0.86295915, 0.3166489, 0.16683327, -0.26316214, -0.8232067, 0.5095601, 0.20595878, 0.45409048, -0.8229478, 0.10812789, -0.47012043, 0.8713862, -0.64504915, -0.24139825, 0.0829124, 0.30529198, -0.04502464, 1.3450638, 0.87469786, 0.1282358, 0.21878737, 0.5608324, -0.023736248, 0.8814906, -0.2450681, -0.64366734, 0.987674, 0.47663254, 0.72472185, 0.20790745, 0.4268311, 0.3406033, -0.40542594, -0.44307786, 0.21143325, 1.1998398, -0.04269371, 0.032475434, -0.028270632, -0.28937843, 0.63828766, -0.4257946, 0.30673802, -0.20225716, -0.8918963, -1.081641, -0.446235, 1.3505905, 0.28334346, -0.113350704, 0.10584864, 0.13026781, 0.9782037, 1.2069069, -0.59382397, 0.13534994, 0.20910484, 0.3964433, -0.08584341, -0.18862218, 0.29279798, 0.10304643, -1.0189443, -0.48712122, 0.089892246, 0.40033635, -0.43739498, -0.09577835, -0.8914217, 0.5634942, 0.46147624, 0.18333669, 0.5018127, -0.57141834, 0.22123447, -0.984082, 0.73240864, -0.42637298, 0.14858729, 0.58898765, -0.41788393, 0.15860158, 0.5590106, 0.5476727, 0.38015527, -0.06930857, 0.63783866, 0.19000062, 0.5320519, 0.85254997, -0.25869924, 0.36578634, 0.059271112, -0.82330275, -0.10596946, 0.32942462, -1.0458459, 0.47975013, -0.9814856, -0.54931, 0.12817167, 0.4720524, -0.60098046, -0.5558935, -0.07903196, 0.08017051, -1.0334187, 0.72646886, 0.28693724, 0.6514715, 0.017122403, 0.059414208, -0.43003318, 0.61294556, 0.15250102, -0.6344637, -0.124711365, -0.40405872, -0.21501787, -0.5084465, -0.6109873, -0.29131338, 0.21077976, 0.4723583, -0.6350576, -0.42727095, 0.3745004, 0.2436617, 0.16013308, -0.266916, 0.41006523, -0.13443582, 1.4617592, -0.09403017, 1.6679444, -0.113599226, -0.1766919, 1.1128019, -0.4637022, 0.6026775, 0.3295456, -0.26246035, -0.58322674, 0.63749, -0.29790995, -0.4552287, -0.34962073, 0.4757661, -0.38596824, 0.40881908, -1.6522696, -0.56499016, -0.9354418, -1.0565773, -0.9105244, 1.0067492, 0.12771598, -0.004504431, 0.23984769, -0.66904426, 3.6624045, 0.2592154, 0.27187067, 0.5508017, -0.10568046, -0.2670927, 0.5288961, -0.6268612, 0.20718782, -0.9910453, 0.4760573, 0.0844937, 0.11704531, 0.7277677, 0.06835682, 0.9558804, -1.4853053, -2.8017908E-4, 0.11895311, -0.11955248, -1.2167906, 0.5527989, 0.5219648, 0.25548583, 0.5149375, 0.123984054, 1.0438063, -1.0745394, -0.09779909, -0.5746613, 1.2606201, 0.4869489, 0.02342626, -0.30612367, -0.4081654, 0.54757965, 0.18535367, 0.089302, 0.14784724, 0.33126256, -0.024330921, -0.46541923, 0.44284585, 0.052763782, 0.093688585, 0.49122953, -0.9165186, 0.34113777, 0.31382066, -0.054380115, 0.8466793, -0.28731346, 0.28629318, -0.57786727, -0.5250714, -0.15221663, 0.029823096, 0.40237293, -0.7914292, 0.24210334, -0.42463204, 0.25620586, -0.21277969, -0.050531507, -0.18733416, 0.16404244, 0.696484, 0.25563902, -0.18624108, -0.8773365, -0.56324744, 0.31544864, -0.31330204, -0.8109294, -0.13510668, 0.9721738, -1.0318075, 0.26569387, 0.038234264, -0.31428084, 0.22263722, 0.06329511, -0.15759473, -0.36926627, 0.17948699, 0.5136905, 0.01984401, -0.19416128, -0.38064262, -0.37309346, 1.102059, 0.7792553, 0.060157903, -0.108390525, 0.11017364, 0.3994228, 0.09555158, 0.5825012, -0.60580367, -1.0827808, -0.1576766, 0.7572717, 0.51690817, 0.76832026, 0.5623794, -0.5242806, 0.10713714, -0.28198227, -0.3057894, -0.4436093, 0.0508234, -0.67036074, -0.50983393, -1.126107, 0.10048007, -0.28169256, 0.06555464, -1.1903594, -0.55183387, -0.4405081, -0.17009944, 0.5612562, 0.047636222, 0.37082034, 0.65144277, -0.21440561, 0.19920659, -0.08983047, -1.3184719, -0.21471508, -0.77892214, 1.0248505, -0.60647166, -0.48059314, -0.38415653, 0.33976716, 0.0074042156, 0.3431964, -0.7637138, -1.562081, 0.21412212, 0.41796106, -0.21860333, -0.036963142, -0.15398574, -0.067759186, 0.6621827, 0.14345872, -0.10131864, -0.15699252, 0.3062003, -0.93177044, 0.110051446, -1.2522842, 0.80647933, 0.19306532, 0.93869627, 0.41989905, -1.2128512, 0.048087396, 0.43417054, 0.51452124, 0.22957322, 0.6538078, 0.045719445, -0.49581295, 0.6129913, 0.2330572, -0.76418656, -0.59514874, 0.10234557, 0.34008834, 0.93430877, -0.7938407, 0.3488256, -0.095158495, 0.39193368, 0.32834923, -0.1460364, -1.1935029, -0.7402658, -0.06672922, 0.34790787, -0.24937785, -0.09675882, 0.54674053, 0.29830703, -0.25361973, 0.26495603, 0.8386657, 0.93270355, -0.30766344, 0.10872549, -0.54271966, -0.2646044, 0.80850345, 0.80533385, -0.3436443, -0.15843843, -1.1156524, -0.37078837, -0.9744277, 0.38333637, -0.7051673, -0.4906921, 0.054198608, 1.0482272, -0.16283801, 0.28291935, -0.2076324, 0.24571949, -0.42660946, 0.6194447, -0.5943218, -0.2044191, 0.80598855, 0.033541154, -0.16847873, -0.4267447, -0.5693771, -0.32211003, -0.80143666, 0.52846223, 0.42857355, -0.2879928, 0.25050047, 0.05486901, -0.059970193, 1.0365646, -0.21031526, -0.2751096, 0.4085902, 0.5967447, 0.46310297, -1.244204, 0.2939693, -0.06727497, -0.65307546, 1.6378098, 0.6602727, 0.3331953, -0.5972358, -0.16830699, -0.4092154, 0.9061645, -0.70522636, -0.30478314, 0.21947536, 0.30807325, -0.5290096, -0.021191731, -0.048273534, 0.052654807, 0.4325883, -0.002106417, 0.22604083, 0.6506453, -0.4128863, 0.06486968, -0.5109035, 0.6262629, -0.59054273, 0.54796576, -0.078081556, -0.22457956, 0.10496932, -0.7126875, -0.07178986, -0.014613241, 0.25202245, 0.6094514, 0.7096744, 0.17859364, -0.07159945, -0.10782984, -1.0702442, 0.2905703, -0.06708715, 0.73710424, 0.025326883, -0.04851279, 0.2838625, 0.100776896, -0.47360796, -0.23008478, 0.7629225, 0.4038585, -1.1927986, 0.7186655, 0.17397834, 0.66196936, -0.3637218, 1.0107775, -0.55020744, -1.4909959, -0.56990623, 0.30201685, -0.20511222, 0.2730165, 0.73218584, 0.048040986, -0.044010743, -0.15303451, -0.17348513, -0.39569393, 0.6480931, 0.10182218, -0.5377528, -0.012679113, -0.007665368, -0.65783006, -0.6718512, 0.36023977, 0.50482917, 0.112826176, -0.16764028, 0.09783888, 0.54286546, 0.82194656, 0.32949015, -0.10446587, -0.66156757, 0.44045573, -0.6881772, -0.12748857, 0.011206888, 0.5880827, -0.3310844, 0.60313576, 0.24298477, 0.18763687, 0.6665168, 0.8176408, 0.63851047, 0.7703525, -0.38874447, 0.29319334, 0.21659724, 0.67248577, -0.04747004, -0.75138336, -0.032682426, -0.58525085, 0.6164005, 0.5252805, 0.067715034, 0.77593464, 0.5756692, 0.01080169, -0.5409408, -0.18088111, 0.28055167, 0.7370628, -0.061915897, -0.14930114, 0.42736712, 0.07878585, 0.6338375, 0.028980128, -0.018971909, 0.24936385, -0.10556009, -0.007052973, -0.08535256, -1.1767282, -0.25823215, -0.16164792, -0.59529424, -0.04154039, -0.43678924, 0.16663226, 0.3614608, -0.4110936, -0.12785242, -0.561177, -0.49575725, -0.53649414, 0.55716574, 0.9938018, 0.3834205, -0.4088232, -0.16438262, -0.8488413, -0.68160176, 0.48920587, -0.35171676, 0.17286812, 0.14482836, -0.4438081, 0.34934083, -0.11522612, -0.18400648, 0.9550849, 0.19140965, -0.25227302, 0.060297303, -0.0070842654, -0.15262157, -0.484868, -0.6926102, 0.84828264, 0.91567695, 0.0016165003, 0.6874639, 0.023342803, -0.5647343, 0.4872593, 0.36987463, -0.53967863, -0.7367035, 0.6690624, 0.36760825, 0.41536736, -0.70216143, -0.78941077, -0.46292698, -0.32272416, 0.00408322, -0.569716, -0.0982589, 0.7778945, -0.22264656, -1.2859204, 0.14981261, -0.4571321, -0.84205663, -0.3931107, -0.13485941, 0.7186496, -0.11406441, -0.19351138, -0.3396683, -0.12722772, 0.0022645625, -0.023715228, 0.7800383, -0.23587298, 0.32181016, 0.6075423, 0.20606756, 0.08583229, -0.3835686, -0.76363343, 0.11516355, 0.26286107, 0.15805645, 0.010979824, -0.28352818, 0.42406383, -0.06747039, 0.7641131, -0.8182565, -0.031834044, 0.59817415, -0.556535, -0.13097134, 0.45006514, 0.45921433, 0.18680452, -0.2353987, -0.39224648, -0.20950153, 0.44744873, 0.7575571, -0.99211806, 1.0048358, -0.21880436, -0.29180026, -0.4883183, 0.11914819, -0.45420957, 0.5537008, 0.038552634, 0.28215736, -0.6505611, -0.05639731, -0.22432365, -0.0753257, 1.534879, 0.6527801, 0.33230194, 0.5043558, -0.17230092, -0.5368485, -0.60196584, -0.972783, -0.35474154, 1.5653621, 0.13357976, -0.23607488, -1.9256357, 0.99502707, 0.56387746, 0.95426637, 0.44848073, -0.6578555, -0.5840174, -0.21664485, -0.06438644, -0.6586791, 0.713435, -0.7542643, 0.4121706, -0.47967133, -0.5214753, -0.86162406, -0.41749653, 0.16635127, 0.67231923, 0.63377875, 0.060160317, -0.16357699, 0.70590246, 0.24508043, -0.31862876, -1.0028367, -0.1415234, -0.4981313, -0.07634404, 0.5626511, -0.5439674, -0.41470236, -0.32987338, 0.38528684, 0.8707138, 0.61265385, -0.7561777, -0.058350243, -0.29060918, -0.8828205, -0.32191333, 0.7171919, -0.6715127, 0.25353637, -0.85777193, -0.22826701, -0.10268143, -0.3677761, -0.21263666, 0.39470083, -0.50553197, 0.104695916, 0.38097295, 0.37870398, -0.7951013, 0.5898909, -1.4096434, 0.18723375, -0.67144465, 0.08446455, -0.32043055, -0.21069425, 0.060452625, 0.89954424, -0.33245453, 0.060212478, -0.16919714, 0.51581824, -0.46913767, -0.43260145, 0.8914732, -0.17595634, -0.39337397, 0.5862695, -0.165371, -0.41703492, 0.2300126, 0.8531972, 6.863475E-4, 0.018732369, -0.19274993, 0.11807219, 0.16294602, -0.13752386, 0.17776681, -0.7283606, 0.5255629, 0.21245965, -0.61398387, -0.019701332, -1.1922736, 0.072056726, -0.15926456, 0.06668207, 0.6565079, 0.3800544, 0.2927567, -0.18829279, -0.47632927, -0.5828585, -0.2932791, -0.32696068, -0.44982386, -0.1601027, 0.23962039, 0.35986, -0.6936998, -0.4130165, -0.028386503, 0.1189172, -0.23614475, -0.13688965, 0.8730439, -0.3260798, 0.6230809, -0.009794818, 0.64238536, -0.30446264, -0.1213474, -0.21677762, 0.64032716, -0.09058951, 0.32761735, -0.8952577, 0.7286184, -0.28435072, -1.0795968, 0.07461093, 0.5260262, 0.081124514, 1.1400597, 0.20557263, -0.22531477, -0.013032559, -0.63784456, -0.25429648, -0.43621144, -0.25980812, -0.68846905, 0.018888742, 0.40777546, 0.31415194, -0.06978384, -0.83367103, -0.47623697, -0.50554305, 0.050676435, -0.54136133, 0.09123197, -0.46119207, 0.8309509, -0.9467837, 1.3522601, -0.56323236, 0.04193849, -0.083614424, 0.65520114, -0.07264876, 1.2610217, -0.6354654, -0.54056776, 0.70698595, 0.00911441, 0.20147234, 0.8186352, -0.38808322, -0.081993535, -0.18767877, 0.27850354, -0.8085504, -0.6826043, -0.70434916, 0.28125268, -0.00417158, 0.1764245, 0.1252622, 0.13679127, 1.1405021, -0.16482627, -0.04663332, -0.58190393, -0.45656186, -0.49414352, -0.6545142, 0.7316151, -0.75474155, -0.13049766, -0.78929186, -0.1713476, 0.68869865, -0.1354918, -0.12297894, 1.374426, 0.53188884, -0.19543867, -0.7560643, 0.7825549, -0.20464867, -0.6691693, -0.024741076, 0.15538393, -0.20939259, 0.09335803, -0.32170793, -0.9581545, -0.3086296, -0.45974192, 0.9343871, 0.28155223, 0.026325535, 0.3607343, -0.51085424, -0.68860966, 0.51546973, 0.9578018, -0.32939222, 0.88570464, 0.8727469, 0.282832, 1.3196431, -0.46789652, 0.18751012, -0.009741772, 0.7062707, 0.7235945, -0.44040543, 0.32659394, 0.82885027, -1.513391, -1.0347612, -0.31969503, -0.17150323, -0.31322023, -1.0168256, -0.39043573, -0.32385135, -0.62966126, 0.4967361, 0.14318325, -0.02364469, -0.18822855, 0.36839056, 0.31844568, -0.25449395, 0.2378134, 1.1323748, -0.57734036, 0.57482517, -0.25512508, -0.3082748, -0.19442557, -0.1397948, -0.37038362, 0.7746373, 0.19150639, 0.057238307, -0.5009022, 0.7646541, -0.3515749, -0.1592197, 0.671271, -1.4349705, -0.87009597, -0.58153695, -0.0132568665, -0.26201454, 0.46259606, -0.24323648, 0.4780776, 0.24452041, 0.022693053, 0.21807481, -1.0536666, -0.3690221, -0.9724109, -0.5958498, 0.2780582, 0.17680575, 0.30712324, 0.33505383, 0.24084339, 0.3497074, -0.066905096, -0.046884567, -0.19839972, 0.49531293, -0.1463247, 0.68853134, -0.57161236, -0.5265372, -0.46173963, -0.29136887, -0.09823992, -0.25131285, -0.49662158, -0.29860687, 0.4173069, 0.61001307, -0.23230451, 0.33880717, -0.38124043, -0.62723, 0.7280858, -0.41596067, 0.12235218, -0.046359077, 0.1374916, -1.0030403, 0.076998085, 0.010334268, 0.16277502, -0.75184274, -0.045661084, 0.6897451, -0.5234157, -0.20258962, -0.35811937, -0.16314638, -1.2877578, -0.29840237, 0.11212779, 0.1864383, 0.30804637, 0.47436863, 0.07938605, 0.23727947, 0.15619943, 0.15607107, 0.3661412, 0.19492516, 0.52977335, 0.14330177, -0.39681092, 0.1595948, -0.17317334, 0.92330325, 0.95668155, 0.16457509, -0.082535796, 0.33720917, -0.6979915, -0.18996246, -0.18736917, 0.0076782946, 0.04778067, 0.4375449, 0.4449576, -0.5646165, 0.4824912, -0.73924667, -0.41778222, 1.228386, -1.4113506, -0.5091015, 0.018879347, -1.0306215, 0.3441526, -0.29703033, -0.76199734, 0.48998946, 0.0538232, -0.6444448, -0.55421084, 0.46473855, 0.41143027, 0.023548841, -0.5623564, -0.15067895, 0.5425395, 0.02348781, 0.33763394, -0.99986434, -0.40732938, 0.64412487, 0.61347324, 0.1844104, 0.060828157, 0.19362581, -0.89388067, 0.44956368, 0.61369896, 0.52955574, -0.93781817, 0.3274699, -0.2934738, 0.886754, -0.7060228, -0.09946883, 0.28589666, 0.38918224, 0.019775577, 0.8416462, 0.60078466, 0.22841358, 0.7777619, 0.048576668, 0.12920377, 0.708591, -0.17719474, -0.62505966, 1.0092452, 0.61805975, 0.53742653, 0.11385523, 0.30024686, 0.50781274, -0.65055555, -0.3315245, 0.089441545, 0.6801583, -0.055591352, 0.5085515, 0.080202654, -0.6231575, 0.7095781, -0.09222566, -0.0023482144, -0.2301088, -0.78504163, -0.89850014, -0.61895406, 1.4755174, 0.44006103, 0.3736515, 0.2789185, 0.3126807, 1.0981504, 0.5982582, -0.5319362, 0.2933641, 0.59055275, 0.449096, 0.09719907, 0.23644274, 0.4262668, 0.19561322, -0.99225354, -0.27452955, 0.0054776296, 0.42809853, -0.3454189, 0.024061855, -0.7582559, 0.4612135, 0.5061168, 0.16127184, 0.2933835, -0.74961704, -0.08755819, -1.038512, 0.52964205, -0.6356245, -0.039177597, 0.8408139, -0.43552092, -0.22568429, 0.6004227, 0.5666311, 0.34723854, 0.17451535, 0.46295786, 0.57787806, 0.5428326, 0.93625444, 0.25844303, 0.71137315, -0.17457405, -0.9393191, -0.0062135123, 0.7324282, -0.8502125, 0.21925573, -0.6307975, -0.40189654, 0.27061498, 0.65880245, -0.59898424, -0.7496212, 0.03331019, 0.19341184, -0.50549847, 0.76212996, 0.35790926, 0.7870286, -0.0400087, 0.055058934, -0.5947467, 0.26547173, 0.13392746, -1.1119648, -0.17382655, -0.5744398, 0.111572, -0.59631276, -0.62594944, -0.097791016, -0.35199642, 0.2313174, -0.58278424, -0.08641501, 0.34744838, 0.34512728, 0.500954, -0.7685111, 0.46870387, -0.10193086, 1.6084917, -0.03636925, 1.4086537, -0.063865475, -0.0015128739, 0.92001283, -0.38939625, 0.45528454, 0.31051323, 0.1577892, -0.5681765, 0.7005183, -0.5051335, -0.34040785, -0.28615594, 0.8032139, -0.46363586, 0.21622391, -1.2667955, -0.29988098, -0.81864244, -0.8201505, -1.1678752, 0.75056106, 0.098227546, -0.010810759, -0.014191384, -0.42939845, 3.9035187, 0.15681595, 0.2582419, 0.4887771, 0.1525703, -0.02428957, 0.66500604, -0.5359085, 0.22960104, -0.7852579, 0.15039048, 0.06367845, 0.3528753, 0.9337709, -0.20073745, 1.0146337, -1.0692636, -0.24778748, 0.23142752, -0.14437445, -1.2041767, 0.28693214, 0.37165838, -0.035585634, 0.52149665, -0.11201562, 0.60554165, -1.043031, 0.06837402, -0.4101506, 0.8253852, 0.12620798, 0.22745697, -0.13505921, -0.45202237, 1.1835434, 0.25073954, 0.1395775, 0.10847205, 0.25401965, -0.37892976, -0.6354462, 0.36379182, 0.1980045, 0.09259137, 0.7982754, -1.1515712, -0.24035174, 0.6636571, -0.15318638, 0.58441776, -0.48915377, 0.5170015, -0.2060879, -0.7129818, -0.1414245, -0.43068886, 0.18446523, -0.9598793, -0.2197116, -0.19919111, 0.12266955, -0.10918245, 0.35740358, -0.3485523, -0.22071102, 0.5921739, 0.5802294, -0.22553721, -0.7331374, -0.5409138, 0.4591624, -0.25060326, -0.6027513, 0.1528463, 1.0014454, -0.9771162, 0.30428672, -0.31012374, -0.36872467, -0.45164657, 0.3022587, -0.3332075, -0.05958897, 0.5864512, 0.29134268, -0.2936555, 0.14974032, -0.21069044, -0.21046856, 1.0327365, 0.87497103, -0.29114136, -0.12409274, 0.30638078, -0.008108355, -0.074863106, 0.1823267, -0.92456347, -1.2252402, 0.023988292, 0.29588172, 0.28956586, 0.92870545, 0.6245167, -0.17748761, 0.49881747, -0.0013700202, -0.6062493, -0.5211433, -0.044155214, -0.58735853, -0.3184926, -1.1066936, 0.31925192, 0.055742487, -0.11290029, -1.2357664, -0.013144705, -0.5662862, 0.06639056, 0.35374135, 0.38557136, 0.20628467, 0.5110246, -0.42163143, 0.12925106, -0.24695382, -1.1608903, -0.15010446, -0.3606254, 1.2112582, -0.5199689, -0.24509984, -0.57505196, 0.06266602, -0.05476774, 0.5543311, -0.6631306, -0.90839344, 0.056663997, 0.39264026, 0.006514296, -0.03379453, -0.06360012, 0.2962194, 0.43456346, 0.29512823, 0.15175281, 0.034137387, -0.15923557, -0.86211294, 0.07326408, -0.80600816, 0.67977273, 0.49671376, 0.6821382, 0.27394387, -1.536363, 0.57825166, 0.7842151, 0.2394658, 0.09236379, 0.6696022, 0.22107342, -0.5844541, 0.68800783, 0.35063517, -0.7489135, -0.84657335, 0.13539974, 0.011126772, 0.83486915, -0.3726464, 0.38500214, 0.15931323, 0.24204169, 0.31334576, -0.38999516, -1.0564649, -0.8066621, 0.32243422, 0.08050046, -0.100161314, 0.1417718, 0.26810834, 0.27799317, -0.24338469, -0.1273042, 0.47630495, 0.761901, -0.31447634, 0.0041330475, -0.6132874, -0.35413107, 0.50921535, 0.92908055, -0.7377505, 0.17884433, -0.97206813, -0.31223825, -1.1257086, 0.054560035, -0.5985438, -0.5419079, 0.34310243, 1.1592656, 0.12414108, 0.6306039, -0.29405472, 0.36001867, -0.26069996, 0.6843612, -0.69717747, -0.25637287, 0.7413816, -0.09426433, 0.007948817, -0.05839423, -0.37699413, -0.54838955, -0.5196219, 0.7450251, 0.5604553, -0.19528422, 0.153679, -0.037510846, 0.21829069, 0.63829726, -0.11303048, 0.0413495, 0.42149734, 0.5452131, 0.12912615, -0.9724758, 0.47631884, -0.11178413, -0.78062665, 1.6786276, 0.88644165, 0.25348303, -0.57685983, -0.10731165, -0.6602384, 0.66389215, -0.7689, 0.1496639, 0.6415253, 0.500464, -0.24878055, -0.07939838, 0.13462633, 0.013040431, 0.73763734, 0.06980479, -0.18928413, 0.6980672, -0.33711007, 0.115530476, -0.61564434, 0.2487322, -0.04897301, 0.13430814, -0.2164018, -0.3666767, -0.095899746, -0.44386792, -0.17055167, -0.036105186, 0.43075958, 0.534845, 0.17878997, 0.06367618, -0.05834858, -0.2430348, -0.6089918, -0.047322188, 0.080885276, 0.5262991, -0.21075973, 0.10692868, 0.13799505, 0.08237328, -0.60258526, -0.51029414, 0.716713, 0.27913976, -1.1312143, 0.69941586, 0.08650997, 0.6624551, -0.70263344, 1.0370399, -0.4800526, -1.3264769, -0.5724056, 0.48490354, -0.36758322, 0.14180458, 1.0191479, -0.16142865, -0.15934804, -0.06126994, -0.12419982, -0.2052495, 0.46710333, 0.25446153, -0.09749228, 0.2416552, 0.13107337, -0.62425584, -0.4665196, 0.41823313, 0.017742202, -0.11604845, -0.014583001, -0.04743681, 0.48962507, 0.5726147, -0.15344103, -0.043124318, -0.4611046, 0.5476682, -0.6814534, -0.13700399, -0.25768772, 0.47459337, -0.5468129, 0.964742, 0.26113805, 0.29224998, 0.69866586, 0.5390306, 0.23548684, 0.5616739, -0.4996161, -0.0531639, 0.15483534, 0.3004987, -0.15385841, -0.6523655, 0.52095807, -0.61126125, 0.29399925, 0.022592522, 0.0036164224, 0.9010767, 0.66380125, 0.22740883, -0.8602492, 0.067954, 0.3547017, 0.4408105, -0.13458662, -0.23914078, 0.20854351, 0.24268481, 0.46751034, 0.36705163, 0.043406673, 0.036361203, 0.05552602, -0.071449906, 0.041502196, -1.2105745, -0.028304726, -0.039797705, -0.66858214, -0.088372126, -0.5237669, 0.16090764, -0.04407379, -0.6910071, 0.054006502, -0.28989974, -0.24306267, -0.61034966, 0.5553436, 0.6809772, 0.096716136, -0.51710796, -0.098939195, -0.3180539, -0.32514825, 0.38779578, -0.7734561, 0.15372227, 0.087640285, -0.4327031, 0.096745, -0.06493625, 0.029305357, 1.0426801, 0.116323724, -0.46691078, 0.011199217, 0.1469512, -0.108034305, -0.24094029, -1.0067587, 0.86667746, 0.681321, -0.34006357, 0.6885098, 0.21300186, -0.55701715, 0.582534, 0.26671684, -0.28656054, -0.7581177, 0.83850646, 0.6659291, 0.63540286, -0.82415324, -0.76791, -0.42685413, -0.1978186, 0.1188646, -0.35998422, -0.4153101, 0.63527155, 0.012389898, -1.5216818, 0.10454872, -0.15033387, -1.1138442, -0.363461, -0.31349632, 0.73108214, -0.13952224, -0.29330423, -0.40340406, 0.19570658, -0.13253699, -0.15259932, 0.8772184, -0.6289534, 0.24124396, 0.8863129, 0.013752261, 0.11636713, -0.2878188, -0.6748302, 0.26673093, 0.074429825, 0.18423261, 0.33583167, -0.31168482, 0.18303514, -0.110326886, 1.0521882, -0.8914687, -0.041218713, 0.7925176, -0.38259062, 0.0699002, 0.39020306, 0.3406126, -0.025504138, 0.030163972, -0.8205811, 0.27958557, 0.42331424, 0.7152617, -0.5693195, 0.79709387, -0.052060973, -0.2502512, -0.5891158, 0.43469584, -0.41373527, 0.6146908, 0.076879665, 0.31544682, -0.5227765, 0.08362824, -0.23998299, -0.06326865, 0.977748, 0.699623, 0.34662923, 0.4053547, -0.57229793, -0.360397, -0.68081236, -0.89546853, -0.38550287, 1.4982802, 0.1295377, 0.03139779, -1.4845395, 0.6942864, 0.52807, 0.8333225, 0.49081743, -0.3854397, -0.5561076, -0.2873355, 0.35955435, -0.40604037, 0.3067069, -0.9793556, 0.54424125, 0.05487563, -0.17266905, -1.1705602, 0.23105747, -0.096690014, 0.66326594, 0.50486475, -0.104512066, -0.17203951, 0.84721786, 0.010612169, -0.2766949, -0.7051157, -0.4017008, -0.63575864, 0.06809341, 0.36169913, -0.83321065, -0.3977779, -0.75799507, 0.45688114, 0.8228988, 0.3614043, -0.3872057, -0.23848563, -0.2693749, -0.90534234, 0.062407956, 0.79575527, -0.28577504, 0.11576642, -0.85940045, -0.2364341, 0.09936187, -0.6178453, -0.2623395, 0.4881133, -0.96528625, -0.002703242, 0.32168373, 0.23600036, -0.5019947, 0.62138635, -1.4865868, -0.15790486, -0.6669983, 0.06801675, -0.5628619, -0.31371945, 0.6114257, 0.96458405, -0.064005196, -0.219717, -0.09132044, 0.547687, -0.633611, -0.21194346, 0.5262808, -0.2213456, -0.47458994, 0.39729577, -0.15099177, -0.43005282, 0.53780806, 0.54377115, -0.124503836, -0.3869376, -0.4276981, -0.017099984, 0.10659635, 0.023432303, -0.023488503, -0.5943924, 0.44783092, 0.21988973, -0.2587016, 0.054121852, -0.98205125, 0.66049236, -0.1100941, 0.40253222, 0.4989391, 0.18264665, 0.024417441, -0.1577205, -0.33052993, -0.40380287, -0.3190465, -0.432463, -0.36828405, -0.5821203, -0.027871974, 0.3407156, -1.0126361, -0.44199046, -0.089746, 0.19934487, 0.24793631, 0.07480049, 0.3483074, -0.468999, 0.49423718, -0.024303712, 0.7697083, -0.5001096, 0.02921876, -0.2797136, 0.5004291, -0.19378904, 0.33850992, -0.5845366, 0.54080933, -0.4231968, -0.8276037, -0.21587685, 0.4471876, 0.17945103, 0.8905926, 0.45168063, 0.120928615, -0.19128208, -0.9465436, -0.4261623, -0.56029624, -0.15703607, -0.70728654, -0.37483913, 0.49776262, 0.25170207, 0.12126787, -1.2433228, 0.06759076, -0.42357254, 0.37723503, -0.37966526, 0.16530818, -0.6875407, 0.6304193, -1.0195813, 1.1075277, -0.78990626, 0.39701256, 0.0069374703, 0.7567582, -0.09521173, 0.67897403, -0.46449107, -0.7232551, 0.6319999, 0.13682938, 0.38638604, 0.4707066, -0.36580908, 0.2677807, 0.34033567, -0.1596111, -0.9749413, -0.37226206, -0.6223806, 0.2617854, 0.103502214, -0.008744709, 0.051227644, 0.351737, 1.1481045, 0.14042997, -0.5311719, -0.49255943, -0.8199234, -0.64042944, -0.21486312, 0.6096419, -0.52185607, -0.2824444, -0.79940456, 0.1712943, 0.4599559, -0.08197235, 0.35854346, 1.6623292, 0.45101458, -0.066510625, -1.0427458, 0.62489176, -0.22252423, -0.5163516, 0.07532082, 0.13290837, 0.13375865, -0.16612516, -0.15780056, -0.94008225, -0.29751578, -0.57456505, 1.1763555, -0.05414252, 0.37103045, 0.19796538, -0.43615937, -0.68003327, 0.3122042, 1.2015585, -0.24554463, 0.8153871, 0.7607808, 0.059229776, 1.3229659, -0.24295142, 0.17053288, 0.048269182, 0.9410707, 0.9070906, 0.06965003, 0.27366185, 0.8945579, -1.2575924, -1.2471954, -0.5133816, -0.03719949, -0.040453598, -0.6262046, -0.22496824, -0.5460526, -0.6761229, 0.38598374, 0.30903018, 0.3048585, 0.05681765, 1.035404, 0.3265798, -0.65159935, 0.012538631, 1.1262999, -0.5801894, 0.6140626, 0.030489383, -0.20633727, -0.091095164, 0.07008093, 0.20600188, 0.42286634, 0.24940234, 0.336841, -0.28344682, 0.15419483, -0.45846593, -0.2657172, 0.30148643, -0.9636932, -0.83163893, -0.15322179, -0.083657995, -0.24991873, 0.2650725, -0.21684909, 0.45393792, 0.2698332, 0.0074559078, 0.4958383, -0.61557376, -0.25072846, -1.2557454, -0.6115327, -0.24550119, -0.04877276, 0.06557663, 0.3164962, 0.2010736, 0.20483038, 0.098864615, 0.4129772, 0.24178419, 0.45724168, -0.4674123, 0.8200659, -0.50947297, -0.449177, -0.30873096, -0.00341261, -0.05515168, -0.5907586, -0.33790907, -0.651591, 0.40981805, 0.7774349, -0.11609654, 0.120979905, -0.17329918, -0.36349046, 0.5757807, -0.30231762, 0.16941534, 0.18787259, 0.016418763, -0.9578842, -0.080765896, -0.023937378, 0.13233513, -0.6668092, -0.18915473, 0.6900721, -0.81779176, -0.3249238, -0.19014584, -0.26334095, -0.9522248, -0.020303745, -0.1590526, 0.45100468, 0.30653527, 0.19623548, 0.3372883, 0.4808515, 0.053027716, 0.039079703, 0.063242614, 0.1595489, 0.36108032, -0.06620808, -0.37538713, 0.023618475, 0.01085633, 0.69008404, 0.27196503, -0.04092282, -0.2127317, 0.2757614, -0.30057618, 0.18570052, -0.19186738, 0.3087836, -0.25180426, 0.26582882, 0.4608781, -0.21650104, 0.2283323, -0.31646472, -0.692105, 1.3698722, -1.257715, -0.45968327, 0.08766882, -0.62902015, 0.52597046, -0.24926928, -0.85368836, 0.53539294, 0.18897045, -0.8144592, -0.24593538, 0.45442003, 0.43394864, -0.021025106, -0.56448966, -0.48068237, 0.57226974, -0.1455751, 0.3920177, -0.805578, -0.3599915, 0.36887014, 0.40636414, -0.38607797, 0.25946122, -0.5041137, -0.7237108, 0.20406774, 0.26659763, 0.50632215, -1.1882919, 0.31482235, -0.16788547, 1.0427362, -0.30384532, 0.25440946, 0.36111465, -0.04078348, -0.08545423, 0.92903745, 0.4287195, 0.38892937, 0.6466388, 0.011067346, 0.10231955, 0.72308904, -0.13572344, -0.31354204, 0.68488604, 0.4170978, 0.42884508, 0.10300704, 0.7566359, 0.17373186, -0.41658837, -0.43844083, -0.086458325, 0.52654135, -0.043467827, 0.6249003, -0.25258037, -0.729916, 0.6514588, -0.21865344, 0.05354707, -0.038330674, -1.0014257, -0.64724433, -0.36293414, 1.4632056, 0.2517041, 0.034037836, 0.24289103, 0.09087169, 0.8479298, 0.55847895, -0.71819776, 0.22156405, 0.59628755, 0.092399985, -0.04420072, -0.3075664, 0.30672166, -0.07358368, -0.9896834, -0.030702464, 0.45216998, 0.23109157, -0.3755612, 0.16779788, -0.6244628, 0.7411318, 0.24217345, 0.17737857, 0.48295784, -0.8859237, -0.24001184, -0.75387233, 0.67960876, -0.83024853, -0.14399245, 0.8452935, -0.3518325, -0.047979936, -0.02630499, 0.5509351, 0.4625635, -0.16918442, 0.30742225, 0.16386184, 0.67220664, 0.6280037, 0.28628358, 0.5660928, -0.1181638, -0.7434205, 0.20981479, 0.30287597, -0.69003713, 0.2184324, -0.76819944, -0.6346251, -0.08185301, 0.4818785, -0.51540446, -0.41744098, -0.09777721, -0.13589545, -0.60600513, 0.5247147, 0.3843186, 0.7094564, -0.16184524, -0.10725272, -0.4548275, 0.19113028, -0.047529392, -1.2795435, 0.17554286, -0.11416066, 0.13803561, -0.15642008, -0.6183412, -0.09616114, -0.37894952, 0.41909993, -0.662439, -0.114946306, 0.24334419, 0.22668067, 0.12224765, -0.63632286, 0.09084573, -0.23651299, 1.572324, 0.2178188, 1.1743072, 0.07571864, -0.1768858, 0.46413594, -0.48011255, 0.60569423, 0.15971124, 0.15805168, -0.9414262, 0.52399147, -0.007178193, -0.5215467, -0.59056896, 0.8559839, -0.2467039, -0.12033293, -0.9019515, -0.59779, -0.7349234, -0.8292922, -0.8635217, 0.5185263, -0.14540526, -0.26934415, 0.09875953, -1.1647751, 4.1182427, 0.46481997, 0.20087855, 0.9354643, 0.105424814, -0.004540026, 0.31147802, -0.6534193, 0.49501762, -0.45092684, 0.26379517, 0.448524, 0.34865677, 0.33569512, -0.016880259, 0.931842, -1.0148392, 0.20927775, 0.27847856, 0.15899846, -1.0693281, 0.1423664, 0.25981626, -0.025161192, 0.37412122, -0.29079884, 0.65601414, -1.0225062, -0.09605144, -0.14980899, 1.4953828, -0.1718415, 0.4066242, -0.08655246, -0.24063088, 1.2393714, 0.30284256, 0.36995012, 0.13408722, 0.30496278, -0.46151608, -0.6467823, 0.6863592, 0.3977234, 0.24254265, 0.30088937, -0.91632855, 0.22041345, 0.21627867, 0.036953487, 0.8198882, -0.38644162, 0.5111023, -0.6528836, -0.05132746, -0.048061155, -0.6670724, 0.32652795, -0.93728834, 0.17837188, -0.07624923, 0.18451518, -0.23230648, 0.34793568, -0.30258647, 0.12964638, 0.51428103, 0.8286943, -0.33250588, -0.6536644, -0.5854663, 0.42078778, 0.0033747032, -1.1266797, 0.10867215, 0.7423345, -0.83774376, 0.77926403, -0.058730222, -0.47217268, -0.092801005, 0.33792138, -0.05150798, -0.31443495, 0.27053922, 0.27824974, -0.11275067, -0.09057309, -0.2926527, 0.06173639, 1.3071758, 0.4730829, -0.14173776, -0.5784081, 0.2668654, 0.23815082, 0.28242433, 0.4774975, -0.54650855, -1.0264833, -0.47225332, 0.8703695, 0.63991624, 0.74452734, 0.42014164, -0.03533741, 0.06514102, -0.09643583, -0.8522862, -1.026076, 0.2499778, -0.42779097, -0.22190364, -0.076258555, 0.44808066, -0.71214545, -0.33959672, -1.3720645, 0.32767367, -0.713407, 0.7200092, 0.54970694, 0.038314663, 0.31601653, 0.82536983, -0.3402146, -0.15020594, -0.38107064, -1.594133, -0.20284157, -0.5158298, 1.4197085, -0.8124861, -0.42961958, -0.9616828, -0.31844, 0.09133983, 0.83976585, -0.69099605, -0.7764937, -0.5044535, -0.021224841, -1.0946624, 0.061164968, -0.008315772, -0.09962118, 0.7529673, 0.13280208, 0.32369834, -0.018207334, 0.30298617, -1.3468391, -0.010767452, -1.2652732, 0.3044045, 0.6346315, 0.41673356, 0.3533945, -1.4007373, 0.73925, 0.4769547, 0.45146942, -0.17096666, 0.53908443, 0.1459171, -0.5496129, 0.8112877, 0.22813308, -0.86315006, -1.0600767, 0.49666116, 0.6343291, 0.9384711, -0.67448175, 0.65366536, 0.12925006, 0.32494718, 0.7210598, -0.119817495, -1.8780767, -1.1060218, 0.26940116, 0.8603358, -0.37159148, 0.22237892, -0.026965573, 1.4551806, -0.04102008, 0.18953791, 1.2205132, 1.3830074, -0.6203029, 0.105550446, -0.9172137, -0.2631466, 1.2078451, 1.1561841, -0.88699704, 0.33485472, -1.1039261, -0.15662864, -0.8889108, -0.021704465, -0.7190207, -0.4444397, -0.09743556, 1.0252041, 0.27867004, 0.47697592, -0.25137198, 0.8654594, -0.5946547, 1.1985759, -0.7184543, -0.37799215, 0.8081364, 0.13715135, 0.03568732, -0.6331051, -0.65091616, -0.63724107, -1.1073422, 0.83576024, 0.01433241, -0.25773996, 0.19880387, 0.26008373, 0.12768374, 1.1019219, -0.48458183, 0.046535883, -0.06099293, 0.5994473, 0.82844126, -1.4832599, 0.76427746, 0.2744197, -0.63113993, 3.4523046, 1.0266101, 0.27708215, -0.41686982, -0.5191848, -0.06873581, 1.3051794, -1.1570866, -0.13528334, 0.36869058, 1.023516, -0.06851939, -0.42901027, -0.061269097, 0.34303978, 0.78846973, -0.10224266, -0.26698807, 0.36766642, -0.052483615, 0.30429786, -0.5263308, 0.8598371, -0.22671875, 0.18051147, -0.08662229, -0.3279599, 0.2018461, -0.6478263, -0.17370462, 0.13946049, 0.68857074, 0.7604215, 0.66072303, -0.2236945, 0.0344449, 0.39498496, -0.86348784, 0.2021577, -0.554239, 1.241565, -0.19903407, 0.096936144, 0.6406258, -0.34654585, -0.73143643, -0.13212292, 0.64585644, 0.20416865, -1.3674644, 0.81159735, -0.53180194, 0.44403616, -0.4629941, 0.8237217, -0.6575767, -1.9094594, -1.0068313, 0.1886729, -0.54099613, -0.31080106, 0.52114534, -0.4064729, -0.3517636, 0.52113307, -0.37713295, -0.54287195, 0.90217155, 0.75736386, -0.057880785, 0.65335006, 0.5185984, -0.6316754, -1.008395, 0.5784696, 0.15871945, -0.096895896, 0.030775126, 0.019246973, 0.635904, 0.7580727, 0.603296, -0.39326644, -0.775648, 0.6632834, -0.76522464, -0.15057506, 0.13213232, 0.8701612, -0.051690824, 0.886158, 0.059451666, 0.39455524, 1.1942627, 0.80077326, 0.30792174, 0.72980845, -0.58946186, 0.11602919, 0.6559696, 0.8268997, -0.20558739, -0.9376819, 0.4666886, -0.6281039, 0.45548218, 0.08520936, 0.19750595, 1.5127107, 0.83545053, 0.3510535, -0.8958543, -0.75617564, 0.894642, 1.4720694, -0.1355076, -0.6986217, 0.29143137, 0.34363377, 0.18577126, 0.26836568, -0.13981187, 0.19420178, -0.1310125, 0.106808856, -0.11584908, -1.3767927, -0.048521705, -0.12314682, -0.70627797, 0.10515572, -0.5317391, 0.5002598, 0.422907, -1.0648339, -0.11869705, -0.93817717, -0.47067133, -1.0766637, 0.7890926, 1.0871282, 0.077466965, -0.022941213, -0.34052557, -0.46262902, -0.21314916, 0.63874835, -0.8034802, -0.12524417, -0.2280509, -0.45375586, 0.11442453, 0.17320183, -0.16676669, 1.2585441, -0.26324847, -1.0815029, 0.48728508, 0.40939358, -0.2852892, -0.01987523, -1.0332665, 1.4922973, 1.2905895, -0.3012445, 1.1206418, 0.58634394, -0.5885947, 1.027236, 0.5461434, -0.56589985, -2.160386, 0.9977782, 1.4122514, 0.35012767, -0.8348484, -0.91156083, -0.44733608, 0.06918893, 0.073672324, -0.49986246, -0.36920917, 1.2300003, -0.028686464, -1.9602597, 0.3586868, -0.5751905, -1.2226559, -0.160415, -0.45962837, 0.7730631, 0.15213728, -0.40129295, -0.3763386, 0.25027445, -0.017731309, -0.35444453, 1.0308242, -0.68111396, 0.027753418, 1.1759561, 0.1284143, -0.1538926, -0.06069766, -0.5967487, -0.46134785, 0.65801346, 0.38983122, -0.13866639, -0.1946084, 0.39163414, -0.05783741, 1.3692302, -1.1921241, 0.12407765, 0.62342554, -0.22950053, -0.15749526, 0.42076403, -0.15916803, -0.6903404, 0.38964617, -0.96953917, 0.1617446, 0.15616782, 0.94165206, -0.7990292, 1.0704751, -0.3479437, 0.014394938, -0.27818298, -0.2686414, -0.8608855, 1.1030215, 0.30865127, 0.56293905, -0.5808595, -0.09553954, -0.5470532, -0.24101052, 1.7932336, 0.5933583, 0.22850809, 0.6440879, -0.13777807, -0.40607083, -0.14935976, -1.0655402, -0.08556904, 1.5463837, -0.2037431, -0.049918488, -1.948359, 1.3937284, 0.8913616, 0.6618716, 0.29112825, -0.9333397, -0.64939773, -0.1519076, 0.43093035, -0.90897346, 0.23105648, -1.6697718, 0.80526376, -0.10556382, -0.29879344, -1.1856492, -0.08865876, -0.3910298, 0.99155366, 0.05003587, -0.25817716, -0.203244, 1.0919954, 0.43314368, -0.36503968, -1.4359604, -0.27645838, -0.82746905, 0.27085295, 0.6530822, -1.179947, -0.5469275, -0.8221712, 0.4316565, 0.8877416, -0.22656713, -0.9242201, -0.30603468, -0.2247964, -0.8370084, -0.35373253, 0.91914237, -0.030093975, 0.6547502, -1.4251751, -0.17141008, -0.10287389, -0.16700989, -0.17503524, 0.30245206, -0.10866988, 0.11191217, 0.87262994, -0.3063119, -0.8902056, 0.56295437, -1.9272543, -0.0981302, -0.67028433, 0.23364708, -0.6498273, -0.37664372, 0.23457718, 1.4059585, -0.1313058, -0.30622694, -0.021324791, 0.7439346, -1.2513928, -0.34206432, 1.3767378, -0.2954388, -0.5523714, 0.60395724, -0.29732507, -0.2831665, 0.24392214, 0.5988505, 0.0795792, -0.29516765, -0.25286347, 0.10891355, -0.043641455, -0.21956724, -0.1222059, -0.90728974, 0.46377242, 0.49633765, -0.20564441, -0.520319, -1.6375936, -0.0139881335, -0.4310044, 0.5800617, 0.28061712, 0.47284612, -0.07800144, -0.51974624, -0.5967198, -0.2567559, -0.40850466, -0.36360377, -0.61648047, -0.5654142, 0.48337257, 0.21692866, -1.1690227, -0.53939724, 0.2567819, 0.52827764, -0.27963173, -0.038007528, 0.5720037, -0.8600977, 0.13065897, 0.19105779, 0.9926014, -0.50321037, -0.4309987, 0.19077024, 0.7039192, -0.09141481, 0.84667844, -0.77341396, 0.5661096, 0.15038273, -1.0883207, -0.30914208, 0.39496368, -0.06485534, 1.641904, 0.6762734, -0.3347199, -0.8617406, -0.6995804, -0.19845611, -0.5784028, -0.47562283, -1.4047565, -1.0122284, 1.0451913, 0.3910407, 0.21691439, -0.5442791, 0.3343481, -0.33234861, 0.66286534, -0.6073909, -0.23710439, -0.8782153, 0.6301357, -0.78039706, 1.0811063, -0.94600165, 0.50099385, -0.20203432, 0.8153803, 0.4326697, 0.9829363, -1.1359497, -0.5724925, 0.46652472, 0.020673493, 0.17816944, 0.64396065, -0.95867497, 0.8279188, -0.80351615, -0.085244454, -1.0182021, -0.48280728, -0.68415624, 0.26940063, 0.17725682, 0.6659137, 0.343051, -0.036139507, 1.9253529, 0.330179, -0.18667798, -0.7256044, -0.5135883, -0.6487113, -0.8936575, 0.7452832, -0.12287533, -0.11825, -0.70136374, 0.14688696, 1.4273101, -0.15633577, 0.6255618, 2.1027944, 0.8671121, -0.36143222, -1.1867063, 1.1065185, 0.8098748, -0.45667458, -0.24226767, 0.0025809854, -0.25722653, 0.19070284, -0.5484266, -0.6555022, -1.0337746, -0.42591894, 1.7423811, 0.654865, 0.64011616, 0.16377617, -1.2083119, -1.4860584, 0.70743257, 1.1795193, 0.07058562, 0.8440395, 1.0345922, 0.28286603, 1.0439405, -0.31949413, 0.6272188, -0.19404978, 1.5465806, 0.8578423, -0.27853975, 0.66072625, 1.2355281, -2.0446782, -1.7492697, 0.0030216204, -0.56266546, -0.6697648, -0.68279344, -0.35443568, -0.54446316, -0.6759806, 0.1435076, 0.28134957, -0.15788919, 0.24428463, 0.014099263, 0.46920812, -0.85195917, 0.0012707915, 1.3709744, -1.0901219, 0.64788854, -0.14823869, -0.085778356, 0.13496846, -0.24483931, 0.4524359, -0.034560725, 0.63981885, 0.35658672, -0.30224392, 1.0347067, -0.85791016, -0.14240645, 0.79247826, -1.1686097, -1.586391, -0.8209819, -0.119535595, -0.2052218, 0.34335265, -0.6570797, -0.2210782, 0.6748208, -0.09502657, 0.24686556, -1.2017366, -0.63983685, -1.5916613, -1.184105, -0.123895474, -0.03346053, 0.2209342, 0.61311907, 0.3206372, -0.118494704, -0.3988993, 0.3909913, -0.36862627, 0.5302286, -0.6324911, 0.94080716, -0.6024734, -0.38162777, -0.4316226, -0.3143518, -0.36463666, -0.20017555, -0.8736055, -0.9380112, 0.45671174, 1.5155923, -0.09486201, 0.9695505, -0.13833332, -0.6298378, 0.8931586, -0.6301222, -0.26646182, 0.46902105, 0.13617973, -1.3055613, 0.30406374, -0.09564643, 0.10455055, -1.0269212, 0.12177908, 1.1355569, -0.6378392, -0.6559861, -0.78072715, -0.68091595, -1.3237638, -0.4806199, -0.16236575, 0.22558266, 0.4245454, 0.6258281, 0.2573674, 0.92344415, 0.108896874, 0.4044994, 0.06719699, 0.66419035, 0.34098536, 0.58486176, -0.41998512, 0.5359888, 0.61129946, 0.5190456, 0.983025, 0.310331, -0.32300448, 0.35044804, -0.97328913, -0.06142584, -0.34457424, 0.42320502, -0.2103809, 0.94158864, 0.751986, -0.41664547, 0.5273929, -0.023898497, -0.58526397, 0.91506046, -1.587615, -0.62792873, 0.20285669, -1.3050082, 0.62498814, -0.4249226, -1.0144218, 0.409593, 0.27104688, -0.9462727, -0.24467865, 0.86334205, 0.45995265, -0.12513909, -0.70971626, -0.19246241, 0.042387776, 0.07669194, 0.115074575, -1.269335, -0.09286548, 0.54315686, 0.34751275, 0.06670852, 0.14310578, 0.02031393, -1.4052739, 0.34125116, 0.34491134, 0.47022027, -0.80838424, 0.43571746, -0.5313221, 0.8576949, -0.2583056, -0.1817374, 0.4537858, -0.14710322, -0.4226152, 1.6146483, 0.88158476, -0.3151336, 1.2690797, 0.11899912, 0.3866578, 0.76637596, 1.5090572, -0.67779464, 0.9428768, 0.6889142, 0.6410521, 0.28004602, 0.7718466, 0.7421934, -0.28616107, -0.914406, 0.18280843, 0.77757883, -0.37666446, 0.607708, -0.28850508, -0.14639486, 1.0358485, -0.57612544, -0.03077536, -0.09469912, -0.5002359, -1.5291424, -0.5715195, 1.1232437, 0.032881796, 0.24273214, 0.114872776, 0.21159294, 0.86429787, 1.2115531, -0.53747576, 0.5324311, 1.046557, 0.3009321, 0.33693448, 0.033356756, 0.44364536, -0.02425829, -1.4809191, -0.15717486, 0.19116181, -0.09143227, -0.27159914, -0.10439899, -0.74533814, 0.82421553, -0.20139456, -0.0032766405, 0.9916576, -1.0329632, 0.19601333, -1.2602824, 0.2017543, -0.64100575, -0.35785395, 1.0780927, -0.14836146, 0.018262547, 0.9442348, 0.83696884, 0.6329565, -0.093982756, 0.7140547, 0.21587613, 1.2869248, 0.60281265, -0.47821552, 0.43734503, 0.25959963, -0.16328156, -0.12055825, 0.4622288, -0.9157813, 0.5098907, -0.31852883, -1.0538068, 0.63930315, 1.0165753, -0.8952555, -1.1551671, -0.07045259, 0.33253628, -1.4805075, 0.5346395, 0.40822038, 0.78947777, 0.056913875, -0.23994705, -0.47662988, 0.12904635, -0.3096597, -1.2386975, 0.027118616, -0.297474, -0.34640983, -0.7081305, -0.987574, -0.4112696, -0.16663915, -0.14638874, -1.0458425, 0.054047197, 0.99362266, 0.47721052, 0.39771488, -0.4090625, 0.1835733, 0.006618239, 1.8029044, -0.5752119, 1.7840273, 0.14250731, -0.8179414, 1.0404874, -0.7235668, 0.43460107, -0.17297104, -0.66153497, -0.53459716, 1.4169344, -0.25907004, -1.0876834, -0.121780336, 0.9376321, 0.087307006, 0.1502156, -1.3873982, -0.47126013, -0.72027636, -1.0648152, -1.0333831, 0.28081003, 0.0047804266, -0.41970125, 0.12368576, -1.0056207, 1.314159, 0.8322662, 0.50192, 0.6606601, 0.19176152, 0.22359805, 0.6299454, -0.8784206, 0.8435247, -0.62076545, 0.46503085, 0.4955411, 0.47523603, 0.59475726, -0.15033536, 1.5292126, -1.6526178, 0.77440363, 0.21343376, -0.1102623, -0.8003335, 0.12464988, 0.1694136, -0.092712775, 1.1573013, 0.26682746, 0.8170211, -1.0412548, 0.09060685, -0.18826349, 1.1423111, 0.03361123, 0.54229814, -0.31807727, -0.034259863, 1.3871967, -0.05026304, 0.28581905, 0.11886263, 0.7556672, 0.09417425, -1.0077528, 0.9749789, 0.031945437, 0.1542672, 0.44604713, -1.1202078, 0.24686609, 0.5521793, -0.26565984, 1.3768492, -0.41607288, 0.89860183, -0.9901299, -0.55397356, 0.3160442, -0.2748052, -0.028745566, -0.60326695, 0.1855664, 0.014004639, 0.043385062, -0.3658645, 0.21059687, -0.45689726, 0.2032052, 0.73326206, 0.35434416, 0.019100547, -1.4163734, -0.44338754, 0.26873967, -0.5155286, -1.3091766, 0.083646804, 1.3032191, -1.2324255, 0.9689458, -0.50306034, -0.13216153, -0.31209743, 0.42126146, 0.24715918, -0.36722437, 0.8198192, 0.7839475, -0.4742727, -0.23958692, -0.53167427, 0.36589828, 1.4970611, 1.1297909, -0.09345523, -0.7373089, -0.6823638] -2025-10-16 19:28:19 [main] INFO OnnxTest - ------------------------ -2025-10-16 19:28:19 [main] INFO OnnxTest - tokenizer加载耗时: 4070 -2025-10-16 19:28:19 [main] INFO OnnxTest - tokenizer计算耗时: 1 -2025-10-16 19:28:19 [main] INFO OnnxTest - 模型加载耗时: 587 -2025-10-16 19:28:19 [main] INFO OnnxTest - 模型数据准备耗时: 2 -2025-10-16 19:28:19 [main] INFO OnnxTest - 模型计算耗时: 14 -2025-10-16 19:28:50 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 19:28:50 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:28:50 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 19:28:50 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 19:28:50 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 19:28:50 [main] INFO OnnxTest - [0.51123345, 0.43754324, 0.22250144, -0.49621642, -0.59625536, -0.24450612, 0.5863322, 0.46978277, 0.5778739, 0.6761688, -0.0854191, 0.36117497, -0.24092007, -0.19524571, -0.7976704, -0.044580948, -0.53635055, -0.11370213, -1.1403378, 0.2129236, -0.34120926, 0.001864681, -1.3665671, -0.22030343, -0.830733, 0.099989876, 0.4966247, -0.066141784, 0.41148925, 0.729914, -0.29459542, 0.29208705, -0.3367949, -1.0972055, -0.024628287, -0.6583721, 1.253141, -0.61462474, -0.518246, -0.53295904, 0.12913027, 0.04108283, 0.55130756, -0.8039789, -1.2061563, -0.34272343, 0.27257943, -0.13096467, 0.18428354, 0.2605311, 0.057498857, 0.7461083, 0.1835212, 0.021440782, -0.20071763, 0.04362084, -1.3614484, -0.1095237, -1.0870106, 0.40957803, 0.7201999, 0.98604536, 0.39732328, -1.3224756, 0.40671548, 0.406975, 0.50348455, 0.22034347, 0.5530567, 0.25672144, -0.6594347, 0.96159023, 0.07775575, -0.7792945, -1.0163779, 0.36998796, 0.5171132, 0.79771215, -0.5552498, 0.80050594, 0.14805704, 0.2997373, 0.26703542, 0.08637628, -1.4002664, -0.813782, 0.25788978, 0.5414073, -0.46593362, -0.027594358, 0.29689378, 0.65353656, -0.31033817, 0.08076967, 0.76214606, 0.8415609, -0.3084258, -0.32594687, -0.72558767, -0.3289697, 1.0932022, 0.87115157, -0.89196694, -0.18925445, -0.9785898, -0.2336246, -0.9026102, 0.088704094, -0.7258216, -0.6594782, 0.09606822, 1.0850618, 0.0013394654, 0.38363743, -0.3874976, 0.20100841, -0.4128504, 0.74124134, -0.6654147, -0.5718573, 0.27072686, -0.046442233, -0.2115764, -0.7070531, -0.9749727, -0.4404279, -1.3043284, 0.93771523, 0.30211914, -0.59651214, 0.12527934, 0.089207426, 0.51316845, 0.8074455, -0.5485792, 0.07305289, 0.10457601, 0.24046482, 0.5214334, -1.1262523, 0.16574118, 0.01661903, -0.72924286, 1.7897038, 0.7391656, 0.26545036, -0.24889244, 0.019522466, -0.38037547, 0.9288784, -0.90373176, -0.2429637, 0.13991763, 0.4122005, -0.6420515, -0.045609288, -0.055985063, 0.121364415, 0.28139967, -0.0052891895, -0.106420964, 0.56713265, -0.46813145, 0.19711205, -0.58464926, 0.3698026, -0.2838148, 0.12638272, 0.01481974, -0.2993888, 0.14940853, -0.4162319, -0.045515813, -0.07729791, 0.47421545, 0.46603337, 0.62959045, 0.1828863, 0.2002228, 0.07522717, -0.50393486, 0.37032261, -0.35638678, 0.8902856, -0.033868957, 0.100021124, 0.43048963, 0.3153236, -0.6283139, -0.24138638, 0.81751156, 0.2257601, -1.2130985, 0.44707552, 0.0037308559, 0.5666142, -0.8444263, 1.204924, -0.65543765, -1.9701289, -0.8207577, 0.08641613, -0.4112931, -0.20802015, 0.87505317, -0.13793634, 0.07145847, 0.31840786, -0.092020944, -0.80500084, 0.58076894, 0.117715076, -0.67379886, 0.45848575, 0.4390001, -0.7055742, -0.712911, 0.33785975, 0.42191327, 0.121282555, 0.13419384, 0.17775199, 0.5506595, 0.67962146, 0.4780363, -0.03222577, -0.8667363, 0.8303137, -0.541459, 0.062450707, 0.03477095, 0.49735057, -0.3892, 0.8767689, -0.06756614, 0.35541242, 0.94193155, 0.8131012, 0.58299375, 0.1854296, -0.60147816, 0.4282838, 0.5299751, 0.7330451, -0.3257398, -0.58661395, 0.5521986, -0.606695, 0.44539154, 0.41345364, -0.023682468, 1.0244411, 0.8901564, -0.025144015, -0.6341725, -0.4240578, 0.31344998, 1.0556707, -0.7415066, -0.32343262, 0.1841922, 0.36124998, 0.5530684, 0.29907, -0.02951768, 0.19808297, 0.08838599, 0.05037989, -0.049141884, -1.1747736, 0.03532947, 0.07290274, -0.7062243, -0.027512219, -0.5645471, -0.034089435, 0.4769841, -0.5791185, -0.062474817, -0.5574461, -0.07675014, -0.58530134, 0.5648111, 0.7009718, 0.19080682, -0.37462634, -0.38008162, -0.8266342, -0.56594104, 0.6085925, -0.8169755, 0.2305794, 0.022104293, -0.32453218, 0.029340252, 0.12966694, -0.35197243, 1.0937076, -0.08106287, -0.630723, -0.07665277, 0.09807674, -0.15652439, -0.032777905, -0.59978753, 0.7365465, 0.8591844, -0.16815796, 0.8361499, 0.27674484, -0.3099411, 0.60480386, 0.23437774, -0.7338224, -0.9829839, 0.67439365, 0.742201, 0.42505273, -0.68957865, -0.47552192, -0.5682225, -0.5110189, -0.28437212, -0.565194, -0.19356139, 0.63973606, -0.014390081, -1.646161, 0.2918704, -0.4594489, -0.8228203, -0.16133638, 0.07148346, 0.9419251, -0.019150853, -0.4403408, -0.56392926, 0.12463045, 0.24700657, -0.19791731, 0.6058087, -0.5370069, -0.051276788, 0.9354616, -0.055462413, 0.050041005, -0.6077635, -0.68125796, -0.13532986, 0.36517376, -0.019653555, -0.03586552, -0.1600579, 0.67996794, -0.25741813, 0.9547673, -0.910809, -0.009982694, 0.7332152, -0.20394151, -0.09925252, 0.5988749, 0.10125684, -0.2892084, 0.09639569, -0.9270706, -0.14898436, 0.23913115, 0.7453801, -1.0168681, 0.80838275, -0.27111107, -0.14699328, -0.68104225, 0.19166322, -0.79916215, 0.43923154, 0.16553934, 0.33551145, -0.5704513, -0.070023894, -0.3918103, -0.17701462, 1.6619401, 0.674843, 0.23895527, 0.80687135, -0.01851894, -0.34060583, -0.58362544, -0.96381485, -0.19843449, 1.6370385, -0.44541967, -0.13564552, -1.7383175, 0.94101083, 0.4386875, 0.8844557, 0.7002662, -0.72894764, -0.6103935, -0.32648364, 0.054746274, -0.6872155, 0.18739484, -1.0520368, 0.6648933, -0.2648567, -0.06654116, -1.3043286, 0.22864798, -0.10361338, 0.594177, 0.5787685, 0.1750473, -0.0105097145, 0.91527426, 0.25346497, -0.27341178, -1.1472199, -0.31140554, -0.49403697, -0.13216135, 0.7429359, -0.57663065, -0.5814875, -0.46789917, 0.62059444, 1.0459176, 0.105841815, -0.8354111, -0.09153462, -0.4892223, -0.9736461, 0.03827665, 0.6993418, -0.5639835, 0.3098794, -0.8142145, 0.047523424, -0.21321937, -0.034833632, -0.010952409, -0.041929975, -0.28044957, 0.060209088, 0.50224316, -0.046635136, -0.85428065, 0.73049414, -1.4654225, 0.11870827, -0.66137636, 0.27924734, -0.7339802, -0.42894232, 0.17209588, 1.1703713, -0.1511008, -0.27938917, -0.13280374, 0.86497086, -0.4407706, -0.3784376, 1.2453586, -0.21126446, -0.15996158, 0.48933926, -0.27048388, -0.2984165, 0.7081715, 0.58110875, -0.06946933, -0.27087092, -0.23854852, 0.36320952, 0.3962092, 0.11321919, 0.10443739, -0.56340504, 0.49124345, 0.6088691, -0.70054543, -0.09448326, -1.4692224, 0.24175254, -0.18142638, 0.3656459, 0.3561722, 0.39745298, 0.35550624, -0.25403917, -0.8084114, -0.3391734, -0.14518976, -0.31460696, -0.8502122, -0.20892489, 0.040290922, 0.36273193, -0.76562995, -0.80031925, 0.060696647, -0.15262939, -0.061190173, -0.09423466, 0.6150074, -0.5358167, 0.3251421, 0.28123394, 0.7587028, -0.4789124, -0.10876167, -0.18576714, 0.49481302, -0.09939133, 0.20352225, -0.5852573, 0.6395335, -0.3011577, -0.8522485, -0.31254715, 0.5950347, -0.26513442, 0.70972127, 0.43091288, -0.041825093, -0.2292053, -0.6451991, -0.34200215, -0.41545817, -0.2689111, -0.9946734, -0.25178003, 0.6669945, 0.17163065, -0.15006264, -0.9421287, -0.019158833, -0.6975499, 0.438868, -0.6849216, 0.03262051, -0.44509438, 0.64882565, -0.5953382, 1.1495787, -0.8011461, 0.20847918, 0.1251037, 0.32168102, -0.21917565, 1.0629005, -0.92278206, -0.37890035, 0.4195118, -0.21815889, 0.2514746, 0.6282729, -0.14128427, 0.050928507, -0.35163182, -0.06737878, -0.9663225, -0.4687798, -0.59459, 0.21002933, 0.048163563, 0.48905462, 0.14316124, 0.028260775, 1.2529061, 0.14390653, -0.21695222, -0.7194682, -0.66993797, -0.70739895, -0.5410352, 0.8340246, -0.2935943, -0.23657572, -0.4150082, 0.20044121, 0.6332451, -0.4892323, -0.016682208, 1.8937812, 0.7091852, 0.14414868, -0.9804469, 1.2162073, 0.17216161, -0.50498605, -0.34003568, 0.16963801, -0.33994526, 0.0731189, -0.41613013, -0.94484633, -0.815923, -0.5739614, 0.94484705, 0.31987455, 0.14467219, -0.14761059, -0.7047535, -1.0639687, 0.40880874, 1.3001518, -0.23591296, 1.0019474, 0.69951487, 0.33188945, 1.2750803, -0.47983044, 0.033220377, 0.12004468, 0.9492074, 0.9103111, -0.052080557, 0.58394325, 0.8401497, -1.830512, -1.4265813, -0.17748688, -0.061487965, -0.1359964, -0.88339686, -0.37029758, -0.13061845, -0.2954845, 0.2814227, 0.25465572, -0.19771555, 0.09913704, -0.15107808, 0.011260349, -0.14225599, -0.11415321, 1.0593241, -0.7078028, 0.5747197, -0.4055798, -0.18129641, -0.47820956, 0.1952592, 0.22990699, 0.5002197, 0.10373032, 0.628042, 0.06865163, 1.0157357, -0.6903584, -0.15411828, 0.6126792, -1.4284332, -1.3705213, -0.07465902, -0.11910443, -0.13134138, 0.41676903, -0.21215296, -0.028965306, 0.3505228, 0.047843248, 0.30888152, -1.1421498, -0.08647778, -1.1076055, -0.78975534, -0.05059923, 0.058172554, 0.27877957, 0.3418617, 0.27528864, -0.0043393373, -0.425253, 0.21216352, 0.02201505, 0.46995455, -0.35277224, 1.1497868, -0.7000632, -0.49699458, -0.36768207, -0.08427355, -0.106513396, -0.15144402, -0.6940467, -0.6297557, 0.4525672, 1.2141936, -0.12161607, 0.24308786, -0.1425119, -0.38016897, 0.91598785, -0.41090524, 0.14860485, 0.28929144, 0.21543092, -0.84538454, 0.0807224, -0.2773164, 0.5301908, -0.7331233, 0.49941978, 0.5512182, -0.5476493, -0.18183059, -0.77233905, -0.15702356, -1.1651708, -0.21300837, 0.018835044, 0.32697025, 0.34967226, 0.51722765, 0.09109617, 0.61710453, 0.062239163, 0.056631085, 0.06611446, 0.46277747, 0.13079983, 0.08349137, -0.17646214, 0.26698142, 0.046738572, 0.6847735, 0.38814327, 0.014033079, -0.04680039, 0.292931, -0.8164349, 0.3852389, 0.19666976, 0.37969127, -0.23450008, 0.45247716, 0.4581556, -0.9366612, 0.5417323, -0.055298187, -0.6215795, 1.218463, -1.3511043, -0.7937524, 0.008464169, -0.9959098, 0.7161945, -0.25348237, -0.68490624, 0.39310396, 0.3586596, -0.7416965, -0.18592128, 0.30235815, 0.63015443, -0.33157557, -0.89634436, -0.5073603, 0.27419057, 0.112835586, 0.471214, -0.9042775, -0.41822886, 0.71185523, 0.6571464, 0.33782732, 0.15355957, -0.1364721, -1.0384371, 0.64586115, 0.5162391, 0.52103496, -1.1132919, 0.1564614, -0.35837764, 0.7777977, -0.5688318, -0.19020915, 0.12580645, 0.23848471, 0.050079808, 1.4870666, 0.74930036, 0.11167382, 0.51369834, 0.0912603, 0.03457948, 0.97924113, -0.2526727, -0.6790167, 1.0118998, 0.17009932, 0.59963554, 0.38631436, 0.5874571, 0.35385707, -0.49165446, -0.43353337, 0.29959297, 0.90330774, 0.008084901, 0.19826728, 0.035730332, -0.26280853, 0.49997848, -0.3445545, 0.25782338, -0.29269776, -0.7271916, -1.1451478, -0.3687011, 1.2749437, 0.28989944, -0.010594554, 0.20570764, -0.039815754, 0.7760036, 0.83210295, -0.37314057, 0.34827492, 0.33832714, 0.2549089, 0.3180246, 0.15750375, 0.37374565, 0.29076517, -1.084236, -0.2536879, 0.09893724, 0.167326, -0.42620236, -0.06183477, -0.85039747, 0.7655713, 0.5407811, 0.135566, 0.61822957, -0.658225, 0.060597345, -1.0510322, 0.29207668, -0.40406957, -0.06383139, 0.8471315, -0.3460373, 0.0568925, 0.42080507, 0.50762975, 0.29434744, -0.07577321, 0.5478096, 0.31866163, 0.77027106, 0.5869493, -0.4031725, 0.34900978, 0.03501825, -0.60266703, -0.12610222, 0.48031133, -0.843012, 0.4924527, -0.8623877, -0.6477808, 0.22316428, 0.52191186, -0.42713517, -0.4163384, 0.02406159, 0.19311489, -0.8280169, 0.7257932, 0.5891742, 0.6126962, -0.107232764, -0.07629745, -0.50356364, 0.6316943, 0.1606891, -0.70639515, -0.12811224, -0.4105088, -0.08755256, -0.40668, -0.5366433, -0.30879006, 0.10060625, 0.28111058, -0.71532774, -0.3630196, 0.59962934, 0.15385062, 0.36727977, -0.45993006, 0.22452451, -0.23574719, 1.6684455, -0.043385856, 1.6276766, -0.16736466, -0.12352954, 1.0252162, -0.27102458, 0.59440255, 0.26338896, -0.2930035, -0.61721444, 0.6569015, -0.34776017, -0.38311705, -0.4351132, 0.751855, -0.44927332, 0.28445652, -1.4778186, -0.5496483, -0.834149, -1.1146356, -0.8802563, 1.0398924, -0.14450291, -0.022082053, -0.009103067, -0.8312893, 3.564548, 0.31639445, 0.43401474, 0.63638914, 0.048858773, -0.24585214, 0.42760444, -0.627559, 0.36051834, -0.75384, 0.3967399, 0.078143656, 0.12599553, 0.86665404, 0.050567865, 0.92432106, -1.5632179, 0.19709128, 0.12208514, -0.078961484, -0.91890043, 0.23671533, 0.47289363, 0.19900943, 0.7240069, 0.16399404, 1.1182141, -1.0169126, -0.1350502, -0.46091932, 1.2807544, 0.35965964, 0.21481083, -0.3007364, -0.39301196, 0.9101389, 0.1932972, 0.15104347, 0.14832743, 0.27131686, -0.067170985, -0.6418764, 0.50354594, 0.25878644, -0.0033070669, 0.70426977, -0.6287618, 0.31597823, 0.45087764, -0.04529953, 0.8379618, -0.3591785, 0.56057227, -0.5669976, -0.84720474, -0.052068297, -0.16401154, 0.30864736, -0.8251212, 0.22997884, -0.28843462, 0.20421404, -0.10270865, 0.12777951, -0.34080166, 0.28729475, 0.63097245, 0.62922233, -0.23039082, -0.9737556, -0.37730604, 0.021021312, -0.18025522, -1.0727465, 0.0019658804, 1.0562756, -1.0607209, 0.55097324, -0.095470026, -0.16923568, 0.29799882, 0.13360816, -0.015510071, -0.3002998, 0.29892552, 0.5038376, 0.07581481, -0.25795814, -0.26878086, -0.018943973, 1.1134932, 0.84816736, 0.07172927, -0.119864315, 0.16197601, 0.55967194, -0.1490119, 0.35443506, -0.12817872, -0.7264169, 0.35164982, 0.5088061, 0.36944637, 0.75947386, 0.22153465, -0.0902444, 0.35916293, -0.22257099, -0.6245021, -0.66597265, -0.2242328, -0.47101194, -0.09299229, -1.0377257, -0.21733049, -0.32486138, -0.23556301, -0.9277732, 0.023987524, -0.5385696, -0.002912309, 0.6834146, 0.06879748, 0.26568368, 1.1300062, -0.17972237, 0.1250636, -0.06957579, -0.9457501, -0.10762876, -0.7763465, 1.5165349, -0.51138073, -0.53803205, -0.7513938, -0.16054633, -0.057135716, 0.56398803, -0.7251428, -0.9011231, -1.1330264, -0.009565931, -0.46391025, -0.3945485, -0.019825712, -0.214825, 0.662374, 0.4089401, -0.25013703, -0.11175172, -0.3359659, -0.73787993, -0.44064045, -0.95422965, 0.24658713, 0.5482323, 0.44154587, 0.15066868, -0.90368706, 0.16147381, 0.23279902, 0.41150323, -0.14870353, 0.4448821, 0.3361582, -0.5416869, 0.66956925, 9.3244016E-4, -0.58035725, -0.9133776, -0.21026349, 0.47709528, 0.559402, -0.096517116, 0.34964085, 0.021026324, -0.052352354, 0.2260392, 0.083108045, -0.82103014, -0.49560097, 0.13991357, 0.72335935, -0.22744378, -0.17416112, -0.06924981, 0.1720519, -0.056980915, -0.0040308535, 0.4777559, 0.34662804, -0.6132766, -0.1805803, -0.58219105, -0.5035861, 0.743928, 0.62252325, -0.43229088, 0.42164406, -0.7834892, 0.19773507, -0.68034565, 0.15410969, -0.46971694, -0.5955516, 0.23321742, 0.61164176, -0.10516539, 0.581982, -0.7406695, 0.31757313, -0.69854766, 0.9880034, -0.84722793, -0.7633326, 0.4578721, 0.10518447, 0.16203061, -0.6790652, -0.47155732, -0.38882074, -0.9170391, 1.0266749, -0.17550212, -0.4792506, -0.0668991, 0.39064267, 0.0947658, 0.8043089, -0.22434905, -0.313821, 0.052670494, -0.048851267, 0.32592362, -0.860603, 0.2698992, 0.3433336, -0.21785763, 1.5819844, 0.88469046, 0.07691138, 0.09752565, -0.42556408, -0.04519853, 0.87291956, -0.6176682, -0.2865502, 0.20136131, 0.36512914, -0.3311012, -0.30614272, -0.26107365, 0.1894452, 0.32637066, 0.35523584, -0.06667226, 0.10347664, -0.11940256, -0.10296476, -0.38421103, 0.6074242, 0.18352178, 0.015820663, -0.14712866, -0.20719282, 0.6038181, -0.15472703, -0.039784297, 0.059039198, 0.4398168, 0.68517715, 0.592921, -0.48001018, 0.29964036, 0.059656337, -0.36691985, -0.11802984, -0.16027823, 0.8514473, 0.061800294, -0.24240336, -0.00616711, -0.2318474, -0.27456677, -0.20014185, 0.39548382, 0.08403352, -0.6075959, 0.7013164, -0.24715367, 0.7730584, -0.5263237, 0.6818461, -0.4345966, -1.9885256, -0.57651246, 0.3897464, -0.22896479, 0.029132985, 0.62822366, -0.3221436, -0.24454945, -0.13972506, 0.07538301, -0.43282226, 0.29167226, 0.26169014, -0.22840403, 0.12716646, 0.5241455, -0.67354554, -0.23412356, 0.1583346, 0.09397203, -0.6005605, -0.062070902, 0.519738, 0.56230676, 0.19490737, 0.09140409, 0.2827071, -0.7554103, 0.9776802, -0.28762445, -0.16992666, -0.27326876, 0.5205804, -0.39026648, 0.8100204, 0.2251311, 0.3743077, 0.41226578, 0.28279757, 0.10248689, 0.78833973, -0.39051318, -0.035605595, 0.6300383, 0.67743725, -0.18472652, -0.3580135, 0.14300483, -0.36656314, 0.09548992, 0.6840508, 0.53377825, 1.0797411, 1.0701865, -0.14112248, -0.1359908, -0.52505445, 0.2282274, 0.8130599, 0.10876868, -0.5497892, -0.06409781, -0.12850465, -0.08437914, -0.348632, -0.55334604, -0.057698317, -0.020369263, 0.0053720847, 0.16307293, -0.8254809, -0.10885659, -0.54735035, -0.9688062, -0.2985726, -0.051860273, -0.13334262, 0.35509858, -0.8054574, -0.28351018, -0.68802255, 0.17037089, -0.7018103, 0.8101351, 0.96281683, -0.053284153, -0.42187208, -0.41856027, -0.7051473, -0.43084157, 0.46245623, -0.6828755, 0.13075721, -0.12911314, -0.28247756, 0.683695, 0.07331526, 0.008655533, 1.0331321, 0.41872248, -0.43458146, 0.11952154, 0.4864054, -0.4770374, -0.672267, -0.7951411, 0.90124786, 0.38761422, -0.06815794, 0.4979946, 0.3519773, -0.51443356, 0.47134402, 0.32008561, -0.52492595, -0.5968779, 0.91214985, 0.62872326, 0.25207788, -0.78720355, -0.65435094, -0.3022893, -0.026059672, 0.03250689, -0.4841232, -0.21127056, 0.94293606, -0.31384826, -1.024962, 0.4258807, -0.5591192, -0.85103065, 0.07572705, -0.029542465, 0.9386782, -0.01834616, -0.41138232, -0.41427138, 0.080845095, -0.021675527, -0.25335732, 0.85154873, -0.83299226, 0.010143421, 0.7232927, 0.60553235, 0.1309088, -0.3839781, -0.5941144, -0.45264992, 0.38672507, 0.21139218, 0.34125578, -0.30670395, 0.5510206, 0.19656421, 0.7967939, -0.61074483, 0.032774314, 0.4495337, -0.4416033, 0.04436638, 0.19213377, 0.25077653, -0.1421333, -0.07981576, -0.80517834, -0.44514215, 0.12253037, 0.5937313, -0.7326427, 0.7710463, -0.47982028, -0.026294831, -0.27366686, 0.59971505, -0.88799405, 0.34242895, 0.011235021, 0.68797493, -0.31184798, -0.2491819, -0.39411223, -0.37572742, 1.597634, 0.5555229, 0.53293955, 0.85264903, -0.014117359, -0.04914263, -0.32758757, -0.42537898, 0.016268618, 1.7822325, 0.014657244, -0.33223224, -1.4506384, 0.8279289, 0.63178736, 0.70278394, 0.16083482, -0.11632228, -0.42550898, 0.2825111, 0.050327733, -0.62059164, 0.24553949, -0.84764546, 0.5793387, -0.19014005, 0.18559122, -0.60808384, -0.22480549, -0.10949272, 0.4119357, 0.48874575, 0.10797066, 0.14826402, 0.95159596, 0.1007035, -0.28172037, -0.78677756, -0.2911378, -0.39184836, 0.18129729, 0.14663315, -0.6903422, -0.6197286, -0.22756599, 0.4553, 0.7559648, -0.19024116, -0.7333675, -0.22558317, -0.10755519, -0.8364387, -0.24587573, 0.61560297, -0.116256624, 0.09515799, -0.61133057, -0.60270244, 0.11373564, -0.478234, 0.054566797, 0.21379222, -0.20055366, 0.4200289, 0.38137415, 0.57250637, -0.8365286, 0.46541566, -1.5011121, 0.007360235, -0.7604555, 0.0025998056, -0.5833547, -0.07466688, 0.39678958, 0.96836436, -0.2345093, -0.18433093, 0.3012629, 0.2799663, -0.70134974, -0.48911846, 0.7690916, -0.06511322, -0.49618146, 0.3662134, -0.6264914, -0.22856562, 0.24773872, 0.3183567, 0.13739681, 0.07009312, 0.23409715, 0.34881467, -0.33139125, 0.28852808, -0.095444344, -0.51926076, 0.51465845, 0.2062692, -0.5242261, -0.46329415, -0.9741153, 0.06456158, 0.030457906, 0.14805505, 0.17728561, 0.27969873, 0.4174524, -0.53553534, -0.050896656, -0.7748257, 0.07999295, -0.064726844, -0.6482009, -0.16539901, 0.52794135, 0.2680578, -0.54837555, -0.846483, -0.1018344, 0.2759287, 0.01647371, -0.30559725, 0.77830505, -0.42698085, 0.22914001, 0.29629123, 0.9014104, -0.6857988, -0.02880317, -0.27855328, 0.5116826, -0.09280562, -0.026375346, -0.82933587, 0.29830056, 0.10016385, -0.9599105, 0.06670639, 0.32166743, -0.12561196, 1.15202, 0.17707397, -0.08005495, -0.039337177, -0.2968356, -0.12169429, -0.36883074, 0.2049313, -0.6679535, 0.031608433, 0.52695143, 0.007821337, -0.1485552, -0.62809414, 0.13040474, -0.15451281, 0.54773754, -0.4706813, 0.24263154, -0.1301415, 0.67641205, -0.62720996, 0.8313544, -0.7381075, -0.14358105, 0.3762475, 0.62239164, -0.045437563, 0.9459873, -0.8233303, -0.7147683, 0.46758357, -0.52135533, 0.06063361, 0.56855184, -0.507306, -0.036665827, -0.6302179, 0.07766994, -0.942735, -0.5909925, -0.2635432, 0.5478883, -0.07890162, 0.32488316, 0.26487243, 0.46853012, 1.1034807, -0.06512659, 0.33847657, -0.61609834, 0.06321365, -0.22743702, -0.87944865, 0.37845594, -0.020726902, -0.59833187, -0.42895967, -0.11077006, 1.0032699, -0.1725022, 0.32639518, 1.6419518, 0.21870343, 0.1484011, -0.7495263, 0.5773338, 0.1948407, -0.26478645, 0.31931522, -0.02530934, -0.18381046, 0.039240766, -0.3821348, -0.880036, -0.40542898, -0.5050127, 1.0508015, 0.6978597, 0.27783167, 0.43318307, -0.686163, -0.95909375, 0.39126918, 0.736118, 0.010625005, 0.4478026, 0.5347271, -0.28854454, 0.7788674, -0.65132344, 0.028316252, -0.24979532, 0.3684371, 0.8357179, -0.35869396, 0.24370271, 0.33024335, -1.4370449, -1.2778331, 0.19882585, -0.017336432, -0.4316948, -1.2735684, -0.26503587, -0.015060261, -0.6085152, 0.22704697, 0.26457584, -0.42646304, 0.03879311, -0.19615118, 0.44677356, -0.32433823, -0.084605284, 1.198679, -0.51367915, 0.36138633, -0.26781407, -0.25285503, 0.10098021, -0.24817827, -0.18135414, -0.17848538, 0.35427713, 0.521286, -0.02674108, 0.4217017, -0.08987662, 0.25608358, 0.50207585, -0.98633564, -1.0628304, -0.3846806, 0.022207262, -0.1283618, 0.37523708, -0.24025467, 0.5153696, 0.46323073, 0.13989824, 0.1561494, -0.77944976, -0.44046345, -0.63301426, -0.34989792, 0.13549271, 0.006190121, 0.24559984, 0.31742877, 0.1545193, -0.44265345, -0.08644013, 0.28001422, 0.15021466, 0.85503155, -0.76575583, 0.86318636, -0.55829847, -0.25753778, -0.7185067, -0.085994214, -0.18091784, 0.446105, -0.77112305, -0.4430915, 0.2551184, 1.1472955, -0.40047967, 0.35478163, -0.4045759, -0.48856065, 0.7408055, -0.13986495, 0.09953445, 0.2774477, 0.2467106, -0.42283788, 0.21039721, 0.10461013, 0.31418386, -0.6786972, 0.964533, 0.6333979, -0.42829648, -0.2897507, -0.9437793, 0.067182526, -0.99148446, -0.31607157, -0.5791597, 0.04460093, 0.2817655, 0.21890405, -0.0091788955, 0.614969, 0.21509607, 0.26194388, -0.028229192, 0.6323737, 0.3229837, -5.941242E-4, 0.1451681, 0.3452308, 0.26828063, 0.82891965, 0.6615142, 0.15845887, -0.1930975, 0.32330292, -0.49461275, 0.33965734, 0.5015075, 0.22370936, -0.038758203, 0.33031383, 0.64308834, -0.22973657, 0.40101275, 0.1735294, -0.62445706, 0.63983095, -1.0835669, -0.59931755, -0.25685513, -1.0129862, 0.148363, -0.3387562, -0.7876695, 0.36497584, 0.4875883, -0.46318775, -0.30246222, 0.24639976, 0.3614344, -0.4353444, -0.7491151, 0.03876262, 0.014877375, 0.5000705, 0.48863775, -0.5708522, -0.29530814, 0.39000627, 0.18866692, 0.13831648, -0.38619447, -0.5484635, -1.1455809, 0.14575654, 0.41666955, 0.17747879, -0.8406549, 0.13223548, -0.45904288, 1.1353003, -0.26693252, -0.12810816, 0.37510347, -0.29213232, -0.43941584, 0.9184803, 0.6855956, 0.2599459, 0.6948795, -0.0708392, -0.12901774, 0.55323, -0.5387498, -0.716477, 0.42386472, 0.12503567, 0.6216118, 0.10394464, 0.8343109, 0.65234077, -0.41163832, -0.39263293, -0.108594045, 0.4115751, 0.16237709, 0.28965876, -0.07473482, -0.23911166, 0.2871039, -0.6131977, 0.513528, -0.11655871, -0.6466727, -1.1273916, -0.19115873, 1.4469596, -0.020101145, -0.11192806, 0.01993516, 0.26601622, 1.1657052, 1.008147, -0.6360585, 0.12956598, 0.9011077, 0.26741764, 0.13538633, -0.082566485, 0.21531783, 0.26441088, -1.1124214, -0.27627683, 0.34551474, 0.15321879, -0.21587288, -0.29057226, -0.5665258, 1.2804754, 0.5072227, 0.2061311, 0.39224344, -0.48967192, 0.2075164, -1.2929554, 0.22832677, -1.1763334, 0.05883432, 0.5320689, -0.19186282, -0.067902, 0.5984157, 0.33769348, 0.24878782, 0.11002658, 0.33792466, 0.547646, 0.7538705, 0.59686947, -0.19582872, 0.39902282, -0.3311249, -0.74637324, -0.14266883, 0.43165115, -0.6139184, 0.29811418, -0.7535113, -0.30266273, 0.53370935, 0.36760342, -0.5749821, -0.68662786, -0.2779321, 0.37260574, -1.1336465, 0.6302474, 0.47815326, 0.9866135, -0.14947067, -0.033082485, -0.2046695, 0.20482336, -0.21032988, -0.52653766, 0.0245497, -0.47625363, -0.12423223, -0.12356821, -0.32638925, -0.0979994, 0.0010491088, 0.29562947, -0.6457077, -0.10971795, 0.06126561, 0.8076332, 0.2573005, -0.21695858, 0.46280462, -0.5214897, 1.3339914, 0.23493724, 1.6153331, 0.18739215, -0.35449666, 0.6756968, -0.35441598, 0.49293745, -0.08351409, -0.24639843, -0.57777464, 0.98248875, 0.0011553783, -0.68022805, -0.1735664, 0.5991789, -0.5056995, 0.28030026, -1.3956647, -0.29886672, -1.040315, -0.6200091, -0.55999726, 0.4394985, 0.25020325, -0.030757431, 0.41339186, -0.99428976, 4.134183, 0.21829394, 0.2768517, 0.24642767, 0.027245255, 0.22640549, 0.47818106, -0.79617405, 0.4751648, -0.4929724, 0.5096883, 0.14533526, 0.087542474, 0.42481625, -0.26212215, 0.94900197, -0.995192, 0.37323165, 0.48663512, 0.16938138, -0.9202455, 0.32618392, 0.3355089, -0.12735334, 0.39952835, -0.4738593, 0.17960149, -0.8438873, -0.15847224, -0.28993642, 1.529727, -0.06471403, 0.040852357, 0.038847372, -0.25056893, 1.0816733, -0.30027992, 0.33796108, 0.057108454, 0.27828, -0.07463636, -0.7907264, 0.89314646, 0.11971448, -0.2797623, 0.56961, -0.5983841, 0.07197225, 0.6231197, -0.16240701, 0.8118333, -0.10884293, 0.36955264, -0.30067077, -0.54466736, 0.23035151, -0.11903405, 0.15843613, -0.9551723, -0.008313894, -0.09104793, -0.34124452, 0.019560076, 0.22333694, -0.46288738, -0.06519584, 0.8732297, 0.4417033, -0.3591715, -0.79684395, -0.18898311, -0.00398656, -0.32608062, -0.624982, -0.43221474, 0.7961611, -1.0244153, 0.6864666, -0.38873324, -0.66227776, 0.18808874, -0.2118657, 0.12453443, -0.20756744, 0.2250452, 0.5361353, -0.38134813, -0.12358688, -0.50916564, 0.06882605, 0.5491102, 0.6088567, 0.043271434, 0.034038477, -0.14568043, 0.34731272, 0.27437162, 0.4291449, -0.5072562, -0.6460547, -0.17843097, 0.4998613, 0.4862506, 0.48174888, 0.43009067, -0.07885784, 0.25953156, -0.44193333, -0.2746965, -0.72802746, -0.24735373, -0.46056688, -0.08113882, -1.2671432, 0.05059053, -0.43514493, 0.09988372, -1.3890023, -0.5439976, -0.5726784, 0.042483523, 0.45590004, -0.12616622, 0.629282, 0.96405625, -0.42434147, 0.29803038, -0.16519342, -0.9395849, -0.230326, -0.83917814, 1.4581625, -0.57237923, -0.5016961, -0.5101177, 0.03989938, -0.16089517, 0.91115934, -0.69840354, -1.4957484, -0.25355923, 0.24498278, -0.03987664, 0.28695616, 0.33610544, 0.42031482, 0.26267177, 0.26665464, -0.036663882, -0.3205201, 0.08044999, -1.3707422, -0.10242602, -1.2773657, 0.44744903, 0.4707493, 1.1146326, 0.52519447, -1.0453299, 0.22108254, 0.3916083, 0.51568663, 0.2354028, 0.50902164, 0.15007426, -0.6983879, 1.0460291, 0.11031413, -0.68165857, -0.867732, 0.08759557, 0.32828143, 0.90392447, -0.74337864, 0.6990192, 0.12273654, 0.1353184, 0.41217592, 0.24795906, -1.3185968, -0.7651147, 0.103916384, 0.6086596, -0.29084563, 0.022982366, 0.28086853, 0.55208766, -0.31949097, -0.01541844, 0.81749123, 0.83401155, -0.14799729, -0.33081663, -0.8713344, -0.20599653, 1.2038018, 0.81881714, -0.62137777, -0.08521465, -0.9437865, -0.19047725, -0.9235109, 0.07554969, -0.54554856, -0.72309697, 0.10257645, 1.2262453, 0.11698446, 0.5399791, -0.6098297, 0.077516764, -0.1635267, 0.7329004, -0.6491352, -0.43532693, 0.13268438, -0.062738866, -0.037672497, -0.6150539, -0.792422, -0.32316244, -1.1831503, 0.8048623, 0.43596715, -0.80266297, 0.20404984, 0.040005, 0.51196873, 0.61864376, -0.3671871, 0.039022297, 0.08777553, 0.34561458, 0.48366174, -1.1842922, 0.108419, 0.09672105, -0.4544338, 1.6715314, 0.8024864, 0.38295293, 0.11245011, -0.13004047, -0.25588313, 0.9442645, -1.106852, -0.3146361, 0.17383303, 0.26125604, -0.836142, -0.2676666, 0.09179972, -0.11250311, 0.35692418, -0.074471295, -0.117300734, 0.47520566, -0.5543069, 0.32387045, -0.66126156, 0.395984, -0.23777974, 0.31760883, -6.269303E-5, -0.42587698, 0.3092674, -0.26971295, 0.12728855, -0.09048116, 0.3214799, 0.6557833, 0.40655518, -0.043354645, 0.23725055, 0.05158411, -0.5487681, 0.47276476, -0.42214486, 0.96318287, 0.101917736, 0.04613815, 0.37172058, 0.35901445, -0.55353534, -0.28215954, 0.646838, 0.055748854, -0.94629276, 0.52053577, -0.096165426, 0.68151516, -0.86083305, 1.2210809, -0.61603034, -1.8547043, -0.70553493, 0.08560893, -0.32475078, -0.07537295, 0.9242262, -0.3031748, -0.039215017, 0.48975095, 0.07386944, -0.635114, 0.5792452, 0.11396569, -0.79614615, 0.47500247, 0.22382374, -0.7640738, -0.7832393, 0.32251167, 0.2957459, 0.19379763, 0.1966333, 0.19957598, 0.47575438, 0.72345144, 0.2891014, -0.07611428, -0.7970295, 0.68839777, -0.65931904, 0.18129885, -0.1070019, 0.4440913, -0.3229485, 0.87062204, 0.0016378155, 0.34254807, 1.0556462, 0.9242675, 0.3841158, 0.19424327, -0.5399717, 0.45922905, 0.4348209, 0.7463028, -0.23992652, -0.60218215, 0.26373464, -0.48176405, 0.3577192, 0.30109936, 0.18007952, 0.97340673, 0.8311445, -0.091018654, -0.43556908, -0.47817314, 0.24427673, 0.86847204, -0.63367134, -0.1392084, 0.20880738, 0.29605484, 0.5102095, 0.0539689, 0.025343515, 0.24565774, 0.20760463, -0.14849266, 0.07748646, -1.0975155, -0.2468316, 0.049564585, -0.81448174, 0.07844066, -0.5533479, -0.12086342, 0.34281364, -0.47970983, 0.012860723, -0.20691025, -0.09066814, -0.6537314, 0.488608, 0.72847027, 0.43217465, -0.3573188, -0.2835165, -0.7994006, -0.60978246, 0.6759259, -0.74162185, 0.021587722, 0.2148367, -0.31782195, 0.15477072, 0.073249355, -0.2504549, 0.9304441, -0.109614864, -0.39431396, -0.13444294, 0.113385625, -0.17943051, -0.13110475, -0.6351985, 0.8168083, 0.7287063, 0.046382003, 0.78491753, 0.12041721, -0.44125587, 0.65859365, 0.1417125, -0.62944174, -0.8578431, 0.5297364, 0.5970799, 0.32134923, -0.6988253, -0.3988505, -0.53683966, -0.5645854, -0.26411146, -0.54879487, -0.08550332, 0.5523895, 0.09527285, -1.4829303, 0.42620313, -0.32207206, -0.80331665, -0.14081834, 0.14321318, 1.0547477, -0.014484324, -0.3733287, -0.6547246, -0.22136927, 0.23872378, -0.114890546, 0.52663624, -0.36137518, -0.10336557, 0.84902483, 0.24802007, 0.2428974, -0.55062777, -0.898774, -0.086360104, 0.42273575, 0.01069665, 0.03268071, -0.22184242, 0.68654114, -0.31356922, 0.99203634, -0.8053663, 0.024493441, 0.52120054, -0.14788416, 0.16501157, 0.71239144, 0.10519813, -0.23112617, -0.30074418, -0.7945606, -0.32828715, 0.1546241, 0.71328896, -0.8631298, 0.6879144, -0.25349656, -0.15505737, -0.52401733, 0.026135508, -0.91197675, 0.4897887, 0.2553321, 0.38357615, -0.5817329, 0.10147074, -0.14365219, -0.07878406, 1.460639, 0.76415765, 0.44990405, 0.9951974, -0.10996676, -0.43003532, -0.6043866, -0.97104216, -0.10857196, 1.7999303, -0.2487742, -0.23330228, -1.9624965, 0.8282924, 0.3562973, 0.99590814, 0.710325, -0.74927074, -0.47313, -0.23652235, 0.17110118, -0.64118886, 0.18618682, -1.0815334, 0.4417191, -0.27619588, 0.13438608, -1.2182668, 0.09222232, -0.046028994, 0.5128414, 0.6309838, 0.17811278, 0.08257908, 0.82218415, 0.24052832, -0.3043413, -1.1845739, -0.31409425, -0.5495012, -0.102475435, 0.6949858, -0.60669345, -0.5356563, -0.12042385, 0.51972234, 0.9788067, 0.27975333, -0.6509743, 0.08709107, -0.3396774, -1.0324789, 0.21493271, 0.64101464, -0.4424937, 0.35320687, -0.8626394, 0.018576376, -0.14504273, 0.0675314, -0.09590454, 0.14231923, -0.32527098, 0.15347226, 0.50280917, -0.12097482, -0.93272054, 0.6082158, -1.5437937, -0.07995024, -0.6858374, 0.39547303, -0.5739462, -0.52489924, 0.041147597, 1.3033543, -0.17370999, -0.22331943, -0.12098679, 0.7863538, -0.6103873, -0.3908378, 1.0210451, -0.33337703, -0.335317, 0.679813, -0.03252794, -0.46655637, 0.58323187, 0.526237, -0.17061844, -0.47416002, -0.35893548, 0.4063307, 0.32042253, -0.0637602, 0.13230446, -0.44979116, 0.5168601, 0.33988982, -0.7665607, 0.0853706, -1.2825401, 0.35769534, -0.21235913, 0.25373393, 0.2737563, 0.4383112, 0.26156312, -0.18157701, -0.82445776, -0.54746836, -0.19033858, -0.14472756, -0.8237075, -0.20849845, 0.09290561, 0.45805925, -0.60196894, -0.9694583, 0.22632071, -0.15821098, -0.07559876, -0.13461533, 0.6933839, -0.32768452, 0.3443336, 0.31391212, 0.9203925, -0.36575687, -0.20933554, -0.31347826, 0.5546571, -0.016795274, -0.092404574, -0.5469727, 0.6365913, -0.43841305, -0.8389967, -0.036488578, 0.61133695, -0.3538103, 0.76916534, 0.2602567, 0.04585594, -0.20960002, -0.69782466, -0.073778585, -0.4628681, -0.31100827, -1.194452, -0.15880762, 0.61074346, 0.01697435, 0.08602919, -1.0204202, -0.1064734, -0.5719034, 0.3842537, -0.61645734, 0.005817363, -0.5069963, 0.73048353, -0.58076227, 1.1014149, -1.002687, 0.26485753, 0.001325082, 0.23775855, -0.1090179, 0.8222375, -0.8824368, -0.60530984, 0.38780227, -0.18472426, 0.18662238, 0.6539168, -0.08568022, 0.0025433525, -0.35558033, 0.019322174, -0.88901633, -0.6802375, -0.69873244, 0.29876226, 0.03279008, 0.41753015, 0.15544944, 0.136213, 1.1869895, 0.13588208, -0.24654882, -0.68050987, -0.6760854, -0.6779837, -0.68511623, 0.96097136, -0.5064433, 0.005498264, -0.47417802, 0.14546248, 0.7594362, -0.367512, -0.098296344, 1.961263, 0.35767633, 0.03230954, -0.69004714, 1.1331533, 0.27895185, -0.49140096, -0.07016089, 0.16740261, -0.34845498, 0.25857598, -0.37114236, -0.92653924, -0.78350365, -0.41225216, 0.69445866, 0.34486955, 0.093205795, -0.066756755, -0.64549917, -1.1127244, 0.37053987, 1.1387469, -0.23592287, 0.80528295, 0.63944227, 0.54414797, 1.0815576, -0.5668222, 0.089382716, 0.13776606, 0.9200868, 0.8992326, -0.27931058, 0.48805022, 0.82883877, -1.7794003, -1.3662231, -0.16744435, 0.084341876, -0.107593, -1.017171, -0.3791846, -0.14377698, -0.27979684, 0.51328593, 0.26247755, -0.27690327, 0.076862276, 0.0780327, -0.07342488, -0.061520025, 0.0024008472, 0.8332128, -0.6966219, 0.4901986, -0.24039306, -0.14298935, -0.24950793, 0.12527625, 0.29839414, 0.7389395, 0.15047178, 0.58706343, 0.12560952, 1.0310695, -0.5962883, -0.18943071, 0.6150714, -1.2840291, -1.3595079, -0.15191634, -0.25942472, -0.17627351, 0.3720213, -0.10289232, 0.056950808, 0.3213657, 0.3321522, 0.053539947, -1.0371126, -0.052774735, -0.87331986, -0.7267541, 0.051209338, 0.1441378, 0.31906247, 0.46871975, 0.18395185, -0.0692848, -0.42856544, 0.01773473, -0.1260064, 0.71401536, -0.27404174, 1.3056145, -0.61608034, -0.3932829, -0.24632904, 0.010613654, -0.21523128, -0.08095754, -0.4983497, -0.626685, 0.64032483, 1.0719864, -0.35518745, 0.31677714, -0.09860298, -0.29361737, 0.98726356, -0.28703505, 0.37888417, 0.2140752, 0.36996755, -0.71319747, 0.2214708, -0.3875488, 0.37793255, -0.7721462, 0.6461019, 0.6115026, -0.5304169, -0.17443098, -0.70448905, -0.021181267, -1.0428503, -0.34047216, -0.06293756, 0.17875059, 0.28179625, 0.44505474, 0.16711755, 0.6964868, 0.2429418, -0.048931554, 0.101600535, 0.29270682, 0.14754868, 0.040776677, -0.2830106, 0.24993977, 0.18217126, 0.5031197, 0.6458861, 0.08088947, -0.06821887, 0.2294434, -0.6025328, 0.4214955, 0.02959657, 0.31607035, 0.048564933, 0.36561626, 0.4328048, -1.0279614, 0.5526877, -0.3101868, -0.7041938, 1.2670145, -1.0038794, -0.7538339, -0.051289015, -0.99725854, 0.54648906, -0.11038782, -0.8033994, 0.31729695, 0.11359299, -0.5800839, -0.29594612, 0.130738, 0.6961497, -0.31145877, -0.6745281, -0.3327659, 0.3130085, 0.12843235, 0.3653333, -0.8100079, -0.22264737, 0.5917342, 0.86295915, 0.3166489, 0.16683327, -0.26316214, -0.8232067, 0.5095601, 0.20595878, 0.45409048, -0.8229478, 0.10812789, -0.47012043, 0.8713862, -0.64504915, -0.24139825, 0.0829124, 0.30529198, -0.04502464, 1.3450638, 0.87469786, 0.1282358, 0.21878737, 0.5608324, -0.023736248, 0.8814906, -0.2450681, -0.64366734, 0.987674, 0.47663254, 0.72472185, 0.20790745, 0.4268311, 0.3406033, -0.40542594, -0.44307786, 0.21143325, 1.1998398, -0.04269371, 0.032475434, -0.028270632, -0.28937843, 0.63828766, -0.4257946, 0.30673802, -0.20225716, -0.8918963, -1.081641, -0.446235, 1.3505905, 0.28334346, -0.113350704, 0.10584864, 0.13026781, 0.9782037, 1.2069069, -0.59382397, 0.13534994, 0.20910484, 0.3964433, -0.08584341, -0.18862218, 0.29279798, 0.10304643, -1.0189443, -0.48712122, 0.089892246, 0.40033635, -0.43739498, -0.09577835, -0.8914217, 0.5634942, 0.46147624, 0.18333669, 0.5018127, -0.57141834, 0.22123447, -0.984082, 0.73240864, -0.42637298, 0.14858729, 0.58898765, -0.41788393, 0.15860158, 0.5590106, 0.5476727, 0.38015527, -0.06930857, 0.63783866, 0.19000062, 0.5320519, 0.85254997, -0.25869924, 0.36578634, 0.059271112, -0.82330275, -0.10596946, 0.32942462, -1.0458459, 0.47975013, -0.9814856, -0.54931, 0.12817167, 0.4720524, -0.60098046, -0.5558935, -0.07903196, 0.08017051, -1.0334187, 0.72646886, 0.28693724, 0.6514715, 0.017122403, 0.059414208, -0.43003318, 0.61294556, 0.15250102, -0.6344637, -0.124711365, -0.40405872, -0.21501787, -0.5084465, -0.6109873, -0.29131338, 0.21077976, 0.4723583, -0.6350576, -0.42727095, 0.3745004, 0.2436617, 0.16013308, -0.266916, 0.41006523, -0.13443582, 1.4617592, -0.09403017, 1.6679444, -0.113599226, -0.1766919, 1.1128019, -0.4637022, 0.6026775, 0.3295456, -0.26246035, -0.58322674, 0.63749, -0.29790995, -0.4552287, -0.34962073, 0.4757661, -0.38596824, 0.40881908, -1.6522696, -0.56499016, -0.9354418, -1.0565773, -0.9105244, 1.0067492, 0.12771598, -0.004504431, 0.23984769, -0.66904426, 3.6624045, 0.2592154, 0.27187067, 0.5508017, -0.10568046, -0.2670927, 0.5288961, -0.6268612, 0.20718782, -0.9910453, 0.4760573, 0.0844937, 0.11704531, 0.7277677, 0.06835682, 0.9558804, -1.4853053, -2.8017908E-4, 0.11895311, -0.11955248, -1.2167906, 0.5527989, 0.5219648, 0.25548583, 0.5149375, 0.123984054, 1.0438063, -1.0745394, -0.09779909, -0.5746613, 1.2606201, 0.4869489, 0.02342626, -0.30612367, -0.4081654, 0.54757965, 0.18535367, 0.089302, 0.14784724, 0.33126256, -0.024330921, -0.46541923, 0.44284585, 0.052763782, 0.093688585, 0.49122953, -0.9165186, 0.34113777, 0.31382066, -0.054380115, 0.8466793, -0.28731346, 0.28629318, -0.57786727, -0.5250714, -0.15221663, 0.029823096, 0.40237293, -0.7914292, 0.24210334, -0.42463204, 0.25620586, -0.21277969, -0.050531507, -0.18733416, 0.16404244, 0.696484, 0.25563902, -0.18624108, -0.8773365, -0.56324744, 0.31544864, -0.31330204, -0.8109294, -0.13510668, 0.9721738, -1.0318075, 0.26569387, 0.038234264, -0.31428084, 0.22263722, 0.06329511, -0.15759473, -0.36926627, 0.17948699, 0.5136905, 0.01984401, -0.19416128, -0.38064262, -0.37309346, 1.102059, 0.7792553, 0.060157903, -0.108390525, 0.11017364, 0.3994228, 0.09555158, 0.5825012, -0.60580367, -1.0827808, -0.1576766, 0.7572717, 0.51690817, 0.76832026, 0.5623794, -0.5242806, 0.10713714, -0.28198227, -0.3057894, -0.4436093, 0.0508234, -0.67036074, -0.50983393, -1.126107, 0.10048007, -0.28169256, 0.06555464, -1.1903594, -0.55183387, -0.4405081, -0.17009944, 0.5612562, 0.047636222, 0.37082034, 0.65144277, -0.21440561, 0.19920659, -0.08983047, -1.3184719, -0.21471508, -0.77892214, 1.0248505, -0.60647166, -0.48059314, -0.38415653, 0.33976716, 0.0074042156, 0.3431964, -0.7637138, -1.562081, 0.21412212, 0.41796106, -0.21860333, -0.036963142, -0.15398574, -0.067759186, 0.6621827, 0.14345872, -0.10131864, -0.15699252, 0.3062003, -0.93177044, 0.110051446, -1.2522842, 0.80647933, 0.19306532, 0.93869627, 0.41989905, -1.2128512, 0.048087396, 0.43417054, 0.51452124, 0.22957322, 0.6538078, 0.045719445, -0.49581295, 0.6129913, 0.2330572, -0.76418656, -0.59514874, 0.10234557, 0.34008834, 0.93430877, -0.7938407, 0.3488256, -0.095158495, 0.39193368, 0.32834923, -0.1460364, -1.1935029, -0.7402658, -0.06672922, 0.34790787, -0.24937785, -0.09675882, 0.54674053, 0.29830703, -0.25361973, 0.26495603, 0.8386657, 0.93270355, -0.30766344, 0.10872549, -0.54271966, -0.2646044, 0.80850345, 0.80533385, -0.3436443, -0.15843843, -1.1156524, -0.37078837, -0.9744277, 0.38333637, -0.7051673, -0.4906921, 0.054198608, 1.0482272, -0.16283801, 0.28291935, -0.2076324, 0.24571949, -0.42660946, 0.6194447, -0.5943218, -0.2044191, 0.80598855, 0.033541154, -0.16847873, -0.4267447, -0.5693771, -0.32211003, -0.80143666, 0.52846223, 0.42857355, -0.2879928, 0.25050047, 0.05486901, -0.059970193, 1.0365646, -0.21031526, -0.2751096, 0.4085902, 0.5967447, 0.46310297, -1.244204, 0.2939693, -0.06727497, -0.65307546, 1.6378098, 0.6602727, 0.3331953, -0.5972358, -0.16830699, -0.4092154, 0.9061645, -0.70522636, -0.30478314, 0.21947536, 0.30807325, -0.5290096, -0.021191731, -0.048273534, 0.052654807, 0.4325883, -0.002106417, 0.22604083, 0.6506453, -0.4128863, 0.06486968, -0.5109035, 0.6262629, -0.59054273, 0.54796576, -0.078081556, -0.22457956, 0.10496932, -0.7126875, -0.07178986, -0.014613241, 0.25202245, 0.6094514, 0.7096744, 0.17859364, -0.07159945, -0.10782984, -1.0702442, 0.2905703, -0.06708715, 0.73710424, 0.025326883, -0.04851279, 0.2838625, 0.100776896, -0.47360796, -0.23008478, 0.7629225, 0.4038585, -1.1927986, 0.7186655, 0.17397834, 0.66196936, -0.3637218, 1.0107775, -0.55020744, -1.4909959, -0.56990623, 0.30201685, -0.20511222, 0.2730165, 0.73218584, 0.048040986, -0.044010743, -0.15303451, -0.17348513, -0.39569393, 0.6480931, 0.10182218, -0.5377528, -0.012679113, -0.007665368, -0.65783006, -0.6718512, 0.36023977, 0.50482917, 0.112826176, -0.16764028, 0.09783888, 0.54286546, 0.82194656, 0.32949015, -0.10446587, -0.66156757, 0.44045573, -0.6881772, -0.12748857, 0.011206888, 0.5880827, -0.3310844, 0.60313576, 0.24298477, 0.18763687, 0.6665168, 0.8176408, 0.63851047, 0.7703525, -0.38874447, 0.29319334, 0.21659724, 0.67248577, -0.04747004, -0.75138336, -0.032682426, -0.58525085, 0.6164005, 0.5252805, 0.067715034, 0.77593464, 0.5756692, 0.01080169, -0.5409408, -0.18088111, 0.28055167, 0.7370628, -0.061915897, -0.14930114, 0.42736712, 0.07878585, 0.6338375, 0.028980128, -0.018971909, 0.24936385, -0.10556009, -0.007052973, -0.08535256, -1.1767282, -0.25823215, -0.16164792, -0.59529424, -0.04154039, -0.43678924, 0.16663226, 0.3614608, -0.4110936, -0.12785242, -0.561177, -0.49575725, -0.53649414, 0.55716574, 0.9938018, 0.3834205, -0.4088232, -0.16438262, -0.8488413, -0.68160176, 0.48920587, -0.35171676, 0.17286812, 0.14482836, -0.4438081, 0.34934083, -0.11522612, -0.18400648, 0.9550849, 0.19140965, -0.25227302, 0.060297303, -0.0070842654, -0.15262157, -0.484868, -0.6926102, 0.84828264, 0.91567695, 0.0016165003, 0.6874639, 0.023342803, -0.5647343, 0.4872593, 0.36987463, -0.53967863, -0.7367035, 0.6690624, 0.36760825, 0.41536736, -0.70216143, -0.78941077, -0.46292698, -0.32272416, 0.00408322, -0.569716, -0.0982589, 0.7778945, -0.22264656, -1.2859204, 0.14981261, -0.4571321, -0.84205663, -0.3931107, -0.13485941, 0.7186496, -0.11406441, -0.19351138, -0.3396683, -0.12722772, 0.0022645625, -0.023715228, 0.7800383, -0.23587298, 0.32181016, 0.6075423, 0.20606756, 0.08583229, -0.3835686, -0.76363343, 0.11516355, 0.26286107, 0.15805645, 0.010979824, -0.28352818, 0.42406383, -0.06747039, 0.7641131, -0.8182565, -0.031834044, 0.59817415, -0.556535, -0.13097134, 0.45006514, 0.45921433, 0.18680452, -0.2353987, -0.39224648, -0.20950153, 0.44744873, 0.7575571, -0.99211806, 1.0048358, -0.21880436, -0.29180026, -0.4883183, 0.11914819, -0.45420957, 0.5537008, 0.038552634, 0.28215736, -0.6505611, -0.05639731, -0.22432365, -0.0753257, 1.534879, 0.6527801, 0.33230194, 0.5043558, -0.17230092, -0.5368485, -0.60196584, -0.972783, -0.35474154, 1.5653621, 0.13357976, -0.23607488, -1.9256357, 0.99502707, 0.56387746, 0.95426637, 0.44848073, -0.6578555, -0.5840174, -0.21664485, -0.06438644, -0.6586791, 0.713435, -0.7542643, 0.4121706, -0.47967133, -0.5214753, -0.86162406, -0.41749653, 0.16635127, 0.67231923, 0.63377875, 0.060160317, -0.16357699, 0.70590246, 0.24508043, -0.31862876, -1.0028367, -0.1415234, -0.4981313, -0.07634404, 0.5626511, -0.5439674, -0.41470236, -0.32987338, 0.38528684, 0.8707138, 0.61265385, -0.7561777, -0.058350243, -0.29060918, -0.8828205, -0.32191333, 0.7171919, -0.6715127, 0.25353637, -0.85777193, -0.22826701, -0.10268143, -0.3677761, -0.21263666, 0.39470083, -0.50553197, 0.104695916, 0.38097295, 0.37870398, -0.7951013, 0.5898909, -1.4096434, 0.18723375, -0.67144465, 0.08446455, -0.32043055, -0.21069425, 0.060452625, 0.89954424, -0.33245453, 0.060212478, -0.16919714, 0.51581824, -0.46913767, -0.43260145, 0.8914732, -0.17595634, -0.39337397, 0.5862695, -0.165371, -0.41703492, 0.2300126, 0.8531972, 6.863475E-4, 0.018732369, -0.19274993, 0.11807219, 0.16294602, -0.13752386, 0.17776681, -0.7283606, 0.5255629, 0.21245965, -0.61398387, -0.019701332, -1.1922736, 0.072056726, -0.15926456, 0.06668207, 0.6565079, 0.3800544, 0.2927567, -0.18829279, -0.47632927, -0.5828585, -0.2932791, -0.32696068, -0.44982386, -0.1601027, 0.23962039, 0.35986, -0.6936998, -0.4130165, -0.028386503, 0.1189172, -0.23614475, -0.13688965, 0.8730439, -0.3260798, 0.6230809, -0.009794818, 0.64238536, -0.30446264, -0.1213474, -0.21677762, 0.64032716, -0.09058951, 0.32761735, -0.8952577, 0.7286184, -0.28435072, -1.0795968, 0.07461093, 0.5260262, 0.081124514, 1.1400597, 0.20557263, -0.22531477, -0.013032559, -0.63784456, -0.25429648, -0.43621144, -0.25980812, -0.68846905, 0.018888742, 0.40777546, 0.31415194, -0.06978384, -0.83367103, -0.47623697, -0.50554305, 0.050676435, -0.54136133, 0.09123197, -0.46119207, 0.8309509, -0.9467837, 1.3522601, -0.56323236, 0.04193849, -0.083614424, 0.65520114, -0.07264876, 1.2610217, -0.6354654, -0.54056776, 0.70698595, 0.00911441, 0.20147234, 0.8186352, -0.38808322, -0.081993535, -0.18767877, 0.27850354, -0.8085504, -0.6826043, -0.70434916, 0.28125268, -0.00417158, 0.1764245, 0.1252622, 0.13679127, 1.1405021, -0.16482627, -0.04663332, -0.58190393, -0.45656186, -0.49414352, -0.6545142, 0.7316151, -0.75474155, -0.13049766, -0.78929186, -0.1713476, 0.68869865, -0.1354918, -0.12297894, 1.374426, 0.53188884, -0.19543867, -0.7560643, 0.7825549, -0.20464867, -0.6691693, -0.024741076, 0.15538393, -0.20939259, 0.09335803, -0.32170793, -0.9581545, -0.3086296, -0.45974192, 0.9343871, 0.28155223, 0.026325535, 0.3607343, -0.51085424, -0.68860966, 0.51546973, 0.9578018, -0.32939222, 0.88570464, 0.8727469, 0.282832, 1.3196431, -0.46789652, 0.18751012, -0.009741772, 0.7062707, 0.7235945, -0.44040543, 0.32659394, 0.82885027, -1.513391, -1.0347612, -0.31969503, -0.17150323, -0.31322023, -1.0168256, -0.39043573, -0.32385135, -0.62966126, 0.4967361, 0.14318325, -0.02364469, -0.18822855, 0.36839056, 0.31844568, -0.25449395, 0.2378134, 1.1323748, -0.57734036, 0.57482517, -0.25512508, -0.3082748, -0.19442557, -0.1397948, -0.37038362, 0.7746373, 0.19150639, 0.057238307, -0.5009022, 0.7646541, -0.3515749, -0.1592197, 0.671271, -1.4349705, -0.87009597, -0.58153695, -0.0132568665, -0.26201454, 0.46259606, -0.24323648, 0.4780776, 0.24452041, 0.022693053, 0.21807481, -1.0536666, -0.3690221, -0.9724109, -0.5958498, 0.2780582, 0.17680575, 0.30712324, 0.33505383, 0.24084339, 0.3497074, -0.066905096, -0.046884567, -0.19839972, 0.49531293, -0.1463247, 0.68853134, -0.57161236, -0.5265372, -0.46173963, -0.29136887, -0.09823992, -0.25131285, -0.49662158, -0.29860687, 0.4173069, 0.61001307, -0.23230451, 0.33880717, -0.38124043, -0.62723, 0.7280858, -0.41596067, 0.12235218, -0.046359077, 0.1374916, -1.0030403, 0.076998085, 0.010334268, 0.16277502, -0.75184274, -0.045661084, 0.6897451, -0.5234157, -0.20258962, -0.35811937, -0.16314638, -1.2877578, -0.29840237, 0.11212779, 0.1864383, 0.30804637, 0.47436863, 0.07938605, 0.23727947, 0.15619943, 0.15607107, 0.3661412, 0.19492516, 0.52977335, 0.14330177, -0.39681092, 0.1595948, -0.17317334, 0.92330325, 0.95668155, 0.16457509, -0.082535796, 0.33720917, -0.6979915, -0.18996246, -0.18736917, 0.0076782946, 0.04778067, 0.4375449, 0.4449576, -0.5646165, 0.4824912, -0.73924667, -0.41778222, 1.228386, -1.4113506, -0.5091015, 0.018879347, -1.0306215, 0.3441526, -0.29703033, -0.76199734, 0.48998946, 0.0538232, -0.6444448, -0.55421084, 0.46473855, 0.41143027, 0.023548841, -0.5623564, -0.15067895, 0.5425395, 0.02348781, 0.33763394, -0.99986434, -0.40732938, 0.64412487, 0.61347324, 0.1844104, 0.060828157, 0.19362581, -0.89388067, 0.44956368, 0.61369896, 0.52955574, -0.93781817, 0.3274699, -0.2934738, 0.886754, -0.7060228, -0.09946883, 0.28589666, 0.38918224, 0.019775577, 0.8416462, 0.60078466, 0.22841358, 0.7777619, 0.048576668, 0.12920377, 0.708591, -0.17719474, -0.62505966, 1.0092452, 0.61805975, 0.53742653, 0.11385523, 0.30024686, 0.50781274, -0.65055555, -0.3315245, 0.089441545, 0.6801583, -0.055591352, 0.5085515, 0.080202654, -0.6231575, 0.7095781, -0.09222566, -0.0023482144, -0.2301088, -0.78504163, -0.89850014, -0.61895406, 1.4755174, 0.44006103, 0.3736515, 0.2789185, 0.3126807, 1.0981504, 0.5982582, -0.5319362, 0.2933641, 0.59055275, 0.449096, 0.09719907, 0.23644274, 0.4262668, 0.19561322, -0.99225354, -0.27452955, 0.0054776296, 0.42809853, -0.3454189, 0.024061855, -0.7582559, 0.4612135, 0.5061168, 0.16127184, 0.2933835, -0.74961704, -0.08755819, -1.038512, 0.52964205, -0.6356245, -0.039177597, 0.8408139, -0.43552092, -0.22568429, 0.6004227, 0.5666311, 0.34723854, 0.17451535, 0.46295786, 0.57787806, 0.5428326, 0.93625444, 0.25844303, 0.71137315, -0.17457405, -0.9393191, -0.0062135123, 0.7324282, -0.8502125, 0.21925573, -0.6307975, -0.40189654, 0.27061498, 0.65880245, -0.59898424, -0.7496212, 0.03331019, 0.19341184, -0.50549847, 0.76212996, 0.35790926, 0.7870286, -0.0400087, 0.055058934, -0.5947467, 0.26547173, 0.13392746, -1.1119648, -0.17382655, -0.5744398, 0.111572, -0.59631276, -0.62594944, -0.097791016, -0.35199642, 0.2313174, -0.58278424, -0.08641501, 0.34744838, 0.34512728, 0.500954, -0.7685111, 0.46870387, -0.10193086, 1.6084917, -0.03636925, 1.4086537, -0.063865475, -0.0015128739, 0.92001283, -0.38939625, 0.45528454, 0.31051323, 0.1577892, -0.5681765, 0.7005183, -0.5051335, -0.34040785, -0.28615594, 0.8032139, -0.46363586, 0.21622391, -1.2667955, -0.29988098, -0.81864244, -0.8201505, -1.1678752, 0.75056106, 0.098227546, -0.010810759, -0.014191384, -0.42939845, 3.9035187, 0.15681595, 0.2582419, 0.4887771, 0.1525703, -0.02428957, 0.66500604, -0.5359085, 0.22960104, -0.7852579, 0.15039048, 0.06367845, 0.3528753, 0.9337709, -0.20073745, 1.0146337, -1.0692636, -0.24778748, 0.23142752, -0.14437445, -1.2041767, 0.28693214, 0.37165838, -0.035585634, 0.52149665, -0.11201562, 0.60554165, -1.043031, 0.06837402, -0.4101506, 0.8253852, 0.12620798, 0.22745697, -0.13505921, -0.45202237, 1.1835434, 0.25073954, 0.1395775, 0.10847205, 0.25401965, -0.37892976, -0.6354462, 0.36379182, 0.1980045, 0.09259137, 0.7982754, -1.1515712, -0.24035174, 0.6636571, -0.15318638, 0.58441776, -0.48915377, 0.5170015, -0.2060879, -0.7129818, -0.1414245, -0.43068886, 0.18446523, -0.9598793, -0.2197116, -0.19919111, 0.12266955, -0.10918245, 0.35740358, -0.3485523, -0.22071102, 0.5921739, 0.5802294, -0.22553721, -0.7331374, -0.5409138, 0.4591624, -0.25060326, -0.6027513, 0.1528463, 1.0014454, -0.9771162, 0.30428672, -0.31012374, -0.36872467, -0.45164657, 0.3022587, -0.3332075, -0.05958897, 0.5864512, 0.29134268, -0.2936555, 0.14974032, -0.21069044, -0.21046856, 1.0327365, 0.87497103, -0.29114136, -0.12409274, 0.30638078, -0.008108355, -0.074863106, 0.1823267, -0.92456347, -1.2252402, 0.023988292, 0.29588172, 0.28956586, 0.92870545, 0.6245167, -0.17748761, 0.49881747, -0.0013700202, -0.6062493, -0.5211433, -0.044155214, -0.58735853, -0.3184926, -1.1066936, 0.31925192, 0.055742487, -0.11290029, -1.2357664, -0.013144705, -0.5662862, 0.06639056, 0.35374135, 0.38557136, 0.20628467, 0.5110246, -0.42163143, 0.12925106, -0.24695382, -1.1608903, -0.15010446, -0.3606254, 1.2112582, -0.5199689, -0.24509984, -0.57505196, 0.06266602, -0.05476774, 0.5543311, -0.6631306, -0.90839344, 0.056663997, 0.39264026, 0.006514296, -0.03379453, -0.06360012, 0.2962194, 0.43456346, 0.29512823, 0.15175281, 0.034137387, -0.15923557, -0.86211294, 0.07326408, -0.80600816, 0.67977273, 0.49671376, 0.6821382, 0.27394387, -1.536363, 0.57825166, 0.7842151, 0.2394658, 0.09236379, 0.6696022, 0.22107342, -0.5844541, 0.68800783, 0.35063517, -0.7489135, -0.84657335, 0.13539974, 0.011126772, 0.83486915, -0.3726464, 0.38500214, 0.15931323, 0.24204169, 0.31334576, -0.38999516, -1.0564649, -0.8066621, 0.32243422, 0.08050046, -0.100161314, 0.1417718, 0.26810834, 0.27799317, -0.24338469, -0.1273042, 0.47630495, 0.761901, -0.31447634, 0.0041330475, -0.6132874, -0.35413107, 0.50921535, 0.92908055, -0.7377505, 0.17884433, -0.97206813, -0.31223825, -1.1257086, 0.054560035, -0.5985438, -0.5419079, 0.34310243, 1.1592656, 0.12414108, 0.6306039, -0.29405472, 0.36001867, -0.26069996, 0.6843612, -0.69717747, -0.25637287, 0.7413816, -0.09426433, 0.007948817, -0.05839423, -0.37699413, -0.54838955, -0.5196219, 0.7450251, 0.5604553, -0.19528422, 0.153679, -0.037510846, 0.21829069, 0.63829726, -0.11303048, 0.0413495, 0.42149734, 0.5452131, 0.12912615, -0.9724758, 0.47631884, -0.11178413, -0.78062665, 1.6786276, 0.88644165, 0.25348303, -0.57685983, -0.10731165, -0.6602384, 0.66389215, -0.7689, 0.1496639, 0.6415253, 0.500464, -0.24878055, -0.07939838, 0.13462633, 0.013040431, 0.73763734, 0.06980479, -0.18928413, 0.6980672, -0.33711007, 0.115530476, -0.61564434, 0.2487322, -0.04897301, 0.13430814, -0.2164018, -0.3666767, -0.095899746, -0.44386792, -0.17055167, -0.036105186, 0.43075958, 0.534845, 0.17878997, 0.06367618, -0.05834858, -0.2430348, -0.6089918, -0.047322188, 0.080885276, 0.5262991, -0.21075973, 0.10692868, 0.13799505, 0.08237328, -0.60258526, -0.51029414, 0.716713, 0.27913976, -1.1312143, 0.69941586, 0.08650997, 0.6624551, -0.70263344, 1.0370399, -0.4800526, -1.3264769, -0.5724056, 0.48490354, -0.36758322, 0.14180458, 1.0191479, -0.16142865, -0.15934804, -0.06126994, -0.12419982, -0.2052495, 0.46710333, 0.25446153, -0.09749228, 0.2416552, 0.13107337, -0.62425584, -0.4665196, 0.41823313, 0.017742202, -0.11604845, -0.014583001, -0.04743681, 0.48962507, 0.5726147, -0.15344103, -0.043124318, -0.4611046, 0.5476682, -0.6814534, -0.13700399, -0.25768772, 0.47459337, -0.5468129, 0.964742, 0.26113805, 0.29224998, 0.69866586, 0.5390306, 0.23548684, 0.5616739, -0.4996161, -0.0531639, 0.15483534, 0.3004987, -0.15385841, -0.6523655, 0.52095807, -0.61126125, 0.29399925, 0.022592522, 0.0036164224, 0.9010767, 0.66380125, 0.22740883, -0.8602492, 0.067954, 0.3547017, 0.4408105, -0.13458662, -0.23914078, 0.20854351, 0.24268481, 0.46751034, 0.36705163, 0.043406673, 0.036361203, 0.05552602, -0.071449906, 0.041502196, -1.2105745, -0.028304726, -0.039797705, -0.66858214, -0.088372126, -0.5237669, 0.16090764, -0.04407379, -0.6910071, 0.054006502, -0.28989974, -0.24306267, -0.61034966, 0.5553436, 0.6809772, 0.096716136, -0.51710796, -0.098939195, -0.3180539, -0.32514825, 0.38779578, -0.7734561, 0.15372227, 0.087640285, -0.4327031, 0.096745, -0.06493625, 0.029305357, 1.0426801, 0.116323724, -0.46691078, 0.011199217, 0.1469512, -0.108034305, -0.24094029, -1.0067587, 0.86667746, 0.681321, -0.34006357, 0.6885098, 0.21300186, -0.55701715, 0.582534, 0.26671684, -0.28656054, -0.7581177, 0.83850646, 0.6659291, 0.63540286, -0.82415324, -0.76791, -0.42685413, -0.1978186, 0.1188646, -0.35998422, -0.4153101, 0.63527155, 0.012389898, -1.5216818, 0.10454872, -0.15033387, -1.1138442, -0.363461, -0.31349632, 0.73108214, -0.13952224, -0.29330423, -0.40340406, 0.19570658, -0.13253699, -0.15259932, 0.8772184, -0.6289534, 0.24124396, 0.8863129, 0.013752261, 0.11636713, -0.2878188, -0.6748302, 0.26673093, 0.074429825, 0.18423261, 0.33583167, -0.31168482, 0.18303514, -0.110326886, 1.0521882, -0.8914687, -0.041218713, 0.7925176, -0.38259062, 0.0699002, 0.39020306, 0.3406126, -0.025504138, 0.030163972, -0.8205811, 0.27958557, 0.42331424, 0.7152617, -0.5693195, 0.79709387, -0.052060973, -0.2502512, -0.5891158, 0.43469584, -0.41373527, 0.6146908, 0.076879665, 0.31544682, -0.5227765, 0.08362824, -0.23998299, -0.06326865, 0.977748, 0.699623, 0.34662923, 0.4053547, -0.57229793, -0.360397, -0.68081236, -0.89546853, -0.38550287, 1.4982802, 0.1295377, 0.03139779, -1.4845395, 0.6942864, 0.52807, 0.8333225, 0.49081743, -0.3854397, -0.5561076, -0.2873355, 0.35955435, -0.40604037, 0.3067069, -0.9793556, 0.54424125, 0.05487563, -0.17266905, -1.1705602, 0.23105747, -0.096690014, 0.66326594, 0.50486475, -0.104512066, -0.17203951, 0.84721786, 0.010612169, -0.2766949, -0.7051157, -0.4017008, -0.63575864, 0.06809341, 0.36169913, -0.83321065, -0.3977779, -0.75799507, 0.45688114, 0.8228988, 0.3614043, -0.3872057, -0.23848563, -0.2693749, -0.90534234, 0.062407956, 0.79575527, -0.28577504, 0.11576642, -0.85940045, -0.2364341, 0.09936187, -0.6178453, -0.2623395, 0.4881133, -0.96528625, -0.002703242, 0.32168373, 0.23600036, -0.5019947, 0.62138635, -1.4865868, -0.15790486, -0.6669983, 0.06801675, -0.5628619, -0.31371945, 0.6114257, 0.96458405, -0.064005196, -0.219717, -0.09132044, 0.547687, -0.633611, -0.21194346, 0.5262808, -0.2213456, -0.47458994, 0.39729577, -0.15099177, -0.43005282, 0.53780806, 0.54377115, -0.124503836, -0.3869376, -0.4276981, -0.017099984, 0.10659635, 0.023432303, -0.023488503, -0.5943924, 0.44783092, 0.21988973, -0.2587016, 0.054121852, -0.98205125, 0.66049236, -0.1100941, 0.40253222, 0.4989391, 0.18264665, 0.024417441, -0.1577205, -0.33052993, -0.40380287, -0.3190465, -0.432463, -0.36828405, -0.5821203, -0.027871974, 0.3407156, -1.0126361, -0.44199046, -0.089746, 0.19934487, 0.24793631, 0.07480049, 0.3483074, -0.468999, 0.49423718, -0.024303712, 0.7697083, -0.5001096, 0.02921876, -0.2797136, 0.5004291, -0.19378904, 0.33850992, -0.5845366, 0.54080933, -0.4231968, -0.8276037, -0.21587685, 0.4471876, 0.17945103, 0.8905926, 0.45168063, 0.120928615, -0.19128208, -0.9465436, -0.4261623, -0.56029624, -0.15703607, -0.70728654, -0.37483913, 0.49776262, 0.25170207, 0.12126787, -1.2433228, 0.06759076, -0.42357254, 0.37723503, -0.37966526, 0.16530818, -0.6875407, 0.6304193, -1.0195813, 1.1075277, -0.78990626, 0.39701256, 0.0069374703, 0.7567582, -0.09521173, 0.67897403, -0.46449107, -0.7232551, 0.6319999, 0.13682938, 0.38638604, 0.4707066, -0.36580908, 0.2677807, 0.34033567, -0.1596111, -0.9749413, -0.37226206, -0.6223806, 0.2617854, 0.103502214, -0.008744709, 0.051227644, 0.351737, 1.1481045, 0.14042997, -0.5311719, -0.49255943, -0.8199234, -0.64042944, -0.21486312, 0.6096419, -0.52185607, -0.2824444, -0.79940456, 0.1712943, 0.4599559, -0.08197235, 0.35854346, 1.6623292, 0.45101458, -0.066510625, -1.0427458, 0.62489176, -0.22252423, -0.5163516, 0.07532082, 0.13290837, 0.13375865, -0.16612516, -0.15780056, -0.94008225, -0.29751578, -0.57456505, 1.1763555, -0.05414252, 0.37103045, 0.19796538, -0.43615937, -0.68003327, 0.3122042, 1.2015585, -0.24554463, 0.8153871, 0.7607808, 0.059229776, 1.3229659, -0.24295142, 0.17053288, 0.048269182, 0.9410707, 0.9070906, 0.06965003, 0.27366185, 0.8945579, -1.2575924, -1.2471954, -0.5133816, -0.03719949, -0.040453598, -0.6262046, -0.22496824, -0.5460526, -0.6761229, 0.38598374, 0.30903018, 0.3048585, 0.05681765, 1.035404, 0.3265798, -0.65159935, 0.012538631, 1.1262999, -0.5801894, 0.6140626, 0.030489383, -0.20633727, -0.091095164, 0.07008093, 0.20600188, 0.42286634, 0.24940234, 0.336841, -0.28344682, 0.15419483, -0.45846593, -0.2657172, 0.30148643, -0.9636932, -0.83163893, -0.15322179, -0.083657995, -0.24991873, 0.2650725, -0.21684909, 0.45393792, 0.2698332, 0.0074559078, 0.4958383, -0.61557376, -0.25072846, -1.2557454, -0.6115327, -0.24550119, -0.04877276, 0.06557663, 0.3164962, 0.2010736, 0.20483038, 0.098864615, 0.4129772, 0.24178419, 0.45724168, -0.4674123, 0.8200659, -0.50947297, -0.449177, -0.30873096, -0.00341261, -0.05515168, -0.5907586, -0.33790907, -0.651591, 0.40981805, 0.7774349, -0.11609654, 0.120979905, -0.17329918, -0.36349046, 0.5757807, -0.30231762, 0.16941534, 0.18787259, 0.016418763, -0.9578842, -0.080765896, -0.023937378, 0.13233513, -0.6668092, -0.18915473, 0.6900721, -0.81779176, -0.3249238, -0.19014584, -0.26334095, -0.9522248, -0.020303745, -0.1590526, 0.45100468, 0.30653527, 0.19623548, 0.3372883, 0.4808515, 0.053027716, 0.039079703, 0.063242614, 0.1595489, 0.36108032, -0.06620808, -0.37538713, 0.023618475, 0.01085633, 0.69008404, 0.27196503, -0.04092282, -0.2127317, 0.2757614, -0.30057618, 0.18570052, -0.19186738, 0.3087836, -0.25180426, 0.26582882, 0.4608781, -0.21650104, 0.2283323, -0.31646472, -0.692105, 1.3698722, -1.257715, -0.45968327, 0.08766882, -0.62902015, 0.52597046, -0.24926928, -0.85368836, 0.53539294, 0.18897045, -0.8144592, -0.24593538, 0.45442003, 0.43394864, -0.021025106, -0.56448966, -0.48068237, 0.57226974, -0.1455751, 0.3920177, -0.805578, -0.3599915, 0.36887014, 0.40636414, -0.38607797, 0.25946122, -0.5041137, -0.7237108, 0.20406774, 0.26659763, 0.50632215, -1.1882919, 0.31482235, -0.16788547, 1.0427362, -0.30384532, 0.25440946, 0.36111465, -0.04078348, -0.08545423, 0.92903745, 0.4287195, 0.38892937, 0.6466388, 0.011067346, 0.10231955, 0.72308904, -0.13572344, -0.31354204, 0.68488604, 0.4170978, 0.42884508, 0.10300704, 0.7566359, 0.17373186, -0.41658837, -0.43844083, -0.086458325, 0.52654135, -0.043467827, 0.6249003, -0.25258037, -0.729916, 0.6514588, -0.21865344, 0.05354707, -0.038330674, -1.0014257, -0.64724433, -0.36293414, 1.4632056, 0.2517041, 0.034037836, 0.24289103, 0.09087169, 0.8479298, 0.55847895, -0.71819776, 0.22156405, 0.59628755, 0.092399985, -0.04420072, -0.3075664, 0.30672166, -0.07358368, -0.9896834, -0.030702464, 0.45216998, 0.23109157, -0.3755612, 0.16779788, -0.6244628, 0.7411318, 0.24217345, 0.17737857, 0.48295784, -0.8859237, -0.24001184, -0.75387233, 0.67960876, -0.83024853, -0.14399245, 0.8452935, -0.3518325, -0.047979936, -0.02630499, 0.5509351, 0.4625635, -0.16918442, 0.30742225, 0.16386184, 0.67220664, 0.6280037, 0.28628358, 0.5660928, -0.1181638, -0.7434205, 0.20981479, 0.30287597, -0.69003713, 0.2184324, -0.76819944, -0.6346251, -0.08185301, 0.4818785, -0.51540446, -0.41744098, -0.09777721, -0.13589545, -0.60600513, 0.5247147, 0.3843186, 0.7094564, -0.16184524, -0.10725272, -0.4548275, 0.19113028, -0.047529392, -1.2795435, 0.17554286, -0.11416066, 0.13803561, -0.15642008, -0.6183412, -0.09616114, -0.37894952, 0.41909993, -0.662439, -0.114946306, 0.24334419, 0.22668067, 0.12224765, -0.63632286, 0.09084573, -0.23651299, 1.572324, 0.2178188, 1.1743072, 0.07571864, -0.1768858, 0.46413594, -0.48011255, 0.60569423, 0.15971124, 0.15805168, -0.9414262, 0.52399147, -0.007178193, -0.5215467, -0.59056896, 0.8559839, -0.2467039, -0.12033293, -0.9019515, -0.59779, -0.7349234, -0.8292922, -0.8635217, 0.5185263, -0.14540526, -0.26934415, 0.09875953, -1.1647751, 4.1182427, 0.46481997, 0.20087855, 0.9354643, 0.105424814, -0.004540026, 0.31147802, -0.6534193, 0.49501762, -0.45092684, 0.26379517, 0.448524, 0.34865677, 0.33569512, -0.016880259, 0.931842, -1.0148392, 0.20927775, 0.27847856, 0.15899846, -1.0693281, 0.1423664, 0.25981626, -0.025161192, 0.37412122, -0.29079884, 0.65601414, -1.0225062, -0.09605144, -0.14980899, 1.4953828, -0.1718415, 0.4066242, -0.08655246, -0.24063088, 1.2393714, 0.30284256, 0.36995012, 0.13408722, 0.30496278, -0.46151608, -0.6467823, 0.6863592, 0.3977234, 0.24254265, 0.30088937, -0.91632855, 0.22041345, 0.21627867, 0.036953487, 0.8198882, -0.38644162, 0.5111023, -0.6528836, -0.05132746, -0.048061155, -0.6670724, 0.32652795, -0.93728834, 0.17837188, -0.07624923, 0.18451518, -0.23230648, 0.34793568, -0.30258647, 0.12964638, 0.51428103, 0.8286943, -0.33250588, -0.6536644, -0.5854663, 0.42078778, 0.0033747032, -1.1266797, 0.10867215, 0.7423345, -0.83774376, 0.77926403, -0.058730222, -0.47217268, -0.092801005, 0.33792138, -0.05150798, -0.31443495, 0.27053922, 0.27824974, -0.11275067, -0.09057309, -0.2926527, 0.06173639, 1.3071758, 0.4730829, -0.14173776, -0.5784081, 0.2668654, 0.23815082, 0.28242433, 0.4774975, -0.54650855, -1.0264833, -0.47225332, 0.8703695, 0.63991624, 0.74452734, 0.42014164, -0.03533741, 0.06514102, -0.09643583, -0.8522862, -1.026076, 0.2499778, -0.42779097, -0.22190364, -0.076258555, 0.44808066, -0.71214545, -0.33959672, -1.3720645, 0.32767367, -0.713407, 0.7200092, 0.54970694, 0.038314663, 0.31601653, 0.82536983, -0.3402146, -0.15020594, -0.38107064, -1.594133, -0.20284157, -0.5158298, 1.4197085, -0.8124861, -0.42961958, -0.9616828, -0.31844, 0.09133983, 0.83976585, -0.69099605, -0.7764937, -0.5044535, -0.021224841, -1.0946624, 0.061164968, -0.008315772, -0.09962118, 0.7529673, 0.13280208, 0.32369834, -0.018207334, 0.30298617, -1.3468391, -0.010767452, -1.2652732, 0.3044045, 0.6346315, 0.41673356, 0.3533945, -1.4007373, 0.73925, 0.4769547, 0.45146942, -0.17096666, 0.53908443, 0.1459171, -0.5496129, 0.8112877, 0.22813308, -0.86315006, -1.0600767, 0.49666116, 0.6343291, 0.9384711, -0.67448175, 0.65366536, 0.12925006, 0.32494718, 0.7210598, -0.119817495, -1.8780767, -1.1060218, 0.26940116, 0.8603358, -0.37159148, 0.22237892, -0.026965573, 1.4551806, -0.04102008, 0.18953791, 1.2205132, 1.3830074, -0.6203029, 0.105550446, -0.9172137, -0.2631466, 1.2078451, 1.1561841, -0.88699704, 0.33485472, -1.1039261, -0.15662864, -0.8889108, -0.021704465, -0.7190207, -0.4444397, -0.09743556, 1.0252041, 0.27867004, 0.47697592, -0.25137198, 0.8654594, -0.5946547, 1.1985759, -0.7184543, -0.37799215, 0.8081364, 0.13715135, 0.03568732, -0.6331051, -0.65091616, -0.63724107, -1.1073422, 0.83576024, 0.01433241, -0.25773996, 0.19880387, 0.26008373, 0.12768374, 1.1019219, -0.48458183, 0.046535883, -0.06099293, 0.5994473, 0.82844126, -1.4832599, 0.76427746, 0.2744197, -0.63113993, 3.4523046, 1.0266101, 0.27708215, -0.41686982, -0.5191848, -0.06873581, 1.3051794, -1.1570866, -0.13528334, 0.36869058, 1.023516, -0.06851939, -0.42901027, -0.061269097, 0.34303978, 0.78846973, -0.10224266, -0.26698807, 0.36766642, -0.052483615, 0.30429786, -0.5263308, 0.8598371, -0.22671875, 0.18051147, -0.08662229, -0.3279599, 0.2018461, -0.6478263, -0.17370462, 0.13946049, 0.68857074, 0.7604215, 0.66072303, -0.2236945, 0.0344449, 0.39498496, -0.86348784, 0.2021577, -0.554239, 1.241565, -0.19903407, 0.096936144, 0.6406258, -0.34654585, -0.73143643, -0.13212292, 0.64585644, 0.20416865, -1.3674644, 0.81159735, -0.53180194, 0.44403616, -0.4629941, 0.8237217, -0.6575767, -1.9094594, -1.0068313, 0.1886729, -0.54099613, -0.31080106, 0.52114534, -0.4064729, -0.3517636, 0.52113307, -0.37713295, -0.54287195, 0.90217155, 0.75736386, -0.057880785, 0.65335006, 0.5185984, -0.6316754, -1.008395, 0.5784696, 0.15871945, -0.096895896, 0.030775126, 0.019246973, 0.635904, 0.7580727, 0.603296, -0.39326644, -0.775648, 0.6632834, -0.76522464, -0.15057506, 0.13213232, 0.8701612, -0.051690824, 0.886158, 0.059451666, 0.39455524, 1.1942627, 0.80077326, 0.30792174, 0.72980845, -0.58946186, 0.11602919, 0.6559696, 0.8268997, -0.20558739, -0.9376819, 0.4666886, -0.6281039, 0.45548218, 0.08520936, 0.19750595, 1.5127107, 0.83545053, 0.3510535, -0.8958543, -0.75617564, 0.894642, 1.4720694, -0.1355076, -0.6986217, 0.29143137, 0.34363377, 0.18577126, 0.26836568, -0.13981187, 0.19420178, -0.1310125, 0.106808856, -0.11584908, -1.3767927, -0.048521705, -0.12314682, -0.70627797, 0.10515572, -0.5317391, 0.5002598, 0.422907, -1.0648339, -0.11869705, -0.93817717, -0.47067133, -1.0766637, 0.7890926, 1.0871282, 0.077466965, -0.022941213, -0.34052557, -0.46262902, -0.21314916, 0.63874835, -0.8034802, -0.12524417, -0.2280509, -0.45375586, 0.11442453, 0.17320183, -0.16676669, 1.2585441, -0.26324847, -1.0815029, 0.48728508, 0.40939358, -0.2852892, -0.01987523, -1.0332665, 1.4922973, 1.2905895, -0.3012445, 1.1206418, 0.58634394, -0.5885947, 1.027236, 0.5461434, -0.56589985, -2.160386, 0.9977782, 1.4122514, 0.35012767, -0.8348484, -0.91156083, -0.44733608, 0.06918893, 0.073672324, -0.49986246, -0.36920917, 1.2300003, -0.028686464, -1.9602597, 0.3586868, -0.5751905, -1.2226559, -0.160415, -0.45962837, 0.7730631, 0.15213728, -0.40129295, -0.3763386, 0.25027445, -0.017731309, -0.35444453, 1.0308242, -0.68111396, 0.027753418, 1.1759561, 0.1284143, -0.1538926, -0.06069766, -0.5967487, -0.46134785, 0.65801346, 0.38983122, -0.13866639, -0.1946084, 0.39163414, -0.05783741, 1.3692302, -1.1921241, 0.12407765, 0.62342554, -0.22950053, -0.15749526, 0.42076403, -0.15916803, -0.6903404, 0.38964617, -0.96953917, 0.1617446, 0.15616782, 0.94165206, -0.7990292, 1.0704751, -0.3479437, 0.014394938, -0.27818298, -0.2686414, -0.8608855, 1.1030215, 0.30865127, 0.56293905, -0.5808595, -0.09553954, -0.5470532, -0.24101052, 1.7932336, 0.5933583, 0.22850809, 0.6440879, -0.13777807, -0.40607083, -0.14935976, -1.0655402, -0.08556904, 1.5463837, -0.2037431, -0.049918488, -1.948359, 1.3937284, 0.8913616, 0.6618716, 0.29112825, -0.9333397, -0.64939773, -0.1519076, 0.43093035, -0.90897346, 0.23105648, -1.6697718, 0.80526376, -0.10556382, -0.29879344, -1.1856492, -0.08865876, -0.3910298, 0.99155366, 0.05003587, -0.25817716, -0.203244, 1.0919954, 0.43314368, -0.36503968, -1.4359604, -0.27645838, -0.82746905, 0.27085295, 0.6530822, -1.179947, -0.5469275, -0.8221712, 0.4316565, 0.8877416, -0.22656713, -0.9242201, -0.30603468, -0.2247964, -0.8370084, -0.35373253, 0.91914237, -0.030093975, 0.6547502, -1.4251751, -0.17141008, -0.10287389, -0.16700989, -0.17503524, 0.30245206, -0.10866988, 0.11191217, 0.87262994, -0.3063119, -0.8902056, 0.56295437, -1.9272543, -0.0981302, -0.67028433, 0.23364708, -0.6498273, -0.37664372, 0.23457718, 1.4059585, -0.1313058, -0.30622694, -0.021324791, 0.7439346, -1.2513928, -0.34206432, 1.3767378, -0.2954388, -0.5523714, 0.60395724, -0.29732507, -0.2831665, 0.24392214, 0.5988505, 0.0795792, -0.29516765, -0.25286347, 0.10891355, -0.043641455, -0.21956724, -0.1222059, -0.90728974, 0.46377242, 0.49633765, -0.20564441, -0.520319, -1.6375936, -0.0139881335, -0.4310044, 0.5800617, 0.28061712, 0.47284612, -0.07800144, -0.51974624, -0.5967198, -0.2567559, -0.40850466, -0.36360377, -0.61648047, -0.5654142, 0.48337257, 0.21692866, -1.1690227, -0.53939724, 0.2567819, 0.52827764, -0.27963173, -0.038007528, 0.5720037, -0.8600977, 0.13065897, 0.19105779, 0.9926014, -0.50321037, -0.4309987, 0.19077024, 0.7039192, -0.09141481, 0.84667844, -0.77341396, 0.5661096, 0.15038273, -1.0883207, -0.30914208, 0.39496368, -0.06485534, 1.641904, 0.6762734, -0.3347199, -0.8617406, -0.6995804, -0.19845611, -0.5784028, -0.47562283, -1.4047565, -1.0122284, 1.0451913, 0.3910407, 0.21691439, -0.5442791, 0.3343481, -0.33234861, 0.66286534, -0.6073909, -0.23710439, -0.8782153, 0.6301357, -0.78039706, 1.0811063, -0.94600165, 0.50099385, -0.20203432, 0.8153803, 0.4326697, 0.9829363, -1.1359497, -0.5724925, 0.46652472, 0.020673493, 0.17816944, 0.64396065, -0.95867497, 0.8279188, -0.80351615, -0.085244454, -1.0182021, -0.48280728, -0.68415624, 0.26940063, 0.17725682, 0.6659137, 0.343051, -0.036139507, 1.9253529, 0.330179, -0.18667798, -0.7256044, -0.5135883, -0.6487113, -0.8936575, 0.7452832, -0.12287533, -0.11825, -0.70136374, 0.14688696, 1.4273101, -0.15633577, 0.6255618, 2.1027944, 0.8671121, -0.36143222, -1.1867063, 1.1065185, 0.8098748, -0.45667458, -0.24226767, 0.0025809854, -0.25722653, 0.19070284, -0.5484266, -0.6555022, -1.0337746, -0.42591894, 1.7423811, 0.654865, 0.64011616, 0.16377617, -1.2083119, -1.4860584, 0.70743257, 1.1795193, 0.07058562, 0.8440395, 1.0345922, 0.28286603, 1.0439405, -0.31949413, 0.6272188, -0.19404978, 1.5465806, 0.8578423, -0.27853975, 0.66072625, 1.2355281, -2.0446782, -1.7492697, 0.0030216204, -0.56266546, -0.6697648, -0.68279344, -0.35443568, -0.54446316, -0.6759806, 0.1435076, 0.28134957, -0.15788919, 0.24428463, 0.014099263, 0.46920812, -0.85195917, 0.0012707915, 1.3709744, -1.0901219, 0.64788854, -0.14823869, -0.085778356, 0.13496846, -0.24483931, 0.4524359, -0.034560725, 0.63981885, 0.35658672, -0.30224392, 1.0347067, -0.85791016, -0.14240645, 0.79247826, -1.1686097, -1.586391, -0.8209819, -0.119535595, -0.2052218, 0.34335265, -0.6570797, -0.2210782, 0.6748208, -0.09502657, 0.24686556, -1.2017366, -0.63983685, -1.5916613, -1.184105, -0.123895474, -0.03346053, 0.2209342, 0.61311907, 0.3206372, -0.118494704, -0.3988993, 0.3909913, -0.36862627, 0.5302286, -0.6324911, 0.94080716, -0.6024734, -0.38162777, -0.4316226, -0.3143518, -0.36463666, -0.20017555, -0.8736055, -0.9380112, 0.45671174, 1.5155923, -0.09486201, 0.9695505, -0.13833332, -0.6298378, 0.8931586, -0.6301222, -0.26646182, 0.46902105, 0.13617973, -1.3055613, 0.30406374, -0.09564643, 0.10455055, -1.0269212, 0.12177908, 1.1355569, -0.6378392, -0.6559861, -0.78072715, -0.68091595, -1.3237638, -0.4806199, -0.16236575, 0.22558266, 0.4245454, 0.6258281, 0.2573674, 0.92344415, 0.108896874, 0.4044994, 0.06719699, 0.66419035, 0.34098536, 0.58486176, -0.41998512, 0.5359888, 0.61129946, 0.5190456, 0.983025, 0.310331, -0.32300448, 0.35044804, -0.97328913, -0.06142584, -0.34457424, 0.42320502, -0.2103809, 0.94158864, 0.751986, -0.41664547, 0.5273929, -0.023898497, -0.58526397, 0.91506046, -1.587615, -0.62792873, 0.20285669, -1.3050082, 0.62498814, -0.4249226, -1.0144218, 0.409593, 0.27104688, -0.9462727, -0.24467865, 0.86334205, 0.45995265, -0.12513909, -0.70971626, -0.19246241, 0.042387776, 0.07669194, 0.115074575, -1.269335, -0.09286548, 0.54315686, 0.34751275, 0.06670852, 0.14310578, 0.02031393, -1.4052739, 0.34125116, 0.34491134, 0.47022027, -0.80838424, 0.43571746, -0.5313221, 0.8576949, -0.2583056, -0.1817374, 0.4537858, -0.14710322, -0.4226152, 1.6146483, 0.88158476, -0.3151336, 1.2690797, 0.11899912, 0.3866578, 0.76637596, 1.5090572, -0.67779464, 0.9428768, 0.6889142, 0.6410521, 0.28004602, 0.7718466, 0.7421934, -0.28616107, -0.914406, 0.18280843, 0.77757883, -0.37666446, 0.607708, -0.28850508, -0.14639486, 1.0358485, -0.57612544, -0.03077536, -0.09469912, -0.5002359, -1.5291424, -0.5715195, 1.1232437, 0.032881796, 0.24273214, 0.114872776, 0.21159294, 0.86429787, 1.2115531, -0.53747576, 0.5324311, 1.046557, 0.3009321, 0.33693448, 0.033356756, 0.44364536, -0.02425829, -1.4809191, -0.15717486, 0.19116181, -0.09143227, -0.27159914, -0.10439899, -0.74533814, 0.82421553, -0.20139456, -0.0032766405, 0.9916576, -1.0329632, 0.19601333, -1.2602824, 0.2017543, -0.64100575, -0.35785395, 1.0780927, -0.14836146, 0.018262547, 0.9442348, 0.83696884, 0.6329565, -0.093982756, 0.7140547, 0.21587613, 1.2869248, 0.60281265, -0.47821552, 0.43734503, 0.25959963, -0.16328156, -0.12055825, 0.4622288, -0.9157813, 0.5098907, -0.31852883, -1.0538068, 0.63930315, 1.0165753, -0.8952555, -1.1551671, -0.07045259, 0.33253628, -1.4805075, 0.5346395, 0.40822038, 0.78947777, 0.056913875, -0.23994705, -0.47662988, 0.12904635, -0.3096597, -1.2386975, 0.027118616, -0.297474, -0.34640983, -0.7081305, -0.987574, -0.4112696, -0.16663915, -0.14638874, -1.0458425, 0.054047197, 0.99362266, 0.47721052, 0.39771488, -0.4090625, 0.1835733, 0.006618239, 1.8029044, -0.5752119, 1.7840273, 0.14250731, -0.8179414, 1.0404874, -0.7235668, 0.43460107, -0.17297104, -0.66153497, -0.53459716, 1.4169344, -0.25907004, -1.0876834, -0.121780336, 0.9376321, 0.087307006, 0.1502156, -1.3873982, -0.47126013, -0.72027636, -1.0648152, -1.0333831, 0.28081003, 0.0047804266, -0.41970125, 0.12368576, -1.0056207, 1.314159, 0.8322662, 0.50192, 0.6606601, 0.19176152, 0.22359805, 0.6299454, -0.8784206, 0.8435247, -0.62076545, 0.46503085, 0.4955411, 0.47523603, 0.59475726, -0.15033536, 1.5292126, -1.6526178, 0.77440363, 0.21343376, -0.1102623, -0.8003335, 0.12464988, 0.1694136, -0.092712775, 1.1573013, 0.26682746, 0.8170211, -1.0412548, 0.09060685, -0.18826349, 1.1423111, 0.03361123, 0.54229814, -0.31807727, -0.034259863, 1.3871967, -0.05026304, 0.28581905, 0.11886263, 0.7556672, 0.09417425, -1.0077528, 0.9749789, 0.031945437, 0.1542672, 0.44604713, -1.1202078, 0.24686609, 0.5521793, -0.26565984, 1.3768492, -0.41607288, 0.89860183, -0.9901299, -0.55397356, 0.3160442, -0.2748052, -0.028745566, -0.60326695, 0.1855664, 0.014004639, 0.043385062, -0.3658645, 0.21059687, -0.45689726, 0.2032052, 0.73326206, 0.35434416, 0.019100547, -1.4163734, -0.44338754, 0.26873967, -0.5155286, -1.3091766, 0.083646804, 1.3032191, -1.2324255, 0.9689458, -0.50306034, -0.13216153, -0.31209743, 0.42126146, 0.24715918, -0.36722437, 0.8198192, 0.7839475, -0.4742727, -0.23958692, -0.53167427, 0.36589828, 1.4970611, 1.1297909, -0.09345523, -0.7373089, -0.6823638] -2025-10-16 19:28:50 [main] INFO OnnxTest - ------------------------ -2025-10-16 19:28:50 [main] INFO OnnxTest - tokenizer加载耗时: 4073ms -2025-10-16 19:28:50 [main] INFO OnnxTest - tokenizer计算耗时: 1ms -2025-10-16 19:28:50 [main] INFO OnnxTest - 模型加载耗时: 558ms -2025-10-16 19:28:50 [main] INFO OnnxTest - 模型数据准备耗时: 2ms -2025-10-16 19:28:50 [main] INFO OnnxTest - 模型计算耗时: 11ms -2025-10-16 21:35:57 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 21:35:57 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 21:35:57 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 21:35:57 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 21:35:57 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 21:35:57 [main] INFO OnnxTest - [101, 3231, 1024, 7592, 2088, 102] -2025-10-16 21:35:57 [main] INFO OnnxTest - ----------------------------- -2025-10-16 21:35:57 [main] INFO OnnxTest - [1, 1, 1, 1, 1, 1] -2025-10-16 21:35:57 [main] INFO OnnxTest - ----------------------------- -2025-10-16 21:35:57 [main] INFO OnnxTest - 加载耗时: 4105ms -2025-10-16 21:35:57 [main] INFO OnnxTest - 计算耗时: 1ms -2025-10-16 21:36:08 [main] INFO ai.djl.util.Platform - Found matching platform from: jar:file:/home/slhaf/.m2/repository/ai/djl/huggingface/tokenizers/0.34.0/tokenizers-0.34.0.jar!/native/lib/tokenizers.properties -2025-10-16 21:36:08 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Using cache dir: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 21:36:08 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading huggingface library from: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64 -2025-10-16 21:36:08 [main] DEBUG a.d.h.tokenizers.jni.LibUtils - Loading native library: /home/slhaf/.djl.ai/tokenizers/0.21.0-0.34.0-cpu-linux-x86_64/libtokenizers.so -2025-10-16 21:36:08 [main] WARN a.d.h.t.HuggingFaceTokenizer - maxLength is not explicitly specified, use modelMaxLength: 512 -2025-10-16 21:36:09 [main] INFO OnnxTest - [0.008940695, 0.50210774, -5.0510945, -0.8937678, 0.8091147, 1.2654096, 1.2879646, -0.72453403, 0.46069813, -1.1958805, -0.038145, 1.8672976, 0.6281317, 1.7732, -0.52271223, -1.4445113, 1.5514337, -2.508686, -0.6864384, -0.6301254, -0.29560322, -1.0180707, -0.83187616, 0.46920234, 1.9916652, -0.35749114, -0.11190428, 2.2374659, -0.6664558, 0.1793392, 0.64779544, -0.111028045, 0.67277247, -0.9106091, 0.2552021, -0.21566938, 0.5772215, 1.3539819, 0.45714578, 0.17660096, 0.49979687, 1.1208547, 0.19748983, -0.71146816, 1.9074292, -0.11441079, -0.24318233, 0.61392385, 1.8441632, -1.3443937, -1.0027645, -0.9185232, 0.19459805, 0.22545397, 1.7715352, 1.353761, 0.21172398, -0.5133596, 0.8219211, 0.9679444, 0.5380537, 1.2222915, 0.1917364, 1.8536644, 0.85374683, -1.6372596, 0.1961565, 0.69616926, -0.24206743, 0.8010477, 1.3424035, -0.050939456, 0.8211133, -0.020956516, 0.26211494, -0.4410275, -1.1032287, 0.115168236, -0.37371528, 0.12982085, 1.0343108, -0.51043314, 0.9773637, 0.52081937, 1.8070213, -1.2970276, -0.36602047, -0.34678212, -1.5465903, 1.0458957, 1.1246372, -0.22684537, -0.33523685, 0.6524532, -0.4258627, 0.8639704, 0.6747687, 1.1801372, -0.18055356, -0.325558, 0.58573216, -0.6885681, -0.008652464, -0.35967788, 1.4759315, 0.79462963, -1.0071485, -0.13985354, -1.7917951, -1.302046, -0.9551339, 0.72700655, -0.82785696, -0.016509667, 0.2450114, -0.14989577, 0.66587335, -1.6692137, -0.10025135, 0.5849763, -0.0066149235, 0.15871382, -1.0094404, 0.57655615, 0.31472182, 0.98309034, -1.8285725, 0.3632993, 0.13209791, 0.5869235, 0.21235198, -0.17361814, -0.32928634, -0.4548379, -0.6051484, 0.4909709, 0.51352304, -0.25750488, 0.21058336, 0.23544005, -1.0283852, 0.61832947, 0.012845237, -0.0017602667, -0.11332193, -0.64147717, 1.3873081, -0.82721007, -0.48795754, 0.04623498, -0.32260513, -0.40278208, 1.4807189, 0.6844304, 0.5813694, -0.7781652, 0.504094, 0.51536506, 0.47406924, 0.9439167, 1.0232425, -0.6551769, -1.3913715, 0.56962323, -0.25564027, -2.001826, 1.0167072, 1.6333333, 0.9226843, 0.23638949, -1.0627227, -1.5849673, 0.53583235, -0.32994375, -1.4948924, -0.54732955, -0.6555769, -0.56513834, 0.56638885, 0.71271247, 1.1922938, -1.5763108, 0.5924969, 1.7915413, -0.6964754, -1.0084081, -0.08877027, -0.28982282, -0.020199053, -0.7514959, -0.24143167, -0.20266221, -2.3080733, -0.34911162, 0.002499245, -0.9315997, 0.14224178, 0.26388752, 0.55929285, -1.9308436, -0.7808089, 0.20109546, -0.50900704, -0.06720903, -0.57660383, -0.12015574, 0.8564407, -0.19855615, 0.5351314, 0.7831901, 2.2334285, -0.07724279, -0.8556066, -1.1182219, -0.10898359, -0.43939131, 0.18218377, -1.0329244, -0.28819674, 0.6573483, 0.94202, -0.5684383, 0.39345515, -0.2149513, 1.1943405, 0.2175886, -1.4272945, -0.15624487, -2.1790175, -0.31830606, -0.074882746, -2.1189816, 1.3915615, 0.53846455, -0.6594929, 1.1428193, 0.14244053, 1.4449791, -0.33742362, 0.1302906, -1.0304217, 1.0046071, -0.14830303, -0.2878356, -0.833144, 0.7353544, -0.047339574, -0.50411963, -0.14792854, 1.2162826, -0.87097895, 0.5479907, -0.61530846, 0.91772366, 0.39351106, -1.1159807, -0.6962802, 0.6177609, 0.28574178, -0.933717, 0.6656517, -2.550455, 0.28417572, -0.81885386, -0.57173115, -0.47732124, -0.83434474, 0.6218224, -0.23378877, -0.16290052, -0.33495492, 0.9589823, -0.13438444, 0.87317586, -0.7977557, -0.8751001, 0.121376105, 0.0016995966, 0.119280726, 0.8511828, -0.80091643, 0.21969834, -0.52506125, 0.21649529, 0.20917195, 0.53206205, -0.060215697, -0.92501277, -0.43172908, 0.1354983, 0.77811605, 0.6264411, 0.11004971, 1.4162332, 0.3008895, 0.6369807, 0.8966343, -0.46057636, -0.4627554, -0.99630976, 0.8575164, 0.45908165, 1.4463993, 0.24505532, -1.313617, -0.26200497, 1.4678717, -0.78108716, 1.5716724, 0.04318331, -1.4950266, 0.87165, -1.2442464, 0.40303344, -0.8583747, 1.123798, -0.27928567, 1.4853265, 0.8615038, -0.22005291, -0.19541085, -0.8011397, 0.6476904, -0.092515044, -0.34317318, -0.16905296, 1.1762776, 0.5573735, -0.59209, -0.3909012, 0.19253278, 1.5935065, -0.7802029, -0.72745705, -0.15390143, 0.9641196, -0.7650623, -0.5825169, -0.42223948, 1.2938359, 0.32511997, -0.48691022, 1.3244666, -0.9317738, 0.0053078495, -0.2814655, -0.010061342, 0.5678287, 0.53736544, 0.84125555, -1.6721346, 0.6866992, -1.039913, -0.55957854, 0.9752761, -0.10916731, 0.81267405, 0.3757345, 0.31622255, -0.070370235, -0.28069317, 0.7060322, -0.30573946, -1.1120561, 0.087441884, 2.1169686, 0.3793122, 0.7199018, 0.7972706, 0.6312716, -0.28640646, -0.24372002, -0.39927763, 1.3067431, 1.3677809, 0.17182645, -1.5993283, -1.0617065, -0.9970951, 0.3591527, -0.2642659, -0.92191654, 0.09367664, -0.8568419, 0.24673605, -0.01075469, 0.53148615, -0.8131387, 0.16646563, 0.4456662, 0.42658246, -0.2286683, -1.240861, 1.2182664, 0.31972283, -0.52042526, 1.0313315, -0.74151134, -1.9206606, 0.67172974, -0.76771915, -0.11668143, -0.16317451, -1.1896999, -0.14067993, -0.5754039, -1.178021, -0.19320671, 1.0556533, -0.13083985, 0.8500223, 0.7322127, 0.47325015, -1.1170738, -0.46539554, 0.60346323, 1.1163684, -0.6468576, -0.6749016, 0.32706273, 0.5102571, 1.538664, 0.2564993, 0.12480027, -0.5115198, -0.22911404, 1.2661121, 2.2754738, 0.054497525, -1.8307894, -0.70205, 0.2732521, 0.3695401, 0.8007306, -0.28857967, 0.38666317, -0.7592721, -0.5713192, 1.1246057, 0.593709, 0.35631394, -0.3205832, -1.4436417, -0.6496872, 0.37343976, 3.2232847, 1.9115183, -1.0618794, -0.96111053, -0.10857664, -1.103422, 0.9816166, 0.60177815, 0.8528089, 1.4430338, -1.370729, 1.3978995, -0.69921416, 0.23256098, 0.4660253, -0.06287591, 0.6654809, -0.69219005, 0.24058081, 0.93626904, -0.7160164, 0.42666763, -0.38045081, -0.17772737, 0.95297396, -0.7321556, -0.82016414, 1.6348257, 0.098678365, -1.8395785, 1.0368643, -0.04200262, 0.7008558, -0.6598028, 1.1169665, 0.59610337, 0.42644075, -0.70989525, -1.1907579, 0.4301988, 0.24375978, 0.12559327, -0.086863026, 0.6391059, 0.3239115, 0.18681988, -0.9638547, 0.6950969, -1.0718625, -0.35861596, 0.007594481, -0.50218886, -0.07959162, 0.3074152, -1.0058187, -0.5779988, -0.21252635, 0.16711673, 0.2945148, -0.9580504, -0.44329655, -0.080028936, -1.9545618, -0.7434137, 0.42564327, -1.1064954, -0.02137646, 0.33320808, 0.87851465, 1.3674957, -0.18974975, 0.30143118, 0.09378138, -2.184264, 1.4090663, 0.42376116, -0.6386673, 0.23209023, 0.93278, -0.9901231, 1.2871186, -0.55473083, -1.0378529, 1.2385598, 0.6200016, -0.19011533, 1.2526734, -0.29594705, -1.159091, 0.12753622, -1.3564175, 0.39733884, 0.35340226, 0.47517172, 0.5938189, -0.97271687, 0.72243273, -0.3874474, -0.8634288, 1.4369297, 0.76829016, -1.5096359, 0.67411625, -0.5942944, -0.68440664, -0.6967539, -1.3790333, -1.0722706, -0.26939258, -0.51274854, -1.6252055, -0.042074203, -0.2941991, -0.9963352, -1.6290406, 0.5964556, 0.61665666, 0.107714295, 0.638748, 0.4289012, -0.8213354, -0.18691581, 0.260664, 0.1988615, -0.67643714, -0.4602536, -1.04408, 0.47709525, -1.5441273, -1.09128, -0.2589167, 0.5129835, 0.35384816, -0.69535726, -0.5024993, 0.17009991, -0.9128699, 0.35023412, 1.5284145, 0.38180998, -0.36242324, 0.7157388, -0.5221178, -0.07077499, -0.80303806, -1.0217718, 0.014210036, 1.1169853, -0.84779525, 0.07265417, 1.5137844, -0.43872315, -3.6163976, -0.71127445, 0.030030718, -0.54634804, 0.6007818, 1.0862793, -1.4570272, 0.29859456, 1.6187196, -0.5408837, 0.7542678, -0.043661788, -0.627822, 0.9626751, -0.18183072, -0.40761006, 0.92285067, 0.4483496, -0.20151655, 2.1187465, -0.5030096, 0.042685598, -1.0087817, -0.27128118, -0.6693532, 0.90893507, -0.5863207, 1.1904533, -0.6463561, -0.9224859, -0.5095885, -0.6562933, 1.7482289, -1.0871308, 0.6194082, -2.2877498, -0.0012813509, -1.1376673, 0.87655807, 0.663956, 0.24306166, 0.22504678, 1.0432729, 0.7316973, -0.20957288, 0.21609576, -0.054103754, 1.2539151, -0.3260904, 1.4898258, 0.71351856, 1.469297, -0.25216702, 2.0916111, 1.6792994, 0.834613, -0.19511522, 0.97750825, -0.1270805, 0.66032535, -0.15046631, -0.99626607, -0.5324382, -0.228696, 0.26502895, -0.7099257, -0.24755025, 0.5434749, -0.4053922, -0.8309872, -0.2989617, -0.86280966, -0.9859461, 0.97572213, 1.3376713, -0.3430115, -0.43402225, -0.1924202, 0.6710346, 0.74688536, 0.68394524, -0.29258135, -0.63783354, -0.25838947, -0.7412832, -0.13756852, 0.29825956, 0.38041145, -1.1111758, 0.5355625, -1.0727328, -0.37962234, -0.90463316, -0.2698317, -0.1467724, 0.13004409, -1.0194534, 0.11609152, 0.4127395, 0.28521538, -0.6652327, -0.7038725, 0.7316348, -0.48964947, 0.87470716, 0.8198417, 0.8121711, -0.55107266, -1.7259613, -0.27550706, -0.29355648, -1.0490227, -0.021362338, 0.19700499, 2.365385, 0.531291, 1.4412646, 0.8194168, 1.334413, -0.21749905, -0.3275181, 0.5781112, 1.150555, 1.4283984, 0.10826522, -1.1658969, -0.45134637, 0.04636837, -0.83447146, 0.81878465, -0.20615144, 0.5333617, -0.60880643, -0.042713113, 0.42055398, -0.5879446, 1.5446286, -0.3906217, -0.014214683, -0.9320095, -1.0041155, -0.77032924, -0.8490772, -0.3068128, -0.3138222, 0.8429545, 0.7392214, 0.059413563, -0.84115446, -0.1827325, 1.2329874, 0.20420718, -0.7757152, -0.4077565, -1.1934249, -0.8312496, 0.06622116, 0.36520314, 1.3569491, 0.27295056, 0.3010164, 1.8382473, -0.42277017, 0.23495656, -0.21165037, 0.37068194, 0.53597724, -0.15588544, -1.2607875, -0.40104312, -0.50267667, -0.13610771, 0.08203963, -4.3039837, -0.082001, 0.4916641, 0.7460458, 1.3272368, -0.5917864, 0.93342024, -1.0633006, -0.22604129, 2.1822553, 0.77348, 1.2415451, -0.92593575, -1.6016923, 1.9382031, -2.2590072, -0.72137606, 0.14148775, 0.13457671, -0.7451491, -0.41633192, 0.572699, 0.20894296, -0.665532, 0.1557113, 1.8900913, -0.17060457, 0.14676529, 0.9459177, 0.1988962, 0.6571039, -1.2214427, 0.48302603, 0.07323967, 0.6089274, 1.5770257, 0.06876827, -0.2896797, 0.6952437, 1.5110533, 0.32220465, -0.6618951, 2.1899383, 0.23477301, -0.41625032, 0.94061273, 1.5684785, -1.8303659, -1.2356102, -0.8779911, 0.89357895, 0.91234356, 1.0632848, 0.9623276, 0.73280936, -0.81256485, 0.62779176, 1.1951995, 0.18735348, 0.48628578, 0.20784137, 1.6061101, 0.6428331, -1.8172319, 0.07742017, 0.76475334, -0.28695786, 0.69205785, 1.3851129, -0.3151007, 0.5124455, -0.4670857, 0.42660737, -0.27413413, -0.79418296, 0.38474238, 0.44336423, -0.70331454, 1.6133739, -0.79705983, 0.58497494, 0.7683212, 0.95143867, -1.2097393, -0.5542208, -1.401292, -1.7129737, 0.32851774, 1.7300217, -0.13283907, 0.7207998, 0.79250276, -0.5060547, 0.838996, 0.33558664, 1.3048035, -0.6595723, 0.01165621, 0.40351102, -0.29559255, -0.3484041, -0.40840417, 0.95276344, 1.3805048, -0.28706077, -0.14665662, -1.5373006, -1.6770992, -0.9637392, 1.0667742, -0.8824096, -0.10521127, -0.33972454, -0.15037933, 0.29304558, -0.7167169, -0.026037984, 0.45332485, -0.30548358, 0.67668605, -0.70388466, 0.9721674, 0.022312656, 0.67783666, -2.221327, 1.0432537, 0.10468251, 0.50377524, 0.5216907, -0.26383665, -0.5668552, -1.0790802, -0.66269624, 0.53420395, -0.056507684, -0.030799769, -0.38935354, -0.26135808, -0.51806945, 0.6764826, 0.21997608, -0.2842363, 0.4153023, -0.7909994, 1.2961726, -0.32138214, -0.21153454, -0.23352191, -0.78287107, -0.47774607, 1.6039003, 0.5824032, 0.2871944, -0.77046245, -0.3201174, 0.4231739, 0.8662363, 0.8589964, 0.5837137, -0.5550777, -0.73803765, 0.7114582, -0.15480545, -2.4421003, 1.2693365, 1.5083162, 0.57656115, 0.5589083, -1.294058, -0.7516413, 0.68240094, -0.6442521, -1.8912579, -0.76375854, -0.18127736, -0.8704367, 0.78815466, 0.58496165, 1.2333207, -0.67811775, 0.7778747, 1.180586, -0.52837384, -1.6866188, 0.43942052, -0.5797858, -0.12091714, -1.5169264, 0.05719204, -0.26951146, -2.684711, -1.0172228, -0.30936632, -1.1998694, 0.13886273, 0.036559507, 0.3245873, -1.6026664, -1.3267136, 0.5069053, -0.36913142, -0.5306911, -0.070908874, -0.18541811, 0.69640446, -0.30087128, 1.0078833, 0.610926, 1.7221036, -0.5379479, -1.326377, -0.52609026, -0.46600527, 0.06604308, 0.2197823, -0.9372009, -0.3256157, 0.14768064, 0.699552, -0.72368884, 0.4794218, 0.026545957, 1.3436007, 0.23628801, -1.5402796, 0.19139451, -1.8511007, -0.44703215, -0.08679469, -1.6827856, 0.8235698, 0.16579445, -0.074705936, 1.0817068, -0.01459034, 0.8199119, -0.80417913, 0.53254235, -1.08217, 0.9492825, 0.24019396, -0.44084668, -0.73341775, 0.9208635, 0.37783542, 0.29370502, 0.27790993, 0.90694183, -0.68210644, 0.35099593, -0.50210375, 0.40147668, 0.56336397, -0.8843219, 0.1813156, 0.60259986, 0.4996659, -1.2195214, -0.06456041, -2.0830536, 0.79561657, -0.33496487, -0.41333812, -0.60755616, -1.3942319, -0.023980334, -0.31574172, -0.47269264, -0.45879, 0.37798846, 0.464371, 1.1505239, -0.35299638, -0.66388196, -0.46442628, -0.0014668554, 0.4657766, 0.3824118, -1.0646446, 0.47359174, -0.5501442, 0.54858595, 0.3592662, 0.41308272, 0.45073894, -0.7594449, -0.33872837, 0.31371093, 0.55662763, -0.20230436, 0.4447407, 1.6444561, 0.22029482, 0.0872115, 0.6798017, -0.32205412, -0.2614859, -0.6706727, 0.35378987, 0.38164073, 1.367708, 0.43917412, -1.6509491, -0.29672295, 1.7558253, -1.3782254, 1.0295317, 0.6083522, -1.7402619, 0.5930131, -1.4394379, -0.3491493, -1.1771997, 0.78438175, 0.0027834475, 1.0757275, 1.8362582, -0.6623099, -0.061427217, -1.429398, 1.0720371, -0.023497377, -0.41509795, 0.07872723, 1.5710311, 0.3394337, -0.86737263, -0.8013209, 1.0093807, 1.9009106, -0.78051865, -0.23401639, 0.073471576, 1.342778, -0.8758744, -0.05092702, -1.0604082, 0.88840294, 0.4845464, -0.31408712, 0.7285716, -0.6598388, 0.26622984, -0.15347672, 0.34162325, 0.5272665, 0.15939362, 1.0359404, -1.3569661, 0.8223073, -0.82353425, -0.851304, 1.2659918, -0.31349543, 0.9090855, 0.25253433, 0.61904687, -0.13841742, -0.67474073, 1.0259502, -0.051506877, -1.1969513, 0.16987415, 0.073220626, 0.37979242, 0.7651893, 0.58660114, 0.7042103, -0.5287451, 0.29557738, 0.17244934, 1.4235036, 1.7157453, 0.37425035, -1.8584217, -1.2582158, -0.6299258, 0.17255291, -0.12686756, -0.49752375, -0.22709069, -0.6200077, 0.42430815, 0.463663, 0.68685627, -0.71040833, -0.17139806, 0.38501126, 0.5601121, 0.50367576, -1.6438738, 0.077835165, -0.36538386, -0.23477188, 1.2270359, -0.61405075, -1.7066628, 0.81988287, -0.7482188, 0.035242945, -0.14084256, -0.65183985, -0.019776158, 0.12996586, -0.9195582, -0.41340956, 0.90673864, -0.6422904, 1.2120672, 0.06385599, 0.63100183, -1.30815, -0.9428998, -0.41631383, 1.965007, -0.86749756, -0.5259007, 0.13663939, 0.3468347, 1.7422681, 0.7007072, -0.020115245, -0.31306064, -0.031459868, 1.0573552, 1.8225657, 0.11774525, -1.5830071, -0.79576176, 0.05965937, 0.6052492, 0.62318075, -0.096916795, 0.31733304, -0.96026015, -0.27850336, 1.4682877, 0.6666615, 0.24167539, -0.5812353, -0.90307945, -0.55028933, 0.5831116, 2.5405624, 2.0145776, -0.960979, -0.4206924, -0.7996599, -1.7888918, 0.5773138, 0.44929433, 0.79602045, 1.2793171, -1.1028179, 1.5785166, -0.6605679, 0.123961315, 1.0325454, -0.030368492, 0.14277515, -0.24839605, 0.22407623, 1.2428747, -0.8223916, 0.7238152, 0.5589315, -1.2599404, 0.36306778, -1.1173778, -0.8732166, 1.4703016, -0.23819679, -1.6242712, 0.7218292, 0.118932486, 0.7071069, 0.53992164, 0.44476104, 0.6507463, 0.5524653, -0.6212482, -0.8308021, 1.7792088, -0.4863599, 0.24588388, 0.48519036, 0.45862278, -0.23362559, 0.6741241, 0.8668838, 0.12244135, -0.6257747, -0.67283255, 0.028253525, -0.6896872, 1.181849, -0.4711876, -0.5782417, 1.0118928, -0.05969412, 0.14305171, -0.4259127, -0.61529285, 0.077514656, 0.85673195, -1.3015722, -0.7207134, -0.27778414, -1.125479, -0.49426728, 0.3936475, 0.8884816, 1.7654979, -0.45583653, -0.11059831, 0.2442121, -2.1273844, 1.4961429, 0.641687, -0.45369974, -0.54703337, 0.6895549, -0.6619705, 1.1465002, -1.1790969, -0.45576596, 1.6416053, 0.6164581, -0.15951222, 0.7921248, -0.032377556, -0.80429655, 0.08237736, -1.4837114, 0.1985715, 0.15340376, 0.801544, 0.078613624, -1.9629599, 0.88010734, -0.46030182, -0.64362615, 1.1952101, 0.32887614, -1.7267823, 0.93907595, 0.094770044, -0.9705627, -0.27643013, -2.292801, -1.2397184, -0.41275358, -0.80883455, -1.7987494, 0.2907484, -0.20178545, -0.87403935, -1.7124034, 0.85280275, 0.042721435, -0.78331816, 0.25862864, -0.045897268, -1.3428419, -0.41759884, 0.6986912, 0.29880998, -0.74742967, -0.5181912, -1.019665, 0.3793689, -1.7902851, -1.4508095, -0.32118288, 0.5071308, 0.7328687, -0.60655284, -0.15128464, 0.6374675, -1.0154953, 0.03218935, 1.279699, 0.28615817, -0.07616529, 0.6687399, -0.7565428, -0.27557972, -0.23855832, -0.93483484, -0.087293684, 1.1687524, -1.3584801, 0.21150073, 1.2037069, -0.6048212, 0.30108434, -0.5661793, -0.27420956, -0.022391453, 0.33260012, 0.85373664, -1.4766654, 0.5845996, 1.4180158, -0.22024389, 0.667976, 0.6244385, -0.3168699, 1.1868767, 0.34774554, -0.64997494, 1.2400774, 0.19068903, -0.13514502, 2.0202057, -0.9182257, 0.199046, -2.1286008, -0.16045126, -0.15270948, 1.3005338, -0.5548139, 1.2173984, -0.29274017, -0.30937454, -0.7711906, -1.2893053, 2.3575566, -0.72209096, 0.7947462, -2.0041177, -0.39761025, -1.015814, 0.6978156, 0.868944, 0.13364673, 0.18352914, 0.8586364, 0.66782385, 0.610228, -0.34375954, 0.13003342, 1.2151164, -0.2166828, 1.1116873, 0.71258795, 1.1434194, -0.47186866, 2.1353364, 1.447041, 0.085622765, -0.5998132, 0.89812726, -0.08066484, 0.8420984, -0.32581723, -0.71437097, -0.17589144, -0.41022748, 0.60955167, -0.6410985, -0.7388026, 0.36736083, 0.039181054, -0.6307165, -0.5466139, -0.7783671, -1.5159419, 0.7252672, 1.2741427, -0.13147596, -0.40053046, -0.028620407, 0.7103258, 0.57227916, 0.87115306, 0.13265681, -0.7893819, -0.73650587, -0.9073851, 0.5145203, 0.11678757, 0.34510773, -0.93830043, 0.11222476, -0.8524616, -0.061620682, -0.55093145, -0.47949544, -0.09997742, 0.09835012, -1.0597764, 0.14261375, 0.1746223, 0.28936136, -1.0353326, -0.19909178, 0.47905058, -1.252357, 0.7624163, 1.2160978, 0.7688873, -0.6454922, -1.0831699, 0.02088613, -0.38204393, -0.907776, -0.9166499, 0.18642414, 2.432432, 0.10058874, 0.8733756, 0.27784142, 1.0831978, -0.60613316, -1.3419845, 0.7750269, 0.8635206, 1.8219028, 0.54030687, -0.87049514, -0.8088964, -0.6807017, -0.89217746, 0.53863055, 0.103357926, 0.29255334, -1.2158495, 0.18755785, -0.41067183, -0.61871785, 2.0842297, -0.6564288, 0.1175787, -0.25890535, -0.7177374, -0.6349298, -0.65529674, -0.26780748, -0.8083765, 0.51767904, 0.6745196, 0.36527988, -0.585937, -0.20295776, 1.7653798, -0.33259234, -0.96098894, -0.07512732, -1.5987782, -0.5730393, 0.25935447, -0.11502524, 0.7548667, 0.6395263, 0.45042387, 2.8521442, -0.95156074, 0.47897643, 0.17717683, 0.36947063, 0.72072726, 0.05572194, -0.8413897, -0.46243054, -1.2105479, 0.13334659, -0.032581076, -4.2375526, -0.59686345, 0.4538272, 1.0885404, 0.6702778, -0.48081216, 0.44729152, -1.140004, -0.010168858, 1.9525921, 0.832294, 1.7936808, -0.048765276, -1.6751267, 1.5497643, -2.353122, -0.4451682, 0.17112952, -0.1890958, -1.3813912, -0.39053974, 0.62938404, 2.082432, -0.7175064, -0.24595845, 2.3162117, -0.3158726, -0.12359636, 0.40302536, 0.18462911, 0.7844205, -0.0015291646, 0.6743531, 0.075157195, 0.11210073, 1.2258631, -0.05680778, -0.24221358, 0.27545154, 0.8361591, 0.5928248, -0.2545021, 1.8165491, -0.04416865, -0.26884404, 0.64862126, 2.21904, -1.7403183, -0.75271726, -0.7202007, 0.16653919, 1.0871801, 1.3364254, 1.4694904, 0.9652211, -0.80510324, 0.5183391, 1.7491461, 0.511918, 1.3462274, 0.7024353, 1.4506098, -0.04295113, -1.2183081, 9.816363E-4, 0.8816808, 0.1508924, 1.1356016, 1.6477102, -0.11800997, 0.30756932, 0.26012784, 0.7386577, 0.29488558, -0.47505602, 0.19272491, 0.51341426, -0.6810482, 0.8993299, -0.60003865, 0.86971986, -0.15220067, 1.1147594, -1.1383475, -0.33894932, -0.26593307, -1.6458954, 0.18725836, 0.94011426, 0.11729905, 0.105840944, 0.3609804, -0.9327989, 0.3713091, 0.060831085, 0.9854874, -0.34511298, -0.2879524, 0.5795063, -0.5236333, 0.065186724, 0.18788286, 1.3223159, 1.1334118, -1.0533829, -0.39967948, -1.9732791, -1.1970584, -1.0549864, 0.43055233, -0.34520608, 0.42950767, -0.003649138, -0.07939597, 0.6475297, -1.3730345, 0.062667415, 1.6147989, -0.1476839, 0.04871749, -0.91856533, 0.56362367, 0.55767614, 1.1749725, -2.0295792, 0.43310302, 0.09634046, 0.20091093, 0.26272556, 0.046745386, -0.21969129, -0.6707004, -0.7647821, -0.063160166, 0.51600844, -0.3087896, 0.41689703, 0.4392679, -0.8582071, 0.79339665, 0.28519478, -0.26558462, -0.6659972, -0.7188982, 1.3808789, -0.89023215, 0.41144633, 0.16805208, -0.75122094, -0.11867887, 1.543643, 0.61344016, -0.19704866, -1.0062346, 0.44627762, 0.4860831, 0.3939407, 0.36183584, 0.7851459, -0.8682549, -1.1847831, 0.5358516, 0.26103783, -2.2152636, 1.103417, 1.4953772, 0.1992315, 0.07908572, -0.8492448, -1.2705877, 0.29931432, -0.9461487, -1.4458283, -1.0470415, -0.41218147, -1.0918698, 0.6166757, 0.18749386, 1.2787181, -0.92622375, 0.6054672, 0.870527, -1.0691093, -1.7123365, 0.0495075, -0.738194, 0.34881157, -0.44842792, -0.4201811, -0.05393745, -2.1925974, 0.09545113, 0.06688569, -0.8977198, -0.085284755, 0.102158695, 0.20149165, -1.7651014, -1.0870925, 0.24054264, -0.74779993, -0.44569153, -0.42099476, 0.8351224, 0.97377527, 0.7060151, 1.0186949, 1.0475934, 2.3733313, -1.1107163, -1.101293, -0.85240287, 0.021774217, -0.03084986, 0.31226873, -0.8944292, -0.6745035, 0.8306402, 0.63163084, -0.88356215, 0.6354829, 0.5462163, 1.6622038, 0.22387153, -1.3001823, -0.0757204, -2.4847255, -0.22084947, -0.7999485, -1.89805, 1.0499556, 0.44911587, -0.5646096, 0.8053865, 1.3021152, 1.8230816, -0.56671524, 0.11187309, -1.3048412, 0.9349616, 0.2546708, -0.36234832, -0.6659309, 0.90868163, 0.04853189, 0.09261486, 0.015527621, 0.7454172, -0.9419852, -0.047329552, 0.08699082, 0.42673504, 0.780743, -0.94500506, -0.73876095, 0.16158783, -0.070774965, -0.5767895, 1.137128, -3.186622, 1.1911851, -1.0656859, -0.392686, -0.03938763, -0.9039558, 0.75739443, 0.5312309, -0.7341834, -0.38595462, 0.2647596, -0.07928561, 0.75340587, -1.3045008, -0.8802977, 0.30121127, 0.2543338, -0.34264043, 0.45520693, -0.9154624, -0.10101467, -0.02641562, -0.12726673, 0.010956101, 0.9258601, 0.1098481, -0.16978537, -0.3670274, -0.07359931, 0.5837086, 0.69936067, -0.28604972, 1.59343, -0.1453458, 0.32370114, 0.6298896, 0.46533775, 0.14416869, -0.39564282, 0.88691527, 0.6066644, 1.3613597, -0.37090945, -1.7808118, -0.1720133, 1.0270717, -0.54187065, 1.6680968, 0.11771559, -1.8401663, 1.1491469, -1.9306219, 0.5856592, -1.1250175, 0.9635127, -0.86805916, 0.9950776, 1.5667278, -0.108083725, -0.8249335, -0.9405231, 1.1947067, -0.35845593, -0.48510844, -0.25952032, 1.5655563, 0.8452434, -0.55366373, -0.842601, 0.14117181, 1.1900853, -0.88801455, -0.8419519, 0.009560674, 0.7411447, -0.11118782, -0.46682933, 0.17498611, 1.4330704, 0.49638534, 0.19230416, 1.2091411, -0.34786895, 0.2274889, -0.37641925, 0.10583784, 0.29251122, 0.26727018, 1.0795634, -1.1727878, 0.7986189, -0.75620455, -0.14081307, 0.70355874, -0.17094393, 0.8434166, 0.0870233, 0.005512327, -0.67821467, -0.5855471, 0.16779336, -0.15551087, -0.58186996, 0.0809322, 0.25340253, 0.4838119, 0.6051569, 0.72161484, 0.24405366, -0.3099302, -0.19053733, -0.33977276, 0.6870599, 1.2345992, 0.3064082, -2.0492685, -0.80029774, -0.73350406, 0.047823828, -0.2212841, -0.53130865, -0.39911112, -0.81050694, 0.19141236, 0.39204028, -0.041854225, -0.41634703, 0.5479881, 0.9199982, 0.37612298, 0.46730843, -0.844545, 0.7269514, -0.54978836, -0.22469144, 0.5518924, -0.21882303, -1.7599337, 0.19333343, -0.6137202, 0.35599604, 0.4681678, -0.93530613, 0.3675471, -0.5560331, -0.93811864, -0.05328221, 0.30546796, -0.06468683, 1.1055162, 0.31039363, 0.79712665, -0.8880656, -0.41150033, 0.62709105, 1.0567634, -1.3500221, -0.58200276, 0.3762134, 0.47680095, 1.6633757, 0.3248726, 0.3021961, -0.65517944, -0.109807625, 1.2432631, 1.7977482, -0.18578239, -2.0532904, -0.619208, 0.14947218, 0.9085295, 1.0551935, 0.011069931, -0.37766242, -0.689911, -0.43453133, 1.6019069, 0.3811674, 0.7572155, -0.40539703, -1.2555295, -0.69455326, 0.49768996, 2.6146052, 2.6659274, -0.9112146, -1.1077894, -0.23498018, -1.2007558, 0.8432704, 1.4062907, 0.53809303, 1.529563, -1.5362505, 1.6111442, -0.5297894, -0.11808497, 0.20472874, 0.31043276, 0.1835281, -0.5836088, -0.02861229, 1.4592621, -0.9100425, 0.61336476, -0.19170228, -0.83800125, 0.8228804, -1.1628532, -0.7328894, 0.84273213, -0.11957289, -1.5090224, 1.0768483, -0.104951106, 0.24791405, -0.366059, 0.96841574, 0.42228532, 0.50324833, -0.5371943, -0.5149842, 1.1027789, 0.19120961, 0.15430793, 0.2757321, -0.36539328, 0.28428805, -0.08055519, -0.3374042, 0.7996474, -0.3285212, -0.14873916, -0.41024688, -0.88183016, 0.2243497, -0.20743272, -0.39711243, -0.20242156, 0.066387035, 0.123112775, 0.469679, -0.39338633, 0.16844624, -0.053532504, -1.3422933, -0.66371524, -0.10573699, -0.2580982, 0.008790031, -0.29559684, 0.8452203, 1.7971001, -0.36888883, 0.58605707, -0.17919783, -1.3992865, 1.8432058, 0.6336147, -0.53755534, 0.05347249, 0.70169985, -1.0162297, 1.4821874, -0.40619004, -1.5554171, 1.3304783, 0.7642607, 0.06273963, 1.190404, 0.050506398, -1.0424638, 0.46894956, -1.1349477, -0.0035732836, 0.47234288, 0.52248424, -0.31404004, -1.919094, 0.51133317, -0.2986818, -0.36438683, 1.6392047, 1.1344445, -1.5788847, 0.9403384, -0.12823837, -0.4158857, -1.3239692, -1.9897468, -0.89076465, -0.47164863, -0.5873591, -1.5080955, -0.4241918, -0.34073642, -0.8595737, -2.1563668, 0.5392478, 1.1566588, -0.48543102, 0.26236895, 0.47868973, -1.1099099, -0.02641529, 0.24095038, 0.05020159, -0.749434, -0.5565289, -1.1763871, 0.7146039, -1.4472867, -0.594348, -0.46612006, 0.7443287, 0.17006834, -1.274579, -0.35685042, -0.07105823, -1.6138446, 0.06209471, 1.7139359, 0.22178563, -0.35350642, 0.543285, -1.3267688, -0.0037474781, -0.6415884, -0.6476863, -0.0051679052, 0.8534037, -1.1693122, 0.010954498, 1.6279119, -0.6788517, -2.533438, -0.8678859, -0.5320176, -0.4124887, 0.9793085, 1.4319218, -1.6222152, 0.5541427, 1.929475, -0.44764268, 0.57726157, 0.30474505, -0.08566475, 1.6472805, 0.15703492, -0.24655053, 0.7776795, 0.49221545, -0.042755544, 1.8118613, -0.33484954, 0.9483563, -1.1041298, -0.34732231, -0.5435285, 0.63029665, -0.29857004, 1.038833, -0.41452676, -0.762923, -0.19454634, -1.763375, 1.6416986, -0.14207828, 0.43010616, -2.5701048, -0.4156133, -0.3095801, 0.7914582, 0.83072764, -0.33544338, 0.03689442, 0.91521347, 0.7419453, 0.4195006, 0.29579616, 0.1270438, 1.1525235, -0.34384894, 1.3438214, 0.7089049, 1.4401239, 0.8427912, 1.9773139, 1.280215, 0.8321328, -0.11056949, 0.541568, -0.37214747, 0.7184359, -0.4635601, -1.0396259, -0.1376052, 0.08048542, 0.2302494, -0.8580882, -0.54565936, 0.0654906, -0.75482774, -0.9244739, 0.06187714, -1.1852716, -0.6424487, 0.25576863, 0.78124565, -0.06435682, -0.70427924, -0.55639213, 0.93429047, 0.69335544, 0.5599617, 0.17459932, -0.41115555, -0.16953023, -0.5571107, -0.6561706, 0.3354718, 0.9480737, -0.94258595, 0.90569663, -1.1170458, -1.9504805, -1.196713, -0.3679911, 0.015131488, 0.18721208, -1.1809741, -0.26950598, 0.6782336, -0.34831914, -0.42956293, -0.62750363, 0.41887188, -0.8657223, 0.2825969, 0.8393127, 0.56417716, -0.05883214, -1.5311673, 0.01864133, -0.1042253, -1.3455918, -0.55855167, -0.24753773, 2.4837918, 0.57509506, 1.0181949, -0.12295708, 0.8753308, -0.5293411, -0.36454523, 0.5012073, 1.1117135, 1.3556263, 0.42402056, -0.93515843, -0.5668046, -0.7429016, -0.49684244, 0.18577796, -0.1632435, 0.12502918, -0.8384259, -0.38961706, -0.20223175, -0.75471324, 2.1295795, -0.3969314, 0.22128996, -0.74520034, -0.675958, -0.56324315, -0.42674473, -0.63405246, -1.2011486, 0.52042735, 0.9495089, 0.020391192, -0.90801936, 0.4682513, 1.7587634, -0.3028639, -1.1834548, -0.31927472, -0.6695488, -0.52235776, -0.7186115, 0.7899222, 1.0014939, 0.27173263, 0.42071947, 1.7468405, -0.78924674, 0.36825815, 0.31606954, 0.11986427, 0.63423735, 0.51299596, -1.373041, -1.069034, -0.57540166, -0.045445397, -0.34945235, -3.3275523, 0.22731975, 0.36902305, 1.2367005, 0.39194432, -0.4746917, -0.24819094, -1.2438312, 0.08193148, 1.8569534, 0.098598346, 1.8004669, 0.097691424, -1.7224234, 0.88370246, -1.9531832, -0.9167318, 0.5780656, 0.05229275, -1.3191699, -0.34447095, 0.68812364, 0.5720577, -0.8811223, -0.11898157, 2.3788629, -0.02985695, -0.5108037, -0.054584697, 0.73180276, 0.4270401, 0.33755153, 1.1565756, 0.23356235, 0.1625686, 0.88033533, -0.2092922, 0.06942951, 0.23726052, -0.23033059, 0.68557966, 0.08532261, 0.99904776, 0.57505476, -0.39024824, -0.13172224, 1.9205338, -1.5390093, -0.08105607, -0.5932407, -0.16045141, 1.7443988, 1.2447889, 1.1255945, 1.2813084, -0.330172, 0.76995254, 1.8966867, 0.1743443, 1.3014711, 1.7853279, 1.1622835, -0.31911337, -0.6598214, 0.7157046, 0.89193434, 0.5118476, 0.65639853, 1.424856, 0.5915188, 0.13096291, 0.022042617, 0.8315848, 0.6827663, 0.07303734, 0.054391682, 0.1589834, -0.9787285, 1.0332872, -0.008612797, 0.8126753, -0.97286534, -0.5721441, -1.9303764, -0.29299396, -0.21202728, -1.1703851, -0.22406223, 1.4962769, 0.11641924, 0.23256451, -0.0811607, -0.8660191, 0.24334851, -0.008027129, 0.9900221, -1.0267837, 0.16684823, 0.57861924, -0.09820887, -0.06444654, 0.79702586, 1.5110456, 1.18736, -1.2774931, -0.78421193, -1.9064893, -1.2888294, -1.0921284, 0.08533788, -0.26716572, 1.0318695, 0.16370623, -0.07553395, 0.5450891, -1.4996822, 0.5724112, 1.5733267, -0.8450707, -0.043714702, -0.6893503, 0.51687837, 1.2746414, 0.7146934, -2.1531124, 0.20818664, -0.10973995, 0.18675843, 0.16448702, -0.7166813, -0.12982129, -0.63502383, 0.031319126, -0.18294649, 0.49100095, -0.36713195, 0.66632205, 0.6834382, -0.35128006, 1.0835311, 0.2283787, -0.66630197, -1.1066312, -0.89536554, 1.5596511, -1.0005987, 0.765801, -0.5909458, -0.85717076, 0.30332184, 1.67724, 1.0395846, -0.028179117, -0.26196128, -0.20154642, -0.15438686, 0.7855068, -0.19717416, 0.5493648, -0.75587803, -0.455737, 0.3237022, 0.42722195, -2.0473754, 0.56801397, 1.3903089, 0.12004324, 0.7005229, -0.3407321, -0.5261313, -0.1538756, -0.7910628, -0.9309482, -0.16353002, -0.58801615, -1.1426258, 0.76081985, -0.53621614, 0.84474635, -0.72333145, 0.24581629, 0.66596776, -0.70429707, -1.6138331, -0.7180623, 0.043840438, 0.84993523, -0.5890736, -0.24500962, -0.20937885, -2.2674901, -0.03398995, -0.078055896, -0.49442667, 0.075571254, 0.09625011, 0.35759744, -0.99303055, -1.5036392, -0.05741927, -0.5990357, -0.56783354, 0.03719426, 2.5208445, 1.2792852, 0.8199502, 0.93128866, 0.9208104, 1.6470743, -1.5426618, -1.3811654, -0.7987242, -0.8944512, 0.4178534, 0.38932425, -0.75248533, -0.06557035, 0.7185067, 0.9333569, -1.0048586, 1.0705352, 0.9695664, 1.353385, 0.09010321, -1.1382583, 0.55308497, -2.6025121, 0.15243526, -1.4278551, -1.6607153, 0.860541, 0.5684724, -0.7798525, 0.9574742, 1.8088274, 1.4807726, -0.1732581, -0.49971592, -1.2938926, 0.6186871, 0.37323606, -0.5336785, -0.98147213, 1.0458283, 0.25446412, 0.36312097, 0.07027008, 0.11262571, -0.42707434, -0.220013, -0.5875742, 0.4669395, 0.6798075, -0.63334805, -0.5783406, 0.1251126, -0.38114056, -0.68132406, 1.0469259, -3.5155873, 1.9671042, -0.9190454, -0.55197716, 0.83801544, -0.5714603, 0.44932735, 0.5354219, -0.5702951, 0.16947825, 0.24018587, 0.48090443, 1.0678362, -1.1853591, 0.079099774, 0.16553098, 0.7293623, -0.71074075, 0.5235574, -0.90503824, -0.88592046, -0.13836983, -1.052803, 0.2526356, 0.34508625, 0.20159572, -0.5355421, -0.43164968, -0.26517433, 0.8913823, 0.39937818, 0.30155915, 2.2124255, 0.0603099, 0.23342517, 0.49676266, 0.75205475, 0.20550296, -0.62654245, 0.28884768, 0.46931282, 1.577348, -0.5057512, -0.8608184, 0.44936067, 1.383238, -0.03490097, 1.2874973, 0.29172882, -1.3608899, 2.2177153, -2.2990627, 0.15486032, -0.94746184, 0.72527826, -0.74821305, 0.5642979, 1.6237416, 0.35510045, -1.371967, -1.4305518, 0.5656934, -1.2487237, 0.4213405, -0.36367983, 0.76374024, 0.93968344, 0.36534926, -0.7551423, -0.0038674623, 0.63060087, -0.6101065, -0.38811347, -0.4785545, 0.5892981, 0.2723823, -0.80994344, -0.7184911, 1.58496, -0.74103945, 0.14645888, 0.8801471, -0.0349124, -0.17808646, -0.8373291, -0.5489321, 0.6399772, -0.56448287, 0.45920986, -0.32797137, 0.48876214, -0.7722936, 0.7110514, 0.5914641, -0.023131683, 0.46343315, 0.4108361, -0.10862967, -0.80872583, -0.56265444, -0.2195296, 0.07072757, -0.32874253, -0.2331534, 0.221698, 0.73738515, 0.7718544, 0.6031042, -0.27522433, -0.8341945, -0.7196441, -0.17732127, 0.5561446, 0.6526755, 0.36112553, -1.6164314, -0.6448827, -0.2615705, 0.37312427, -0.42878437, -0.50876844, 0.01557447, -0.9423974, 0.14062455, 0.6049541, 0.67849314, -0.34584293, 0.4975931, 0.025627308, 0.8797541, 0.4259451, -0.22281408, 0.24196546, -0.11239098, -0.01917174, 0.25028148, -0.34636748, -2.0611026, -0.06447427, -0.62459165, 0.858958, 0.36105034, -1.1696876, 0.056905136, -0.4261216, -0.94341487, -0.30531296, -0.47526762, -0.42512742, 1.4714365, 0.083199374, 1.0179315, -0.9701613, -1.1648011, 0.42087835, 1.1566582, -1.1164685, -0.39050156, 0.4177849, 0.54503053, 1.0581168, 0.122496866, 0.64877594, -0.3731066, 0.8710224, 1.0467112, 1.4225514, -0.1536279, -1.5523295, -0.52426374, -0.2779017, 0.8133898, 0.85683167, -0.36897337, -0.35123062, 0.120082036, -0.54450643, 1.0384865, 0.27679268, 1.8568588, 0.03938148, -1.1608962, -0.41695762, 0.39431348, 3.1264772, 2.3877347, -0.15257652, -0.7320024, 0.12419622, -1.287175, 0.39385453, 0.974821, 0.049994696, 1.0091165, -1.7531127, 1.6948011, -0.366085, -0.4567839, -0.29971364, 0.16656825, 0.08037225, -1.1328343, -0.36554125, 0.40561542, -0.63396376, 0.57928526, -0.40685052, -0.5381798, 0.8005147, -1.3192124, -0.904293, 0.008866582, -0.44051528, -1.3872772, 0.43811536, -0.014631502, -0.022128046, -0.13452059, 1.015941, 0.53356636, 0.39078796, -0.75855446, -0.047520082, 1.2373616, 1.0721242, 0.12809762, 0.1334298, -0.89095044, 0.004328221, -0.24677542, -0.5256807, 0.41210282, 0.35521665, -0.3742752, -0.5365181, -0.40289578, 1.0373986, -0.62946624, 0.09559971, 0.16945997, 0.16011313, 0.15484661, 0.7171279, 0.2228621, 0.62859035, 0.56555617, -1.0822077, 0.104222655, -0.3825818, -0.7731678, -0.34897146, -0.45309782, 0.80402774, 2.3230875, -0.30913597, 0.6176475, -0.15234187, -0.9130463, 1.9025639, 0.86815125, -0.83166724, -0.21401684, 0.78785205, -1.739686, 2.2668343, -0.345401, -1.0512193, 0.91875213, 0.5199171, 0.58468884, 0.73392284, 0.041696012, -0.6166961, 0.84339494, -0.77854466, -0.24405773, 0.67765325, 0.55435055, -0.8057577, -1.5064452, 0.16376469, 0.14463758, 0.19168483, 1.114181, 0.55640376, -1.3145398, 0.98460054, 0.9113636, 0.8381783, -1.8150179, -1.5715137, -0.4935258, -0.49357474, -1.229667, -1.7216921, 0.4676819, -0.11519488, -1.0244559, -2.2180781, 1.4384127, 0.9492223, -0.69357115, 0.1867604, 1.0693477, 0.27487653, 0.121413276, -0.042237528, 0.12876141, -1.2549193, -0.77649903, -1.20677, 0.9945025, -1.718436, -0.3108896, -0.3544942, 0.9586106, 0.12614103, -1.4019394, 0.06979652, -0.51264375, -0.7824047, -0.14419945, 0.78628355, 0.07944815, -0.37333307, 0.540624, -1.2557046, 0.07462505, -0.41541994, -0.62134737, -0.28327915, 1.3320854, -1.043966, -0.12159033, 1.3173989, -0.81243837, -1.0274365, -0.49187303, -0.7640168, -0.7643263, 0.33342665, 1.655695, -1.7654641, 0.35340893, 1.9987454, -0.78443074, 0.79294956, 0.6738753, 0.023859248, 1.9800975, 0.47687012, -0.7451932, 0.1652671, 0.6715458, 0.29612985, 0.89887625, 0.14210236, 0.73136324, -1.5946822, -1.0582726, -0.038778365, 0.16555099, 0.524512, 1.2363143, -0.49336198, -1.3413302, -0.7077877, -1.6578598, 1.5656521, 0.8138503, -0.36629808, -2.1896977, 0.0034853667, 0.9763886, 0.8405733, 0.8849647, -0.17390905, -0.6129, 0.6286722, 1.2564892, 0.2851164, 0.13694803, 9.93222E-4, 0.4676696, -0.48247516, 1.1001453, 0.5705339, 0.94548523, 1.187321, 1.783094, 0.8113491, 1.2139865, -0.016164929, 0.06480987, -0.4149706, 0.23398118, -0.37877452, -1.9220417, -0.050598614, -0.043078206, 0.16855747, -1.6443363, -1.1252139, 0.29613024, -0.672517, -0.5698791, 0.9530813, -1.0694199, -0.46017033, 0.24601588, -0.092323065, -0.44932622, -1.0141845, -1.1348956, 0.61431545, 1.1054189, 0.6349839, 0.7187088, -0.17796, -0.62297076, -0.031074379, -0.79158825, 0.9304359, 1.0766014, -0.76064134, 1.7666234, -0.80129695, -0.74121195, -1.0616574, -0.47188386, -0.36682612, 0.056807466, -0.8654932, -1.0248501, 0.546155, -0.5306963, 0.13037133, -0.6111008, 0.6068614, -0.91773814, -0.44095993, 0.5009603, 0.23484223, -0.17028934, -0.99245024, -0.65067893, 0.5472163, -0.3604442, -0.090568155, -0.4291102, 2.0521805, 0.1021027, 0.6916592, -0.023792937, 1.0715119, -0.83712643, -0.262352, 0.49454427, 0.8390617, 1.3250201, 0.46689984, -1.3506244, -0.99871457, -0.41264826, -0.49381423, 0.26062092, -0.0091345385, -0.02672518, -0.83447754, -0.5903585, -0.39882338, -1.0657839, 1.609232, -0.8066679, 0.4368572, -0.27918258, -2.0761468, -0.09133339, -0.9619137, -1.0781144, -1.9522108, 0.26916057, 1.4185976, -0.2584761, -0.8973954, 1.2409537, 1.2401322, -0.5636558, -0.85113424, 0.65403336, -0.060163096, -0.25691256, -2.1591415, 0.51948744, 0.88662255, 0.1598527, 0.44388902, 0.83538866, -0.6544175, 0.7489537, 0.3759879, -0.30538988, 0.76651734, 0.8989458, -1.1572857, -1.8967073, -0.8011603, 0.20302266, -0.10743599, -3.762876, -0.24564815, -0.6410657, 1.6019788, 1.327007, -1.260699, 0.17235702, -0.99035263, 0.1482996, 2.056026, -0.44028974, 1.9759376, -0.12924966, -1.6157428, 0.03122072, -1.1889125, -0.908909, 0.54299027, -0.8005189, -2.12892, -0.791977, 0.74162257, -0.1204547, -0.6256237, -0.26259482, 1.8753844, -0.3260839, 0.080399685, -0.026118852, 0.8907727, 0.4319697, 0.08642858, 0.8313999, 0.17721243, 1.0065078, 0.6526892, 0.7172497, -0.8695093, 0.6089649, 0.27802703, 0.71105754, 0.31578606, 0.9712795, 0.16790774, -0.038687415, -0.13922635, 1.5738863, -1.0589528, -0.4771744, -0.22979447, 0.21364734, 1.2524059, 1.6702797, 0.20834085, 1.1059339, -1.6936125, 0.6711643, 1.6396366, 0.57020766, 1.045982, 1.2803408, 1.4934437, -0.41918638, -1.1421211, 0.030070513, 0.7253566, 0.31505457, 0.63685656, 1.8019769, 0.54031014, 0.11650577, 0.2846742, 1.5046045, 0.5767608, 0.36930075, 0.32829267, 0.052114997, 0.578656, 1.4265828, 0.3710441, 1.0938163, -0.5008584, -0.5134587, -1.9278206, 0.30874428, 0.15796334, -1.2401778, 0.17576662, 2.0004287, -0.02314052, -0.055543534, -0.50468975, -0.11305372, 0.54043645, -0.5756428, 0.49722683, -0.5297424, 0.13753265, 0.25518733, -0.23544669, -0.5141269, 0.75673586, 1.3438044, 0.9461643, -0.39285365, -0.5860044, -1.787984, -0.8788467, -0.40555692, 0.3285657, -0.38691264, 1.3708282, 0.36385515, -0.7747672, 1.2061442, -1.6046813, -0.23393211, 1.293443, -0.31235135, 0.28134233, -1.1506547, -0.0991762, 1.4272449, 0.6899714, -1.3709666, -0.30998096, 0.7646165, 0.52666295, 0.6161754, -0.32877484, -0.054364443, -0.44929767, -0.8694531, 0.94425637, 0.3422884, 0.6323704, 0.34922627, 0.9050418, -1.5845101, 0.45886135, -0.29504868, -0.5662195, -1.5704926, -0.54826355, 2.2663965, -0.96759653, 0.07684225, -0.68078613, -0.49419355, 0.5082733, 1.7261288, 1.2518026, -0.02031415, -0.90473115, 0.35896915, 0.49848247, 0.5520185, -0.7405191, 0.3500682, -0.262386, -0.3942172, 0.29561684, 1.021035, -1.4068037, 2.2699223, 1.4257491, -0.10412434, 0.17128283, -1.0413268, -0.86806285, 0.37422425, -1.391298, -0.995613, -0.81997967, -1.0913445, -0.43824428, 0.7557612, 0.7228685, 1.022525, -0.8960229, -0.5878514, 0.29143187, -0.24042165, -1.5417792, -0.8847957, -0.16454956, -0.108894505, -0.8830671, 0.30506596, -0.047977895, -1.5889373, 0.0026431233, 0.1652314, -0.084799856, -0.14659284, 0.7213514, -0.25080308, -2.7894351, 0.05464632, 0.20575038, -1.2875743, -0.5489224, -0.23698223, 0.62773806, 1.4328256, 0.87418485, 0.29029268, 0.72027886, 1.5169219, -0.93750125, -0.6640493, -0.8408683, -0.69088763, 0.071907505, -0.33705214, -0.37655997, -1.1414671, -0.3436033, 0.6703798, -0.34200937, 0.76734024, 0.48768342, 2.0672226, 0.3513915, -2.6420221, 0.79512703, -1.9421546, -0.39919388, -0.3103354, -1.3154385, 0.5201629, -0.039092638, -1.0361304, 1.2638918, 1.6469301, 1.4541465, -0.12338864, -0.20437062, -1.3766631, 0.20336919, 0.3032297, -1.1453805, -0.63037485, 0.86080396, 0.057820674, -0.17105912, -0.66717327, 0.8759303, -1.5944928, -0.34394643, -0.81281877, -0.10437061, 0.51413935, -0.6940095, 0.09568102, 0.4002368, 0.3984665, -0.4812769, 1.0038961, -2.2231097, 1.4474787, -0.57229334, -0.20271471, 0.8423536, -0.3723959, 1.499843, 0.74556774, -0.2668783, -0.17127366, -0.26935872, 0.04133615, 0.5453585, -0.8243729, -0.39952496, 0.4004973, 0.41419125, -0.5219258, 0.78898853, -1.1944782, -0.069127515, -0.50455236, -0.72714645, -0.020746175, 0.5059885, 0.04399816, -0.7894044, -0.4625147, -1.1342267, 1.1750203, 1.0542814, 0.54491824, 1.1081833, 0.9187785, 0.35971174, 1.2452533, 0.34259045, 0.21274799, -0.3588566, 0.4610651, -0.04601556, 1.4945889, -0.5564384, -1.0967007, 0.7066467, 3.3626142, -0.45100608, 0.94582105, 0.5915438, -1.2985345, 1.8414979, -1.8253032, 0.14959589, -0.77038383, 1.4642384, -0.4388054, 1.288484, 1.3210498, -0.80942005, -0.9672099, -0.65774846, 1.1029816, 0.46842724, -0.6264829, 0.4077455, 0.81473553, -0.42250708, 0.32202694, -0.22059433, -0.7988756, 0.708937, -0.9522668, -0.7775771, 0.059927836, 0.74642587, -0.19692329, -1.2440609, -1.098552, 1.0545642, -1.0772063, 0.74647504, 1.470575, -0.5858193, -0.0924616, -0.17740022, -0.66750735, 1.1928539, -0.23574628, 0.81189126, 0.09582798, 0.4183188, -1.1813284, -0.026065111, 0.31969306, 0.43597493, 0.66805744, 0.62070143, -0.0034784377, -0.8889909, -0.80639535, 0.3112222, 3.1803548E-4, -0.6416318, 0.33191863, 1.1382916, 1.3028858, -0.10085269, 0.3195763, -0.31446657, -0.35984194, -0.38577667, 0.53107315, 0.40813607, 0.7133298, 0.25367644, -1.0670294, -0.6008749, 0.2553314, 0.80797035, -0.35269725, -0.6880298, 0.24852966, -1.1319366, -0.8757431, -0.21580404, -0.18601301, -0.6906879, 0.014807865, 1.1912467, 1.04509, -0.10085851, -0.45177278, -0.072870165, 0.329378, -0.49100843, -0.43467385, -1.2889651, -0.70850945, 0.26771125, 0.18572438, -0.2720942, 0.43180743, -0.81432074, -0.16396782, -0.6017848, -1.1050781, -0.1555152, -0.23216394, 0.037618868, 0.7290777, 0.9550213, 0.5936872, -1.586561, -0.6771395, 0.56206936, 1.130935, -1.2366065, -0.1617217, 0.51420254, 0.971334, 1.78033, -0.1060246, 0.21716677, -0.27206194, 0.54947907, 0.94673073, 0.73379856, -0.8343029, -1.4676459, -0.46819842, 0.48852733, 0.37889057, 0.23780534, 0.38874793, -0.5406712, 1.3277413, 0.15832564, 1.6661067, 1.2097427, 1.4635663, -0.12328875, -0.67774004, -0.28292066, 0.320097, 2.5623178, 1.3031111, -0.603192, -0.89567465, 0.30138868, -1.5841885, 0.53296447, 0.6786059, 0.40331912, 2.0684633, -1.8140808, 1.4070704, -0.3449422, 0.042878196, 0.015341766, -0.5814527, 0.40312484, -1.6848412, 0.3573785, 0.58632135, -1.2993916, 0.4050647, 0.09386148, -0.9597645, 0.24521033, -1.296575, -0.8788979, -0.07583651, -0.19651726, -1.3198664, 0.91247207, -0.23491615, -0.69126385, -0.36646947, 0.6679405, 0.6521822, 1.2520598, -1.2030113, -0.05532061, 1.2752007, 0.65868104, 0.13310033, -0.38185915, -0.36582285, 0.6203386, -0.44607306, -1.0542217, 0.69973034, -0.21898067, -0.90345484, 0.3432177, -1.1876707, -0.61998874, -0.17062163, 0.03154456, 0.9546824, -1.1999363, 0.35003653, 0.3774589, -0.69688475, 0.5394852, -0.4178684, -0.5743325, 0.44549868, 0.23013777, 0.48078102, -1.2584909, 0.17692174, 0.77223897, 2.3418598, -0.60895723, 0.47246987, 0.0635868, -1.6709051, 0.9226307, 0.87492394, -0.26498368, -0.62524897, 0.4892697, -1.2254604, 1.4037976, -0.2848704, -1.2092291, 0.07173258, 0.9759337, 0.28825217, 1.1190293, 0.36933511, -0.86020666, 0.46288306, -0.8207261, 0.7977053, 0.3890648, 1.1675832, 0.0275044, -0.39459595, -0.13455182, 0.07498321, -1.271422, 1.2770928, 0.049766738, -1.4789736, 0.9204863, 0.70714617, 0.70985067, -2.331192, -0.61922467, -0.2763989, -0.5571157, -0.67623353, -1.1761963, -0.21970682, 0.27037323, -0.8994191, -2.381745, 0.6371306, 1.2865686, -0.18902478, 0.50391877, 0.059875734, 0.060568426, -0.29835868, 0.04036907, 0.22656354, -0.50994015, -0.37293923, -1.2668151, 0.49166775, -0.8428958, -0.19374083, -0.60098785, 1.1365696, 0.27369553, -0.7550793, -0.1837983, -0.28003544, -1.5021, 0.017706933, 1.007257, 0.5001768, -0.76717174, 0.81601655, -1.4830563, -0.06647308, -0.8637145, -0.8227021, 0.45729873, 0.8057303, -0.9028343, -0.6716624, 1.3764576, -0.049274106, 1.3423727, -0.92215544, -1.1009762, -0.32981873, 0.7333975, 1.4434083, -2.4913514, 1.482163, 1.5521965, -0.81519526, 0.5059769, 0.44045776, 0.5900404, 1.4250352, 0.49720865, 0.41570318, 0.15930353, -0.13293587, -0.64938587, 1.6937196, -0.1525658, -0.090940125, -1.6866062, -1.2692227, -0.82893753, 0.8964745, 0.75051117, 1.5867168, 0.096937, -0.74163896, -1.2800126, -1.4941839, 1.6449912, 0.4826567, 0.5664867, -1.7497717, -0.06550709, -0.08505991, 0.4821029, 0.54030067, -0.082249105, -0.99253076, 0.2034322, 0.25167018, 0.32151845, 0.032924175, 0.16754732, 0.11660733, -0.69654804, 1.8220257, 0.28798974, 1.8381176, 1.1841091, 1.6198701, 1.8414903, 1.23679, 0.043849654, 0.1534152, 0.18300694, -0.21019913, -0.8895652, -1.1764803, 0.6239901, -0.26321217, 0.06479309, -0.55182844, 0.040147334, 0.2995581, -0.5331417, -1.0413771, 0.60910714, -1.2584362, -0.28730014, 0.12595543, 0.12742367, -1.0103757, -0.8232557, -0.49357045, 0.70783716, 0.30833355, 0.48050115, 0.29242313, -0.7269964, 0.22016521, 0.14010502, -0.7454974, 0.6690863, 0.8573559, -0.17470227, 1.4966593, -1.2781067, -0.77586764, -0.7272115, -0.45727804, 0.17809007, -0.449621, -0.93235147, -0.45838866, 0.7588631, -0.5219085, 0.1722843, -0.51468235, 0.4696321, -0.7007964, -0.6519156, 0.652754, -0.419362, 0.13925533, -1.5399723, -0.36031464, 0.07082115, -0.5639774, -0.2888695, -0.56151384, 2.0554755, 0.14657974, 0.87772167, -0.4596722, 1.6220878, -0.30062535, -0.63579226, 0.23556773, 1.7248702, 0.17956474, 0.51734966, -1.474717, -0.72370553, 0.016837284, -0.6655267, -0.108507134, 0.09206803, 0.23756504, -0.75349075, -0.7275167, 0.3287605, -0.20825714, 0.540179, -0.563493, 0.18271421, -0.93017954, -1.3007112, -0.36480477, -0.9600047, -0.803205, -1.6867162, 0.55379134, 0.6960957, -0.47614285, -0.7246411, 0.5093761, 1.6628364, -0.5569885, -0.6545775, -0.80253917, -0.8271408, -0.9183827, -1.5228175, -0.09946534, 0.99671286, 0.6209274, 0.12665525, 1.159173, -0.30778784, 0.2912266, 0.12909448, 0.579844, 0.14042296, 0.57635796, -1.6015556, -1.344032, -0.08781851, -0.10264405, 0.1350973, -4.4351306, -0.18748549, 0.11809458, 1.3453304, 0.9689776, -0.86725503, 0.02527731, -0.9093106, -0.039363153, 1.8000926, 0.37629968, 1.5821699, -0.11818232, -1.6388477, 0.70786685, -1.7642478, -0.34004864, 0.05239167, -0.45685053, -1.4894409, -0.6160852, 0.8691628, 8.518949, -0.44275343, -0.15159568, 1.7194852, -0.32879514, 0.503711, 0.32538795, -0.047598664, 0.4116954, -0.37143373, 0.8617377, -0.0024800003, 0.68594164, 0.8106313, 0.5021601, -0.65510845, 0.2947012, 0.4580874, 0.8429514, -0.029524736, 1.244981, 0.056723148, -0.11515126, 0.2904784, 1.5083828, -0.90244603, -0.89504975, -0.5929145, -0.13560995, 1.2172327, 1.2993513, 0.5471312, 0.9823583, -0.53089905, 0.6470476, 1.3706353, 0.07710672, 0.66170347, 0.8522321, 3.7581966, 0.18205029, -1.5388376, 0.14968619, 0.7957213, 0.5417012, 0.57052195, 1.7262292, 0.3853963, 0.05573173, 0.019531325, 0.889642, 0.14051607, -0.10019319, 0.52222127, -0.045800984, -0.1372413, 1.3182182, 0.06720713, 0.65188503, -0.49704686, 0.15328996, -1.4841757, 0.07393673, -0.10667658, -1.741219, 0.15979664, 1.0401752, 0.20498934, -0.09760857, 0.26027164, -0.4799143, 0.66915995, 0.0971428, 0.50639033, -0.5895407, -0.2591088, -0.12500899, -0.44097197, -0.018114433, 0.07570505, 1.8875248, 0.72134954, -0.6835846, -0.43611696, -1.5730146, -0.47251692, -0.967706, 0.67281497, -0.3970288, 0.23531409, 0.31934413, -0.4834523, 0.85528296, -1.4495584, -0.17761847, 1.0605572, -0.33328635, 0.09331871, -1.6740737, 0.32838723, 1.2812709, 0.7532023, -1.6620958, -0.06949543, 0.22357371, 0.5511003, 0.44403845, -0.088602625, 0.086290106, -0.29867518, -0.59133786, 0.47898614, -0.16206141, -0.3974132, 0.020216722, 0.9978839, -0.88115966, 0.43280727, -0.027793905, -0.67816794, -0.6834847, -0.310411, 1.4877534, -0.9325847, 0.08318488, -0.056899868, -0.3264665, 0.18626533, 1.311764, 0.52422476, 0.27261677, -0.9771914, -0.07349676, 0.23518278, 0.6440802, -0.38859436, 0.7356058, -0.87186205, -0.79511106, 0.6331253, 0.51360786, -1.8998158, 1.2421445, 1.6992611, 0.3416561, 0.08102964, -1.1458695, -1.3352224, 0.4332353, -0.82750726, -0.68687415, -1.0607231, -0.45399368, -0.65770257, 0.5407971, 0.36140308, 0.78880286, -0.87017035, 0.11368229, 0.9742579, -0.836373, -1.4891531, -0.39808506, -0.12711097, 0.2665581, -0.94508183, 0.3168681, 0.18193309, -2.0642102, -0.42695135, -0.01493331, -0.8744083, 0.136745, 0.33562094, 0.35592413, -1.9299185, -0.9336301, 0.21273266, -1.1257002, -0.46698323, -0.44841182, 0.4095448, 0.9316055, 0.42856336, 0.7239482, 0.5807358, 1.7736349, -0.8905484, -0.98154503, -0.8812651, -0.591294, 0.114608765, 0.074452646, -0.7906054, -0.48456904, 0.58756906, 0.72785217, -0.45900884, 0.80664396, 0.20831603, 1.404514, 0.10135339, -1.7207683, 0.121471085, -1.4293977, -0.25176442, -0.88530314, -1.932973, 0.75488913, 0.053633798, -0.5996313, 1.1192294, 0.7987387, 1.0803125, -0.20899309, -0.3250925, -1.0392616, 0.60894144, 0.24588943, -0.64634514, -0.6554399, 0.8959745, 0.44019213, -0.045357216, -0.38841888, 0.79150975, -0.70056456, -0.10906712, -0.35132694, 0.38104087, 0.83124346, -0.9196306, 0.101093374, 0.3173144, 0.35568184, -0.72773474, 1.0110441, -2.1881406, 0.90069056, -1.2138778, -0.49465472, 0.29515645, -0.42973396, 0.86696035, 0.462676, -0.2891507, 0.48092514, 0.14870986, 0.2362285, 0.94265085, -0.95444787, -0.7235914, 0.15523535, 0.8009351, -0.57308763, 0.8169279, -0.66213703, -0.03514193, -0.06134875, -0.7540824, -0.20499344, 0.5033528, 0.6832062, -1.0438838, 0.0013836473, -0.5009912, 0.93052953, 0.57491046, 0.42732602, 1.4600122, 0.7491548, 0.1275791, 0.9447524, 0.14973052, 0.5151727, -0.4853087, 0.71405834, 0.5183598, 1.313502, -0.21636684, -0.77506334, -0.12591712, 1.486607, -0.7264576, 0.99942267, 0.3202754, -1.502707, 1.4193612, -1.40818, 0.27752662, -0.80451846, 1.1607374, -0.20769496, 0.61043406, 1.315206, 0.0568088, -0.40790638, -0.5757813, 1.0029505, -0.25614408, -0.60398436, 0.2829705, 0.90209776, 0.19745542, -0.3516592, -0.55319506, -0.1090347, 0.9403592, -0.28909415, -0.61357373, -0.28233677, 0.8260039, -0.211104, -1.1662388, -0.7386189, 1.4462554, -0.34844738, 0.37773976, 0.7810842, -0.5882355, -0.059488796, -0.19547813, -0.24606134, 0.6835963, 0.2511679, 0.856332, -1.0636065, 0.3394099, -0.96563685, -0.005031675, 0.50627327, -0.5008203, 0.90881467, 0.3842252, 0.11551586, -0.83781016, -0.77075464, -0.2338815, -0.035362475, -1.0022215, 0.20489949, 1.1973978, 0.6405313, 0.22105882, 0.759547, -0.15372802, -0.9853528, -0.055215254, -0.11200724, 0.93392026, 0.92165124, 0.56908315, -1.6037151, -0.63075554, -0.3626079, 0.42245942, -0.37033117, -0.899393, 0.3136378, -0.38658756, -0.045805737, -0.12737003, -0.62156856, -0.77010757, 0.3646657, 0.30881408, 0.81467205, -0.35185418, -1.2174497, -0.124289915, 0.21588212, -0.5912653, 0.5155864, -0.55197835, -0.74786615, 0.32146156, -0.54999655, -0.3350795, -0.074797854, -1.4570993, 0.23734923, -0.6517045, -0.39027223, -0.0027831644, -0.07549344, -0.12575209, 1.3137401, 0.77984715, 0.5054453, -1.1595855, -0.31115592, 0.5981977, 1.5581173, -0.71296954, -0.60147953, 0.23892058, 0.90308523, 1.2783934, 0.4829749, 0.56447566, -0.11322677, 0.4671607, 0.7727588, 0.7172333, -0.1574448, -1.2798158, -0.3061784, 0.6185353, 0.9465671, 0.679906, -0.2793042, -0.46887103, -0.016957872, -0.17706259, 0.90864146, 0.5860386, 0.78973603, -0.2444247, -1.0041484, -0.34054106, 0.3139922, 5.928577, 1.9771936, -0.54047304, -0.6981526, 0.18960235, -0.8373701, 0.44040245, 0.92274296, 0.32851875, 2.1369495, -1.9185268, 1.7090166, -0.22396593, -0.0027257204, 0.2886428, -0.14268377, 0.30027795, -1.1787082, 0.29569986, 0.44846383, -1.0683426, 0.19287628, -0.061031498, -0.45552272, 0.8514906, -1.1983136, -0.7224097, 0.56610334, -0.43930328, -1.6241871, 0.022371702, 0.056378156, -0.28574908, 0.22669566, 0.6215599, 0.56851315, -0.12263401, -1.1360767, -0.6112565, 0.9653295, 0.23831022, 0.46430987, -0.004769601, 0.007459389, 0.447268, -0.1048284, -0.29818714, 0.39249915, -0.34207064, -0.57210505, -0.4499803, -0.7788103, -0.0464814, -0.31602553, -0.30049258, -0.26680958, -0.12828995, -0.037486445, 0.09821058, -0.24948204, -0.25496805, 0.3345239, -1.4232894, -0.15812662, 0.08070272, -0.36936277, -0.69673073, -0.33060092, 0.73889613, 1.8970333, -0.53052443, 0.9062418, -0.33914202, -1.9018056, 0.61787736, 0.46802747, -0.40738654, -0.24149843, 0.52864766, -1.6946682, 1.5362931, -0.2065873, -1.3585843, 0.3950286, 0.48188406, 0.37551737, 0.4769164, 0.48761457, -1.0027927, 0.14477731, -1.1952885, -0.23367448, 1.2076813, 0.58423406, 0.07876493, -1.041011, 0.13759089, -0.14066333, -0.40304744, 0.8249726, 0.5309512, -1.5140133, 0.6465395, 0.00805977, -0.35565233, -1.0447453, -1.6391871, -0.57476056, -0.60116166, -0.6509856, -1.6507915, -0.24304004, -0.32796037, -0.9862035, -2.3792913, 0.72232765, 0.88596475, 0.05681677, 0.69371164, 0.4067158, -0.32266128, 0.35941786, 0.14268196, 0.008820172, -0.44048947, -0.3807906, -1.2657222, 0.011590555, -1.4166234, -0.5570914, -0.09691977, 0.61406046, 0.85134614, -0.9073981, -0.14514786, -0.19705656, -1.3431568, -0.18641903, 1.1970922, 0.43596244, -0.4643676, 0.23464873, -1.4809799, 0.22952351, -0.79023015, -0.9660293, -0.06106868, 0.91435355, -0.9410994, -0.27363744, 1.1213156, -0.5552039, 0.47450387, -0.67726296, -0.84531724, -0.3695472, 0.32097948, 1.236008, -1.9377409, 0.8715727, 1.7278404, -0.7182699, 0.34749338, 0.055821747, -0.25673252, 1.5338271, 0.5981914, 0.26056722, 0.35266542, 0.34506303, -0.2707516, 1.6680403, -0.26225284, 0.28264982, -0.93208283, -0.7195003, -0.49397373, 1.097455, -0.17251527, 1.2040282, -0.13247448, -0.8344006, -1.3730105, -0.9985511, 1.6127682, 0.102908984, -0.050705314, -2.0138884, -0.26599008, -0.67300093, 0.4828793, 0.8306255, 0.06904271, -0.2150876, 0.71669734, 0.71310204, 0.18367703, 0.3811021, 0.3367172, 0.4790209, -0.52320474, 1.4387411, 0.49768502, 1.6168096, 0.48664856, 2.0569668, 1.767732, 1.2483784, -0.1911243, 0.2164427, -0.41037652, 0.44743055, -0.32683307, -1.4615301, -0.2763298, -0.3156423, 0.28007326, -1.0386963, -0.556035, 0.55629194, -1.0255252, -0.54166985, 0.47017503, -1.3562512, -0.6570422, 0.85600406, 0.42322922, -0.3800823, -0.96864665, -0.39303845, 0.6151631, 0.8127344, 0.40640417, 0.29468858, -0.3595955, -0.26588053, -0.48084825, 0.1381006, 0.6274589, 0.50441945, -0.70409054, 0.6415553, -1.4776558, -0.7265096, -0.56839985, -0.37481079, -0.0556299, -0.07709563, -1.0079755, -0.31482062, 0.5529114, -0.2905458, -0.33441335, -0.7538321, 1.0301089, -0.8336837, 0.014018759, 0.6930184, 0.2822684, -0.59929043, -1.2549504, -0.04152093, -0.15594202, -0.8416114, 0.30521527, 0.085296825, 1.998172, 0.17953297, 0.81972474, -0.12049776, 0.636938, -0.32321817, -0.6623517, 0.4681129, 0.86831105, 1.3369138, 0.3237801, -1.4724734, -0.77724206, -0.13026565, -0.4761805, 0.25618175, -0.5109254, 0.33371875, -0.54170126, -0.25134182, 0.2437961, -0.46777722, 0.7951042, -0.92533684, 0.3077589, -0.67483133, -1.337733, -0.46373364, -0.6056862, -1.1445198, -0.5523313, 0.5446045, 0.69936764, -0.100782454, -0.7716193, 0.18777585, 1.7000009, -0.13324845, -0.04496102, -0.38585514, -0.6497307, -0.9735717, -0.3312297, 0.67569, 0.6791347, 0.1443547, -0.28027967, 1.9505106, -0.31825987, 0.09358952, -0.003940981, 0.060346037, 0.75013196, 0.75749826, -1.0889099, -1.6545596, 0.1618316] -2025-10-16 21:36:09 [main] INFO OnnxTest - ------------------------ -2025-10-16 21:36:09 [main] INFO OnnxTest - tokenizer加载耗时: 4082ms -2025-10-16 21:36:09 [main] INFO OnnxTest - tokenizer计算耗时: 1ms -2025-10-16 21:36:09 [main] INFO OnnxTest - 模型加载耗时: 441ms -2025-10-16 21:36:09 [main] INFO OnnxTest - 模型数据准备耗时: 10ms -2025-10-16 21:36:09 [main] INFO OnnxTest - 模型计算耗时: 5ms diff --git a/Partner-Main/pom.xml b/Partner-Main/pom.xml index e4211334..2ac948f9 100644 --- a/Partner-Main/pom.xml +++ b/Partner-Main/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 work.slhaf @@ -26,7 +26,11 @@ org.jetbrains.kotlinx kotlinx-coroutines-core 1.10.2 - test + + + org.jetbrains.kotlinx + kotlinx-coroutines-test + 1.10.2 @@ -44,6 +48,38 @@ tokenizers 0.34.0 + + + io.modelcontextprotocol.sdk + mcp + 0.17.0 + + + work.slhaf + Partner-Common + 0.5.0 + compile + + + org.mockito + mockito-core + 5.20.0 + + + org.mockito + mockito-junit-jupiter + 5.20.0 + + + org.mockito + mockito-inline + 5.2.0 + + + com.cronutils + cron-utils + 9.2.1 + @@ -66,7 +102,7 @@ + implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> work.slhaf.partner.Main diff --git a/Partner-Main/src/main/java/work/slhaf/partner/Main.java b/Partner-Main/src/main/java/work/slhaf/partner/Main.java index 5d5e27a0..318b385c 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/Main.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/Main.java @@ -12,7 +12,7 @@ public class Main { .setAgentConfigManager(PartnerAgentConfigManager.class) .setGateway(WebSocketGateway.class) .setAgentExceptionCallback(PartnerExceptionCallback.class) - .addAfterLaunchRunners(() -> VectorClient.load()) + .addAfterLaunchRunners(VectorClient::load) .launch(); } } \ No newline at end of file diff --git a/Partner-Main/src/main/java/work/slhaf/partner/common/Constant.java b/Partner-Main/src/main/java/work/slhaf/partner/common/Constant.java new file mode 100644 index 00000000..5cecd24a --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/common/Constant.java @@ -0,0 +1,10 @@ +package work.slhaf.partner.common; + +public final class Constant { + + public static final class Path { + public static final String DATA = "data"; + public static final String MEMORY_DATA = DATA + "/memory"; + } + +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/common/util/PathUtil.java b/Partner-Main/src/main/java/work/slhaf/partner/common/util/PathUtil.java new file mode 100644 index 00000000..3266de53 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/common/util/PathUtil.java @@ -0,0 +1,14 @@ +package work.slhaf.partner.common.util; + +public class PathUtil { + public static String buildPathStr(String... path) { + StringBuilder str = new StringBuilder(); + for (int i = 0; i < path.length; i++) { + str.append(path[i]); + if (i < path.length - 1) { + str.append("/"); + } + } + return str.toString(); + } +} \ No newline at end of file diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/PartnerCore.java b/Partner-Main/src/main/java/work/slhaf/partner/core/PartnerCore.java index eee0652c..9b75d06d 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/PartnerCore.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/PartnerCore.java @@ -13,10 +13,11 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import static work.slhaf.partner.common.Constant.Path.MEMORY_DATA; + @Slf4j public abstract class PartnerCore> extends PersistableObject { - private static final String STORAGE_DIR = "./data/memory/"; private final String id = ((PartnerAgentConfigManager) AgentConfigManager.INSTANCE).getConfig().getAgentId(); public PartnerCore() throws IOException, ClassNotFoundException { @@ -53,7 +54,7 @@ public abstract class PartnerCore> extends PersistableO public void serialize() throws IOException { //先写入到临时文件,如果正常写入则覆盖原文件 Path filePath = getFilePath(id + "-temp"); - Files.createDirectories(Path.of(STORAGE_DIR)); + Files.createDirectories(Path.of(MEMORY_DATA)); try { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath.toFile())); oos.writeObject(this); @@ -78,12 +79,12 @@ public abstract class PartnerCore> extends PersistableO } private Path getFilePath(String s) { - return Paths.get(STORAGE_DIR, s + "-" + getCoreKey() + ".memory"); + return Paths.get(MEMORY_DATA, s + "-" + getCoreKey() + ".memory"); } private void createStorageDirectory() { try { - Files.createDirectories(Paths.get(STORAGE_DIR)); + Files.createDirectories(Paths.get(MEMORY_DATA)); } catch (IOException e) { log.error("[{}]创建存储目录失败: {}", getCoreKey(), e.getMessage()); } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCapability.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCapability.java index 69bf78bd..1f99bfe0 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCapability.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCapability.java @@ -1,26 +1,59 @@ package work.slhaf.partner.core.action; +import lombok.NonNull; +import org.jetbrains.annotations.Nullable; import work.slhaf.partner.api.agent.factory.capability.annotation.Capability; -import work.slhaf.partner.core.action.entity.CacheAdjustData; +import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaActionInfo; +import work.slhaf.partner.core.action.entity.PhaserRecord; +import work.slhaf.partner.core.action.entity.cache.CacheAdjustData; +import work.slhaf.partner.core.action.runner.RunnerClient; +import work.slhaf.partner.module.modules.action.interventor.entity.MetaIntervention; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Phaser; @Capability(value = "action") public interface ActionCapability { - void putPreparedAction(String uuid, MetaActionInfo metaActionInfo); - List popPreparedAction(String userId); + void putAction(@NonNull ActionData actionData); - List popPendingAction(String userId); + Set listActions(@Nullable ActionData.ActionStatus actionStatus, @Nullable String source); - List listPreparedAction(String userId); + List popPendingAction(String userId); - List listPendingAction(String userId); + List listPendingAction(String userId); - void putPendingActions(String userId, MetaActionInfo metaActionInfo); + void putPendingActions(String userId, ActionData actionData); List selectTendencyCache(String input); void updateTendencyCache(CacheAdjustData data); + + ExecutorService getExecutor(ActionCore.ExecutorType type); + + PhaserRecord putPhaserRecord(Phaser phaser, ActionData actionData); + + void removePhaserRecord(Phaser phaser); + + List listPhaserRecords(); + + PhaserRecord getPhaserRecord(String tendency, String source); + + MetaAction loadMetaAction(@NonNull String actionKey); + + MetaActionInfo loadMetaActionInfo(@NonNull String actionKey); + + Map listAvailableMetaActions(); + + boolean checkExists(String... actionKeys); + + RunnerClient runnerClient(); + + void handleInterventions(List interventions, ActionData data); + } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCore.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCore.java index 502a3753..140238f7 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCore.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCore.java @@ -1,91 +1,115 @@ package work.slhaf.partner.core.action; +import lombok.NonNull; import lombok.extern.slf4j.Slf4j; -import work.slhaf.partner.api.agent.factory.capability.annotation.Capability; +import lombok.val; +import org.jetbrains.annotations.Nullable; +import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod; import work.slhaf.partner.common.vector.VectorClient; import work.slhaf.partner.core.PartnerCore; -import work.slhaf.partner.core.action.entity.ActionCacheData; -import work.slhaf.partner.core.action.entity.CacheAdjustData; -import work.slhaf.partner.core.action.entity.CacheAdjustMetaData; +import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaActionInfo; +import work.slhaf.partner.core.action.entity.PhaserRecord; +import work.slhaf.partner.core.action.entity.cache.ActionCacheData; +import work.slhaf.partner.core.action.entity.cache.CacheAdjustData; +import work.slhaf.partner.core.action.entity.cache.CacheAdjustMetaData; +import work.slhaf.partner.core.action.exception.ActionDataNotFoundException; +import work.slhaf.partner.core.action.exception.MetaActionNotFoundException; +import work.slhaf.partner.core.action.runner.RunnerClient; +import work.slhaf.partner.core.action.runner.SandboxRunnerClient; +import work.slhaf.partner.module.modules.action.interventor.entity.InterventionType; +import work.slhaf.partner.module.modules.action.interventor.entity.MetaIntervention; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; +import java.util.*; +import java.util.concurrent.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; @SuppressWarnings("FieldMayBeFinal") -@Capability(value = "action") +@CapabilityCore(value = "action") @Slf4j public class ActionCore extends PartnerCore { /** - * 对应本次交互即将执行或将要放置在行动池的预备任务,因此将以本次交互的uuid为键,其起到的作用相当于暂时的模块上下文 + * 持久行动池 */ - private HashMap> preparedActions = new HashMap<>(); + private CopyOnWriteArraySet actionPool = new CopyOnWriteArraySet<>(); /** * 待确认任务,以userId区分不同用户,因为需要跨请求确认 */ - private HashMap> pendingActions = new HashMap<>(); + private HashMap> pendingActions = new HashMap<>(); /** * 语义缓存与行为倾向映射 */ private List actionCache = new ArrayList<>(); - private Lock cacheLock = new ReentrantLock(); + private final Lock cacheLock = new ReentrantLock(); - private Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + // 由于当前的执行器逻辑实现,平台线程池大小不得小于 2,这里规定为最小为 4 + private final ExecutorService platformExecutor = Executors + .newFixedThreadPool(Math.max(Runtime.getRuntime().availableProcessors(), 4)); + private final ExecutorService virtualExecutor = Executors.newVirtualThreadPerTaskExecutor(); + + /** + * 已存在的行动程序,键格式为‘::’,值为 MCP Server 通过 Resources 相关渠道传递的行动程序元信息 + */ + private final ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + private final List phaserRecords = new ArrayList<>(); + private RunnerClient runnerClient; public ActionCore() throws IOException, ClassNotFoundException { + // TODO 通过 AgentConfigManager指定采用何种 runnerClient + runnerClient = new SandboxRunnerClient(existedMetaActions, virtualExecutor); + setupShutdownHook(); + } + + private void setupShutdownHook() { + // 将执行中的行动状态置为失败 + val executingActionSet = listActions(ActionData.ActionStatus.EXECUTING, null); + for (ActionData actionData : executingActionSet) { + actionData.setStatus(ActionData.ActionStatus.FAILED); + actionData.setResult("由于系统中断而失败"); + } } @CapabilityMethod - public synchronized void putPendingActions(String userId, MetaActionInfo metaActionInfo) { + public void putAction(@NonNull ActionData actionData) { + actionPool.removeIf(data -> data.getUuid().equals(actionData.getUuid())); // 用来应对 ScheduledActionData 的重新排列 + actionPool.add(actionData); + } + + @CapabilityMethod + public Set listActions(@Nullable ActionData.ActionStatus actionStatus, @Nullable String source) { + return actionPool.stream() + .filter(actionData -> actionStatus == null || actionData.getStatus().equals(actionStatus)) + .filter(actionData -> source == null || actionData.getSource().equals(source)) + .collect(Collectors.toSet()); + } + + @CapabilityMethod + public synchronized void putPendingActions(String userId, ActionData actionData) { pendingActions.computeIfAbsent(userId, k -> { - List temp = new ArrayList<>(); - temp.add(metaActionInfo); + List temp = new ArrayList<>(); + temp.add(actionData); return temp; }); } @CapabilityMethod - public synchronized List popPendingAction(String userId) { - List infos = pendingActions.get(userId); + public synchronized List popPendingAction(String userId) { + List infos = pendingActions.get(userId); pendingActions.remove(userId); return infos; } @CapabilityMethod - public synchronized void putPreparedAction(String uuid, MetaActionInfo metaActionInfo) { - preparedActions.computeIfAbsent(uuid, k -> { - List temp = new ArrayList<>(); - temp.add(metaActionInfo); - return temp; - }); - } - - @CapabilityMethod - public synchronized List popPreparedAction(String userId) { - List infos = preparedActions.get(userId); - preparedActions.remove(userId); - return infos; - } - - @CapabilityMethod - public List listPreparedAction(String userId) { - return preparedActions.get(userId); - } - - @CapabilityMethod - public List listPendingAction(String userId) { + public List listPendingAction(String userId) { return pendingActions.get(userId); } @@ -101,10 +125,11 @@ public class ActionCore extends PartnerCore { return null; } VectorClient vectorClient = VectorClient.INSTANCE; - //计算本次输入的向量 + // 计算本次输入的向量 float[] vector = vectorClient.compute(input); - if (vector == null) return null; - //与现有缓存比对,将匹配到的收集并返回 + if (vector == null) + return null; + // 与现有缓存比对,将匹配到的收集并返回 return actionCache.parallelStream() .filter(ActionCacheData::isActivated) .filter(data -> { @@ -136,9 +161,188 @@ public class ActionCore extends PartnerCore { } } - executor.execute(() -> adjustMatchAndPassed(matchAndPassed, inputVector, input, vectorClient)); - executor.execute(() -> adjustMatchNotPassed(matchNotPassed, vectorClient)); - executor.execute(() -> adjustNotMatchPassed(notMatchPassed, inputVector, input, vectorClient)); + platformExecutor.execute(() -> adjustMatchAndPassed(matchAndPassed, inputVector, input, vectorClient)); + platformExecutor.execute(() -> adjustMatchNotPassed(matchNotPassed, vectorClient)); + platformExecutor.execute(() -> adjustNotMatchPassed(notMatchPassed, inputVector, input, vectorClient)); + } + + @CapabilityMethod + public ExecutorService getExecutor(ExecutorType type) { + return switch (type) { + case VIRTUAL -> virtualExecutor; + case PLATFORM -> platformExecutor; + }; + } + + @CapabilityMethod + public Map listAvailableActions() { + return existedMetaActions; + } + + @CapabilityMethod + public synchronized PhaserRecord putPhaserRecord(Phaser phaser, ActionData actionData) { + PhaserRecord record = new PhaserRecord(phaser, actionData); + phaserRecords.add(record); + return record; + } + + @CapabilityMethod + public synchronized void removePhaserRecord(Phaser phaser) { + PhaserRecord remove = null; + for (PhaserRecord record : phaserRecords) { + if (record.phaser().equals(phaser)) { + remove = record; + } + } + + if (remove != null) { + phaserRecords.remove(remove); + } + } + + @CapabilityMethod + public PhaserRecord getPhaserRecord(String tendency, String source) { + for (PhaserRecord record : phaserRecords) { + ActionData data = record.actionData(); + if (data.getTendency().equals(tendency) && data.getSource().equals(source)) { + return record; + } + } + throw new ActionDataNotFoundException("未找到对应的 Phaser 记录: tendency=" + tendency + ", source=" + source); + } + + @CapabilityMethod + public MetaAction loadMetaAction(@NonNull String actionKey) { + MetaActionInfo metaActionInfo = existedMetaActions.get(actionKey); + if (metaActionInfo == null) { + throw new MetaActionNotFoundException("未找到对应的行动程序信息" + actionKey); + } + + String[] split = actionKey.split("::"); + if (split.length < 2) { + throw new MetaActionNotFoundException("未找到对应的行动程序,原因: 传入的 actionKey(" + actionKey + ") 存在异常"); + } + return new MetaAction( + split[1], + metaActionInfo.isIo(), + MetaAction.Type.MCP, + split[0] + ); + } + + @CapabilityMethod + public List listPhaserRecords() { + return phaserRecords; + } + + @CapabilityMethod + public MetaActionInfo loadMetaActionInfo(@NonNull String actionKey) { + MetaActionInfo info = existedMetaActions.get(actionKey); + if (info == null) { + throw new MetaActionNotFoundException("未找到对应的行动程序描述信息: " + actionKey); + } + return info; + } + + @CapabilityMethod + public boolean checkExists(String... actionKeys) { + return existedMetaActions.keySet().containsAll(Arrays.asList(actionKeys)); + } + + @CapabilityMethod + public RunnerClient runnerClient() { + return runnerClient; + } + + @CapabilityMethod + public void handleInterventions(List interventions, ActionData actionData) { + // 加载数据 + if (actionData == null) { + return; + } + + // 加锁确保同步 + synchronized (actionData.getStatus()) { + applyInterventions(interventions, actionData); + } + } + + private void applyInterventions(List interventions, ActionData actionData) { + boolean rebuildCleanTag = false; + + interventions.sort(Comparator.comparingInt(MetaIntervention::getOrder)); + + for (MetaIntervention intervention : interventions) { + List actions = intervention.getActions() + .stream() + .map(this::loadMetaAction) + .toList(); + + switch (intervention.getType()) { + case InterventionType.APPEND -> handleAppend(actionData, intervention.getOrder(), actions); + case InterventionType.INSERT -> handleInsert(actionData, intervention.getOrder(), actions); + case InterventionType.DELETE -> handleDelete(actionData, intervention.getOrder(), actions); + case InterventionType.CANCEL -> handleCancel(actionData); + case InterventionType.REBUILD -> { + if (!rebuildCleanTag) { + cleanActionData(actionData); + rebuildCleanTag = true; + } + handleRebuild(actionData, intervention.getOrder(), actions); + } + } + } + + } + + /** + * 在未进入执行阶段的行动单元组新增新的行动 + */ + private void handleAppend(ActionData actionData, int order, List actions) { + if (order <= actionData.getExecutingStage()) + return; + + actionData.getActionChain().put(order, actions); + } + + /** + * 在未进入执行阶段和正处于行动阶段的行动单元组插入新的行动 + */ + private void handleInsert(ActionData actionData, int order, List actions) { + if (order < actionData.getExecutingStage()) + return; + + actionData.getActionChain().computeIfAbsent(order, k -> new ArrayList<>()).addAll(actions); + } + + private void handleDelete(ActionData actionData, int order, List actions) { + if (order <= actionData.getExecutingStage()) + return; + + Map> actionChain = actionData.getActionChain(); + if (actionChain.containsKey(order)) { + actionChain.get(order).removeAll(actions); + if (actionChain.get(order).isEmpty()) { + actionChain.remove(order); + } + } + } + + private void handleCancel(ActionData actionData) { + actionData.setStatus(ActionData.ActionStatus.FAILED); + actionData.setResult("行动取消"); + } + + private void handleRebuild(ActionData actionData, int order, List actions) { + Map> actionChain = actionData.getActionChain(); + actionChain.put(order, actions); + } + + private void cleanActionData(ActionData actionData) { + actionData.getActionChain().clear(); + actionData.setExecutingStage(0); + actionData.setStatus(ActionData.ActionStatus.PREPARE); + actionData.getHistory().clear(); } /** @@ -148,9 +352,10 @@ public class ActionCore extends PartnerCore { * @param inputVector 本次输入内容的语义向量 * @param vectorClient 向量客户端 */ - private void adjustMatchAndPassed(List matchAndPassed, float[] inputVector, String input, VectorClient vectorClient) { + private void adjustMatchAndPassed(List matchAndPassed, float[] inputVector, String input, + VectorClient vectorClient) { matchAndPassed.forEach(adjustData -> { - //获取原始缓存条目 + // 获取原始缓存条目 String tendency = adjustData.getTendency(); ActionCacheData primaryCacheData = selectCacheData(tendency); if (primaryCacheData == null) { @@ -169,7 +374,7 @@ public class ActionCore extends PartnerCore { private void adjustMatchNotPassed(List matchNotPassed, VectorClient vectorClient) { List toRemove = new ArrayList<>(); matchNotPassed.forEach(adjustData -> { - //获取原始缓存条目 + // 获取原始缓存条目 String tendency = adjustData.getTendency(); ActionCacheData primaryCacheData = selectCacheData(tendency); if (primaryCacheData == null) { @@ -189,13 +394,13 @@ public class ActionCore extends PartnerCore { /** * 针对未命中但评估通过的缓存做出调整: *
    - *

    如果存在缓存条目

    - *
  1. - * 若已生效,但此时未匹配到则说明尚未生效或者阈值、向量{@link ActionCacheData#getInputVector()}存在问题,调低阈值,同时带权移动平均 - *
  2. - *
  3. - * 若未生效,则只增加计数并带权移动平均 - *
  4. + *

    如果存在缓存条目

    + *
  5. + * 若已生效,但此时未匹配到则说明尚未生效或者阈值、向量{@link ActionCacheData#getInputVector()}存在问题,调低阈值,同时带权移动平均 + *
  6. + *
  7. + * 若未生效,则只增加计数并带权移动平均 + *
  8. *
* 如果不存在缓存条目,则新增并填充字段 * @@ -204,9 +409,10 @@ public class ActionCore extends PartnerCore { * @param input 本次输入内容 * @param vectorClient 向量客户端 */ - private void adjustNotMatchPassed(List notMatchPassed, float[] inputVector, String input, VectorClient vectorClient) { + private void adjustNotMatchPassed(List notMatchPassed, float[] inputVector, String input, + VectorClient vectorClient) { notMatchPassed.forEach(adjustData -> { - //获取原始缓存条目 + // 获取原始缓存条目 String tendency = adjustData.getTendency(); ActionCacheData primaryCacheData = selectCacheData(tendency); float[] tendencyVector = vectorClient.compute(tendency); @@ -232,4 +438,9 @@ public class ActionCore extends PartnerCore { protected String getCoreKey() { return "action-core"; } + + public enum ExecutorType { + VIRTUAL, PLATFORM + } + } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionData.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionData.java deleted file mode 100644 index 4fed2443..00000000 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionData.java +++ /dev/null @@ -1,11 +0,0 @@ -package work.slhaf.partner.core.action.entity; - -import lombok.Data; - -@Data -public class ActionData { - private String key; - private String[] array; - private String reason; - private String description; -} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionData.kt b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionData.kt new file mode 100644 index 00000000..9aededd8 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionData.kt @@ -0,0 +1,143 @@ +package work.slhaf.partner.core.action.entity + +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.HistoryAction +import java.time.ZonedDateTime +import java.util.* + +/** + * 行动模块传递的行动数据,包含行动uuid、倾向、状态、行动链、结果、发起原因、行动描述等信息。 + */ +sealed class ActionData { + /** + * 行动ID + */ + val uuid: String = UUID.randomUUID().toString() + + /** + * 行动倾向 + */ + abstract val tendency: String + + /** + * 行动状态 + */ + var status: ActionStatus = ActionStatus.PREPARE + + /** + * 行动链 + */ + abstract val actionChain: MutableMap> + + /** + * 行动阶段(当前阶段) + */ + var executingStage: Int = 0 + + /** + * 行动结果 + */ + lateinit var result: String + + val history: MutableMap> = mutableMapOf() + + /** + * 修复上下文 + */ + val additionalContext: MutableMap> = mutableMapOf() + + /** + * 行动原因 + */ + abstract val reason: String + + /** + * 行动描述 + */ + abstract val description: String + + /** + * 行动来源 + */ + abstract val source: String + + enum class ActionStatus { + /** + * 执行成功 + */ + SUCCESS, + + /** + * 执行失败 + */ + FAILED, + + /** + * 执行中 + */ + EXECUTING, + + /** + * 暂时中断 + */ + INTERRUPTED, + + /** + * 预备执行 + */ + PREPARE + } +} + +/** + * 计划行动数据类,继承自{@link ActionData},扩展了属性{@link ScheduledActionData#type}和{@link ScheduledActionData#scheduleContent},用于标识计划类型(单次还是周期性任务)和计划内容 + */ +data class ScheduledActionData( + override val tendency: String, + override val actionChain: MutableMap>, + override val reason: String, + override val description: String, + override val source: String, + val scheduleType: ScheduleType, + val scheduleContent: String, +) : ActionData() { + + val scheduleHistories = ArrayList() + + fun recordAndReset() { + val newHistory = ScheduleHistory(ZonedDateTime.now(), result, history.toMap()) + scheduleHistories.add(newHistory) + + additionalContext.clear() + executingStage = 0 + for (entry in actionChain) { + for (action in entry.value) { + action.params.clear() + action.result.reset() + } + } + + status = ActionStatus.PREPARE + } + + enum class ScheduleType { + CYCLE, + ONCE + } + + data class ScheduleHistory( + val endTime: ZonedDateTime, + val result: String, + val history: Map> + ) +} + +/** + * 即时行动数据类 + */ +data class ImmediateActionData( + override val tendency: String, + override val actionChain: MutableMap>, + override val reason: String, + override val description: String, + override val source: String, +) : ActionData() diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionFileMetaData.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionFileMetaData.java new file mode 100644 index 00000000..18094e6b --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionFileMetaData.java @@ -0,0 +1,10 @@ +package work.slhaf.partner.core.action.entity; + +import lombok.Data; + +@Data +public class ActionFileMetaData { + private String content; + private String name; + private String ext; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionStatus.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionStatus.java deleted file mode 100644 index 31256076..00000000 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package work.slhaf.partner.core.action.entity; - -public enum ActionStatus { - SUCCESS, FAILED, EXECUTING, WAITING, PREPARE -} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/GeneratedData.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/GeneratedData.java new file mode 100644 index 00000000..512e33c8 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/GeneratedData.java @@ -0,0 +1,15 @@ +package work.slhaf.partner.core.action.entity; + +import com.alibaba.fastjson2.JSONObject; +import lombok.Data; + +import java.util.List; + +@Data +public class GeneratedData { + private List dependencies; + private String code; + private String codeType; + private boolean serialize; + private JSONObject responseSchema; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ImmediateActionInfo.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ImmediateActionInfo.java deleted file mode 100644 index f0ba45ff..00000000 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ImmediateActionInfo.java +++ /dev/null @@ -1,9 +0,0 @@ -package work.slhaf.partner.core.action.entity; - -import lombok.Data; -import lombok.EqualsAndHashCode; - -@EqualsAndHashCode(callSuper = true) -@Data -public class ImmediateActionInfo extends MetaActionInfo{ -} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionType.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/McpData.java similarity index 50% rename from Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionType.java rename to Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/McpData.java index 2354929e..aa8121a7 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionType.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/McpData.java @@ -1,5 +1,5 @@ package work.slhaf.partner.core.action.entity; -public enum ActionType { - IMMEDIATE, PLANNING +public class McpData { + } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaAction.kt b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaAction.kt new file mode 100644 index 00000000..ca201293 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaAction.kt @@ -0,0 +1,73 @@ +package work.slhaf.partner.core.action.entity + + +/** + * 行动链中的单一元素,封装了调用外部行动程序的必要信息与结果容器,可被[work.slhaf.partner.core.action.ActionCapability]执行 + */ +data class MetaAction( + /** + * 行动name,用于标识行动程序 + */ + val name: String, + /** + * 是否IO密集,用于决定使用何种线程池 + */ + val io: Boolean = false, + /** + * 行动程序类型,可分为 MCP、ORIGIN 两种,前者对应读取到的 MCP Tool、后者对应生成的临时行动程序 + */ + val type: Type, + /** + * 当类型为 MCP 时,该字段对应相应 MCP Client 注册时生成的 id; + * 当类型为 ORIGIN 时,该字段对应相应的磁盘路径字符串 + */ + val location: String, +) { + + /** + * 行动程序可接受的参数,由调用处设置 + */ + val params: MutableMap = mutableMapOf() + + /** + * 行动结果,包括执行状态和相应内容(执行结果或者错误信息) + */ + val result = Result() + + val key: String + /** + * actionKey 将由 location+name 共同定位 + * + * @return actionKey + */ + get() = "$location::$name" + + class Result { + var status = Status.WAITING + var data: String? = null + + fun reset() { + status = Status.WAITING + data = null + } + + enum class Status { + SUCCESS, + FAILED, + WAITING + } + } + + enum class Type { + /** + * 将调用的 MCP 工具,可包括远程、本地任意服务 + */ + MCP, + + /** + * 适用于‘临时生成’的行动程序,在生成后根据序列化选项及执行情况,进行持久化 + */ + ORIGIN + } + +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaActionInfo.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaActionInfo.java index bc2abe4a..c0b4a8af 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaActionInfo.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaActionInfo.java @@ -1,12 +1,25 @@ package work.slhaf.partner.core.action.entity; +import com.alibaba.fastjson2.JSONObject; import lombok.Data; +import java.util.List; +import java.util.Map; + @Data -public abstract class MetaActionInfo { - protected String uuid; - protected String tendency; - protected ActionStatus status; - protected ActionData actionData; - protected String Result; +public class MetaActionInfo { + private boolean io; + + private Map params; + private String description; + private List tags; + + private List preActions; + private List postActions; + /** + * 是否严格依赖前置行动的成功执行,若为true且前置行动失败则不执行该行动,后置任务多为触发式。默认即执行。 + */ + private boolean strictDependencies; + + private JSONObject responseSchema; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java new file mode 100644 index 00000000..c0c85289 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java @@ -0,0 +1,33 @@ +package work.slhaf.partner.core.action.entity; + +import work.slhaf.partner.core.action.entity.ActionData.ActionStatus; + +import java.util.concurrent.Phaser; + +public record PhaserRecord(Phaser phaser, ActionData actionData) { + + public void fail() { + actionData.setStatus(ActionStatus.FAILED); + } + + /** + * 负责将 ActionData 的状态设置为 INTERRUPTED + * 同时循环检查进行阻塞 + */ + public void interrupt() { + actionData.setStatus(ActionStatus.INTERRUPTED); + while (actionData().getStatus() == ActionStatus.INTERRUPTED) { + try { + Thread.sleep(500); + } catch (InterruptedException ignored) { + } + } + } + + /** + * 将状态重新设置为 EXECUTING ,恢复 interrupt 阻塞状态 + */ + public void complete() { + actionData().setStatus(ActionStatus.EXECUTING); + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ScheduledActionInfo.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ScheduledActionInfo.java deleted file mode 100644 index ddf86503..00000000 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ScheduledActionInfo.java +++ /dev/null @@ -1,15 +0,0 @@ -package work.slhaf.partner.core.action.entity; - -import lombok.Data; -import lombok.EqualsAndHashCode; - -@EqualsAndHashCode(callSuper = true) -@Data -public class ScheduledActionInfo extends MetaActionInfo { - private ScheduledType type; - private String scheduleContent; //如果为周期,则对应cron表达式,如果为一次性,则对应为LocalDateTime字符串 - - enum ScheduledType { - CYCLE, ONCE - } -} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionCacheData.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/cache/ActionCacheData.java similarity index 99% rename from Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionCacheData.java rename to Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/cache/ActionCacheData.java index caba8198..38deccd7 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionCacheData.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/cache/ActionCacheData.java @@ -1,4 +1,4 @@ -package work.slhaf.partner.core.action.entity; +package work.slhaf.partner.core.action.entity.cache; import lombok.Data; import work.slhaf.partner.common.vector.VectorClient; diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/CacheAdjustData.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/cache/CacheAdjustData.java similarity index 75% rename from Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/CacheAdjustData.java rename to Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/cache/CacheAdjustData.java index b0289fde..d2fadd26 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/CacheAdjustData.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/cache/CacheAdjustData.java @@ -1,4 +1,4 @@ -package work.slhaf.partner.core.action.entity; +package work.slhaf.partner.core.action.entity.cache; import lombok.Data; diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/CacheAdjustMetaData.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/cache/CacheAdjustMetaData.java similarity index 73% rename from Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/CacheAdjustMetaData.java rename to Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/cache/CacheAdjustMetaData.java index 3afed553..04cb8dff 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/CacheAdjustMetaData.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/cache/CacheAdjustMetaData.java @@ -1,4 +1,4 @@ -package work.slhaf.partner.core.action.entity; +package work.slhaf.partner.core.action.entity.cache; import lombok.Data; diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionDataNotFoundException.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionDataNotFoundException.java new file mode 100644 index 00000000..8fd351bd --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionDataNotFoundException.java @@ -0,0 +1,13 @@ +package work.slhaf.partner.core.action.exception; + +import work.slhaf.partner.api.agent.runtime.exception.AgentRuntimeException; + +public class ActionDataNotFoundException extends AgentRuntimeException { + public ActionDataNotFoundException(String message) { + super(message); + } + + public ActionDataNotFoundException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionInitFailedException.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionInitFailedException.java new file mode 100644 index 00000000..4e3e2849 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionInitFailedException.java @@ -0,0 +1,13 @@ +package work.slhaf.partner.core.action.exception; + +import work.slhaf.partner.api.agent.runtime.exception.AgentLaunchFailedException; + +public class ActionInitFailedException extends AgentLaunchFailedException { + public ActionInitFailedException(String message, Throwable cause) { + super(message, cause); + } + + public ActionInitFailedException(String message) { + super(message); + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionLoadFailedException.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionLoadFailedException.java new file mode 100644 index 00000000..7cded2a6 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionLoadFailedException.java @@ -0,0 +1,13 @@ +package work.slhaf.partner.core.action.exception; + +import work.slhaf.partner.api.agent.runtime.exception.AgentRuntimeException; + +public class ActionLoadFailedException extends AgentRuntimeException { + public ActionLoadFailedException(String message) { + super(message); + } + + public ActionLoadFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionSerializeFailedException.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionSerializeFailedException.java new file mode 100644 index 00000000..1f6d411f --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/ActionSerializeFailedException.java @@ -0,0 +1,13 @@ +package work.slhaf.partner.core.action.exception; + +import work.slhaf.partner.api.agent.runtime.exception.AgentRuntimeException; + +public class ActionSerializeFailedException extends AgentRuntimeException { + public ActionSerializeFailedException(String message) { + super(message); + } + + public ActionSerializeFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/MetaActionNotFoundException.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/MetaActionNotFoundException.java new file mode 100644 index 00000000..0c59e0b7 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/exception/MetaActionNotFoundException.java @@ -0,0 +1,13 @@ +package work.slhaf.partner.core.action.exception; + +import work.slhaf.partner.api.agent.runtime.exception.AgentRuntimeException; + +public class MetaActionNotFoundException extends AgentRuntimeException { + public MetaActionNotFoundException(String message) { + super(message); + } + + public MetaActionNotFoundException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/runner/LocalRunnerClient.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/runner/LocalRunnerClient.java new file mode 100644 index 00000000..1e2c5a42 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/runner/LocalRunnerClient.java @@ -0,0 +1,1571 @@ +package work.slhaf.partner.core.action.runner; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import io.modelcontextprotocol.client.McpClient; +import io.modelcontextprotocol.client.McpSyncClient; +import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport; +import io.modelcontextprotocol.client.transport.ServerParameters; +import io.modelcontextprotocol.client.transport.StdioClientTransport; +import io.modelcontextprotocol.client.transport.customizer.McpSyncHttpClientRequestCustomizer; +import io.modelcontextprotocol.common.McpTransportContext; +import io.modelcontextprotocol.json.McpJsonMapper; +import io.modelcontextprotocol.server.McpServer; +import io.modelcontextprotocol.server.McpStatelessAsyncServer; +import io.modelcontextprotocol.server.McpStatelessServerFeatures; +import io.modelcontextprotocol.spec.McpClientTransport; +import io.modelcontextprotocol.spec.McpSchema; +import javassist.NotFoundException; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; +import work.slhaf.partner.common.mcp.InProcessMcpTransport; +import work.slhaf.partner.core.action.entity.ActionFileMetaData; +import work.slhaf.partner.core.action.entity.MetaAction; +import work.slhaf.partner.core.action.entity.MetaActionInfo; +import work.slhaf.partner.core.action.exception.ActionInitFailedException; +import work.slhaf.partner.core.action.exception.ActionSerializeFailedException; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URI; +import java.net.http.HttpRequest; +import java.nio.charset.StandardCharsets; +import java.nio.file.*; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiFunction; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static work.slhaf.partner.common.util.PathUtil.buildPathStr; + +@Slf4j +public class LocalRunnerClient extends RunnerClient { + + private final String TMP_ACTION_PATH; + private final String DYNAMIC_ACTION_PATH; + private final String MCP_SERVER_PATH; + private final String MCP_DESC_PATH; + + private final String MCP_NAME_DESC = "mcp-desc"; + private final String MCP_NAME_DYNAMIC = "mcp-dynamic"; + + /** + * 存储包括 DescMcp、DynamicActionMcp、CommonMcp 在内的所有 MCP Server 对应的客户端 + *
+ * 自身需要针对 CommonMcp 维护一个存储 McpServers.json 文件的目录 + *
+ * 相关目录按照以下格式组织: + *

+ * MCP_SERVER_PATH/mcp-server.json + *

+ */ + private final Map mcpClients = new HashMap<>(); + /** + * 动态生成的行动程序都将挂载至该 McpServer + *
+ * 相关目录按照以下格式进行组织: + *

+ * DYNAMIC_ACTION_PATH/action 名称/ + *

+ * 每个action子目录下,除了相关的程序文件外,将额外提供一个 .meta.json 文件来提供相关描述文件, + * 该描述文件将携带 McpTools、MetaActionInfo 相关的所有信息, + * 故 McpDescServer 将只负责 Common Mcp Servers 的额外描述文件 + */ + private McpStatelessAsyncServer dynamicActionMcpServer; + /** + * 负责监听常规 MCP Server 的描述文件(描述文件主要用于添加原本 MCP Tools 不携带的信息,如前置依赖、后置依赖、是否 IO 密集等 + *
+ * 目录按照以下格式组织: + *

+ * MCP_DESC_PATH/server::toolName.desc.json + *

+ * 该 MCP Server-Client 的作用为: 与 CommonMcp Clients 配合,补齐第三方 MCP 服务的描述信息 + */ + private McpStatelessAsyncServer mcpDescServer; + + public LocalRunnerClient(ConcurrentHashMap existedMetaActions, ExecutorService executor, @Nullable String baseActionPath) { + super(existedMetaActions, executor, baseActionPath); + this.TMP_ACTION_PATH = buildPathStr(ACTION_PATH, "tmp"); + this.DYNAMIC_ACTION_PATH = buildPathStr(ACTION_PATH, "dynamic"); + this.MCP_SERVER_PATH = buildPathStr(ACTION_PATH, "mcp"); + this.MCP_DESC_PATH = buildPathStr(MCP_SERVER_PATH, "desc"); + + createPath(TMP_ACTION_PATH); + createPath(DYNAMIC_ACTION_PATH); + createPath(MCP_SERVER_PATH); + createPath(MCP_DESC_PATH); + + try { + registerDescMcp(); + registerDynamicActionMcp(); + registerCommonMcp(); + } catch (IOException e) { + throw new ActionInitFailedException("目录监听器启动失败", e); + } + setupShutdownHook(); + } + + private void registerCommonMcp() throws IOException { + val ctx = new WatchContext(Path.of(MCP_SERVER_PATH), FileSystems.getDefault().newWatchService()); + val common = new LocalWatchEventProcessor.Common(existedMetaActions, mcpClients, mcpClients.get(MCP_NAME_DESC), ctx); + new LocalWatchServiceBuild.BuildRegistry(ctx) + .initialLoad(common.buildLoad()) + .registerCreate(common.buildCreate()) + .registerDelete(common.buildDelete()) + .registerModify(common.buildModify()) + .registerOverflow(common.buildOverflow()) + .commit(executor); + log.info("CommonMcp 文件监听注册完毕"); + } + + private void registerDescMcp() throws IOException { + InProcessMcpTransport.Pair pair = InProcessMcpTransport.pair(); + McpSchema.ServerCapabilities serverCapabilities = McpSchema.ServerCapabilities.builder() + .resources(true, true) + .build(); + mcpDescServer = McpServer.async(pair.serverSide()) + .capabilities(serverCapabilities) + .jsonMapper(McpJsonMapper.getDefault()) + .build(); + registerDescMcpWatch(); + log.info("DescMcp 文件监听注册完毕"); + registerMcpClient(MCP_NAME_DESC, pair.clientSide(), 10); + log.info("DescMcp 注册完毕"); + + } + + private void registerDescMcpWatch() throws IOException { + WatchContext ctx = new WatchContext(Path.of(MCP_DESC_PATH), FileSystems.getDefault().newWatchService()); + LocalWatchEventProcessor.Desc desc = new LocalWatchEventProcessor.Desc(existedMetaActions, mcpDescServer, ctx); + new LocalWatchServiceBuild.BuildRegistry(ctx) + .initialLoad(desc.buildLoad()) + .registerCreate(desc.buildCreate()) + .registerDelete(desc.buildDelete()) + .registerModify(desc.buildModify()) + .registerOverflow(desc.buildOverflow()) + .watchAll(true) + .commit(executor); + } + + private void registerDynamicActionMcp() throws IOException { + InProcessMcpTransport.Pair pair = InProcessMcpTransport.pair(); + McpSchema.ServerCapabilities serverCapabilities = McpSchema.ServerCapabilities.builder() + .tools(true) + .build(); + dynamicActionMcpServer = McpServer.async(pair.serverSide()) + .capabilities(serverCapabilities) + .jsonMapper(McpJsonMapper.getDefault()) + .build(); + // Tools 的执行逻辑应当高度一致化,但仍需要独立为不同 Tool + // 初始的加载逻辑通过 initialLoad 加载 + // 后续的动态更新通过对应的 event 事件触发 + registerDynamicActionMcpWatch(); + log.info("DynamicActionMcp 文件监听注册完毕"); + registerMcpClient(MCP_NAME_DYNAMIC, pair.clientSide(), 10); + log.info("DynamicActionMcp 注册完毕"); + } + + private void registerDynamicActionMcpWatch() throws IOException { + // MODIFY、CREATE、DELETE、OVERFLOW 都需要不同的处理方式 + WatchContext ctx = new WatchContext(Path.of(DYNAMIC_ACTION_PATH), FileSystems.getDefault().newWatchService()); + LocalWatchEventProcessor.Dynamic dynamic = new LocalWatchEventProcessor.Dynamic(existedMetaActions, dynamicActionMcpServer, ctx); + new LocalWatchServiceBuild.BuildRegistry(ctx) + .initialLoad(dynamic.buildLoad()) + .registerCreate(dynamic.buildCreate()) + .registerModify(dynamic.buildModify()) + .registerDelete(dynamic.buildDelete()) + .registerOverflow(dynamic.buildOverflow()) + .watchAll(true) + .commit(executor); + } + + @Override + protected RunnerResponse doRun(MetaAction metaAction) { + log.debug("执行行动: {}", metaAction); + RunnerResponse response; + try { + response = switch (metaAction.getType()) { + case MetaAction.Type.MCP -> doRunWithMcp(metaAction); + case MetaAction.Type.ORIGIN -> doRunWithOrigin(metaAction); + }; + } catch (Exception e) { + response = new RunnerResponse(); + response.setOk(false); + response.setData(e.getLocalizedMessage()); + } + log.debug("行动执行结果: {}", response); + return response; + } + + private RunnerResponse doRunWithOrigin(MetaAction metaAction) { + RunnerResponse response = new RunnerResponse(); + File file = new File(metaAction.getLocation()); + String ext = FileUtil.getSuffix(file); + if (ext == null || ext.isEmpty()) { + response.setOk(false); + response.setData("未知文件类型"); + return response; + } + String[] commands = SystemExecHelper.buildCommands(ext, metaAction.getParams(), file.getAbsolutePath()); + if (commands == null || commands.length == 0) { + response.setOk(false); + response.setData("不支持的文件类型: " + file.getName()); + } + SystemExecHelper.Result execResult = SystemExecHelper.exec(commands); + response.setOk(execResult.isOk()); + response.setData(execResult.getTotal()); + return response; + } + + private RunnerResponse doRunWithMcp(MetaAction metaAction) { + RunnerResponse response = new RunnerResponse(); + McpSyncClient mcpClient = mcpClients.get(metaAction.getLocation()); + McpSchema.CallToolRequest callToolRequest = McpSchema.CallToolRequest.builder() + .name(metaAction.getName()) + .arguments(metaAction.getParams()) + .build(); + McpSchema.CallToolResult callToolResult = mcpClient.callTool(callToolRequest); + val callToolResultError = callToolResult.isError(); + if (callToolResultError == null) { + response.setOk(false); + } else { + response.setOk(!callToolResultError); + } + response.setData(callToolResult.structuredContent().toString()); + return response; + } + + @Override + public String buildTmpPath(String actionKey, String codeType) { + return Path.of(TMP_ACTION_PATH, System.currentTimeMillis() + "-" + actionKey + codeType).toString(); + } + + @Override + public void tmpSerialize(MetaAction tempAction, String code, String codeType) throws IOException { + log.debug("行动程序临时序列化: {}", tempAction); + Path path = Path.of(tempAction.getLocation()); + File file = path.toFile(); + file.createNewFile(); + Files.writeString(path, code); + log.debug("临时序列化完毕"); + } + + private static @NotNull Path createActionDir(String baseName, Path baseDir) { + Path actionDir = null; + + // 原子地“抢占”目录名 + for (int i = 0; ; i++) { + String dirName = (i == 0) ? baseName : baseName + "(" + i + ")"; + Path candidate = baseDir.resolve(dirName); + + try { + Files.createDirectory(candidate); // 原子操作 + actionDir = candidate; + break; + } catch (FileAlreadyExistsException ignored) { + // 继续尝试下一个名字 + } catch (IOException e) { + throw new ActionSerializeFailedException( + "无法创建行动目录: " + candidate.toAbsolutePath(), e + ); + } + } + return actionDir; + } + + @Override + public void persistSerialize(MetaActionInfo metaActionInfo, ActionFileMetaData fileMetaData) { + log.debug("行动程序持久序列化: {}", metaActionInfo); + val baseDir = Path.of(DYNAMIC_ACTION_PATH); + + if (!Files.isDirectory(baseDir)) { + throw new ActionSerializeFailedException( + "目录不存在或不可用: " + baseDir.toAbsolutePath() + ); + } + + val baseName = fileMetaData.getName(); + val ext = fileMetaData.getExt(); + + val actionDir = createActionDir(baseName, baseDir); + + // 使用临时文件写入内容 + val runTmp = actionDir.resolve("run." + ext + ".tmp"); + val descTmp = actionDir.resolve("desc.json.tmp"); + + val runFinal = actionDir.resolve("run." + ext); + val descFinal = actionDir.resolve("desc.json"); + + try { + Files.writeString(runTmp, fileMetaData.getContent()); + Files.writeString(descTmp, JSONObject.toJSONString(metaActionInfo)); + + // 原子提交 + Files.move(runTmp, runFinal, StandardCopyOption.ATOMIC_MOVE); + Files.move(descTmp, descFinal, StandardCopyOption.ATOMIC_MOVE); + } catch (IOException e) { + // 失败清理 + safeDelete(runTmp); + safeDelete(descTmp); + safeDelete(runFinal); + safeDelete(descFinal); + safeDelete(actionDir); + throw new ActionSerializeFailedException("行动文件写入失败", e); + } + log.debug("持久序列化结束"); + } + + private void safeDelete(Path path) { + try { + if (Files.exists(path)) { + Files.delete(path); + } + } catch (IOException ignored) { + } + } + + + @Override + public JSONObject listSysDependencies() { + // 先只列出系统/环境的 Python 依赖 + // TODO 在 AgentConfigManager 内配置启用的脚本语言及对应的扩展名 + // 这里的逻辑后续需要替换为“根据 AgentConfigManager 读取到的脚本语言启用情况,遍历并列出当前系统环境依赖” + // 还需要将返回值调整为相应的数据类 + // 后续还需要将不同语言的处理逻辑分散到不同方法内,这里为了验证,先写死在当前方法 + JSONObject sysDependencies = new JSONObject(); + sysDependencies.put("language", "Python"); + JSONArray dependencies = sysDependencies.putArray("dependencies"); + SystemExecHelper.Result pyResult = SystemExecHelper.exec("pip", "list", "--format=freeze"); + System.out.println(pyResult); + if (pyResult.isOk()) { + List resultList = pyResult.getResultList(); + for (String result : resultList) { + JSONObject element = dependencies.addObject(); + String[] split = result.split("=="); + element.put("name", split[0]); + element.put("version", split[1]); + } + } else { + JSONObject element = dependencies.addObject(); + element.put("error", pyResult.getTotal()); + } + return sysDependencies; + } + + private void registerMcpClient(String id, McpClientTransport clientTransport, int timeout) { + McpSyncClient client = McpClient.sync(clientTransport) + .requestTimeout(Duration.ofSeconds(timeout)) + .clientInfo(new McpSchema.Implementation(id, "PARTNER")) + // 行动程序(现 MCP Tool)的描述文本将直接由resources返回 + // 原因: ToolChange 发送的内容侧重调用,缺少可承担描述文本的字段 + // ResourcesChange 事件传递的 Resource 可以由 Client 读取内容 + // 预计在 Server 侧,收到客户端发送的新的行动程序信息,该信息由客户端处补充后,将其放置在指定位置 + // 并写入描述文件、发起 ResourcesChange 事件 + .build(); + mcpClients.put(id, client); + } + + private void setupShutdownHook() { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + dynamicActionMcpServer.close(); + mcpDescServer.close(); + this.mcpClients.forEach((id, client) -> { + client.close(); + log.info("[{}] MCP-Client 已关闭", id); + }); + })); + } + + private interface LocalWatchServiceBuild { + LocalWatchServiceBuild registerCreate(EventHandler handler); + + LocalWatchServiceBuild registerModify(EventHandler handler); + + LocalWatchServiceBuild registerDelete(EventHandler handler); + + LocalWatchServiceBuild registerOverflow(EventHandler handler); + + LocalWatchServiceBuild initialLoad(InitLoader loader); + + LocalWatchServiceBuild watchAll(boolean watchAll); + + void commit(ExecutorService executor); + + interface EventHandler { + void handle(Path thisDir, Path context); + } + + interface InitLoader { + void load(); + } + + class BuildRegistry implements LocalWatchServiceBuild { + + private final Map, EventHandler> handlers = new HashMap<>(); + private InitLoader initLoader; + private final WatchContext ctx; + private boolean watchAll = false; + + private BuildRegistry(WatchContext ctx) { + this.ctx = ctx; + } + + @Override + public LocalWatchServiceBuild registerCreate(EventHandler handler) { + ctx.kinds.add(StandardWatchEventKinds.ENTRY_CREATE); + handlers.put(StandardWatchEventKinds.ENTRY_CREATE, handler); + return this; + } + + @Override + public LocalWatchServiceBuild registerModify(EventHandler handler) { + ctx.kinds.add(StandardWatchEventKinds.ENTRY_MODIFY); + handlers.put(StandardWatchEventKinds.ENTRY_MODIFY, handler); + return this; + } + + @Override + public LocalWatchServiceBuild registerDelete(EventHandler handler) { + ctx.kinds.add(StandardWatchEventKinds.ENTRY_DELETE); + handlers.put(StandardWatchEventKinds.ENTRY_DELETE, handler); + return this; + } + + @Override + public LocalWatchServiceBuild registerOverflow(EventHandler handler) { + ctx.kinds.add(StandardWatchEventKinds.OVERFLOW); + handlers.put(StandardWatchEventKinds.OVERFLOW, handler); + return this; + } + + @Override + public LocalWatchServiceBuild initialLoad(InitLoader loader) { + initLoader = loader; + return this; + } + + @Override + public LocalWatchServiceBuild watchAll(boolean watchAll) { + this.watchAll = watchAll; + return this; + } + + @Override + public void commit(ExecutorService executor) { + registerPath(); + if (initLoader != null) + initLoader.load(); + executor.execute(buildWatchTask()); + } + + private void registerPath() { + Path root = ctx.root; + WatchService watchService = ctx.watchService; + Map watchKeys = ctx.watchKeys; + try { + WatchEvent.Kind[] kindsArray = ctx.kinds.toArray(WatchEvent.Kind[]::new); + WatchKey rootKey = root.register(watchService, kindsArray); + watchKeys.put(rootKey, root); + if (!watchAll) { + return; + } + Stream walk = Files.list(root).filter(Files::isDirectory); + for (Path dir : walk.toList()) { + WatchKey key = dir.register(watchService, kindsArray); + watchKeys.put(key, dir); + log.debug("注册目录监听: {}", dir); + } + walk.close(); + } catch (IOException e) { + log.error("监听目录注册失败: ", e); + } + } + + private Runnable buildWatchTask() { + return () -> { + String rootStr = ctx.root.toString(); + log.info("行动程序目录监听器已启动,监听目录: {}", rootStr); + while (true) { + WatchKey key = null; + try { + key = ctx.watchService.take(); + List> events = key.pollEvents(); + for (WatchEvent e : events) { + WatchEvent.Kind kind = e.kind(); + Object context = e.context(); + log.debug("文件目录监听事件: {} - {} - {}", rootStr, kind.name(), context); + Path thisDir = (Path) key.watchable(); + EventHandler handler = handlers.get(kind); + if (handler == null) { + continue; + } + handler.handle(thisDir, context instanceof Path ? thisDir.resolve((Path) context) : null); + } + } catch (InterruptedException e) { + log.info("监听线程被中断,准备退出..."); + Thread.currentThread().interrupt(); // 恢复中断标志 + break; + } catch (ClosedWatchServiceException e) { + log.info("WatchService 已关闭,监听线程退出。"); + break; + } finally { + if (key != null) { + // reset 返回 false 表示该 key 已失效(目录被删、不可访问等) + boolean valid = key.reset(); + if (!valid) { + log.info("WatchKey 已失效,停止监听该目录: {}", key.watchable()); + ctx.watchKeys.remove(key); + if (key.watchable().equals(ctx.root)) { + try { + Files.createDirectories(ctx.root); + registerPath(); + if (initLoader != null) + initLoader.load(); + } catch (IOException e) { + log.error("重建根目录并重新注册监听失败: {}", ctx.root, e); + } + } + } + } + } + } + }; + } + + } + } + + private record WatchContext(Path root, WatchService watchService, Map watchKeys, + List> kinds) { + private WatchContext(Path root, WatchService watchService) { + this(root, watchService, new HashMap<>(), new ArrayList<>()); + } + } + + private sealed static abstract class LocalWatchEventProcessor permits LocalWatchEventProcessor.Dynamic, LocalWatchEventProcessor.Desc, LocalWatchEventProcessor.Common { + + protected final ConcurrentHashMap existedMetaActions; + protected final WatchContext ctx; + + private LocalWatchEventProcessor(ConcurrentHashMap existedMetaActions, WatchContext ctx) { + this.existedMetaActions = existedMetaActions; + this.ctx = ctx; + } + + protected abstract @NotNull LocalWatchServiceBuild.InitLoader buildLoad(); + + protected abstract @NotNull LocalWatchServiceBuild.EventHandler buildModify(); + + protected abstract @NotNull LocalWatchServiceBuild.EventHandler buildCreate(); + + protected abstract @NotNull LocalWatchServiceBuild.EventHandler buildDelete(); + + protected abstract @NotNull LocalWatchServiceBuild.EventHandler buildOverflow(); + + protected File[] loadFiles(Path root) { + // 在批量删除场景下,在接收到事件时目录等内容可能已被删除,此时不应该报错,而是返回一个‘异常值’ + if (!Files.isDirectory(root)) { + return null; + } + return root.toFile().listFiles(); + } + + @SuppressWarnings("LoggingSimilarMessage") + private static final class Dynamic extends LocalWatchEventProcessor { + + private final McpStatelessAsyncServer dynamicActionMcpServer; + + private Dynamic(ConcurrentHashMap existedMetaActions, McpStatelessAsyncServer dynamicActionMcpServer, WatchContext ctx) { + super(existedMetaActions, ctx); + this.dynamicActionMcpServer = dynamicActionMcpServer; + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + private boolean normalPath(Path path) { + val files = loadFiles(path); + if (files == null || files.length < 2) { + return false; + } + boolean desc = false; + int run = 0; + for (File f : files) { + String fileName = f.getName(); + if (fileName.equals("desc.json")) { + desc = true; + } + if (fileName.startsWith("run.")) { + run++; + } + } + return run == 1 && desc; + } + + private boolean addAction(String name, Path dir) { + File program = null; + try (Stream stream = Files.list(dir)) { + for (Path p : stream.toList()) { + if (p.getFileName().toString().startsWith("run.")) + program = p.toFile(); + } + } catch (Exception e) { + log.error("添加 action 失败", e); + return false; + } + MetaActionInfo info; + try { + info = JSONUtil.readJSONObject(dir.resolve("desc.json").toFile(), StandardCharsets.UTF_8).toBean(MetaActionInfo.class); + } catch (Exception e) { + log.error("desc.json 加载失败: {}", dir); + return false; + } + String actionKey = "local::" + name; + existedMetaActions.put(actionKey, info); + dynamicActionMcpServer.addTool(buildAsyncToolSpecification(info, program, actionKey, name)).subscribe(); + return true; + } + + private void removeAction(String name) { + existedMetaActions.remove("local::" + name); + dynamicActionMcpServer.removeTool(name).subscribe(); + } + + private BiFunction> buildToolHandler(File finalProgram) { + return (mcpTransportContext, callToolRequest) -> { + Map arguments = callToolRequest.arguments(); + if (arguments == null) { + arguments = Map.of(); + } + String ext = FileUtil.getSuffix(finalProgram); + String[] commands = SystemExecHelper.buildCommands(ext, arguments, finalProgram.getAbsolutePath()); + if (commands == null) { + return Mono.just(McpSchema.CallToolResult.builder() + .addTextContent("未知文件类型: " + finalProgram.getName()) + .isError(true) + .build()); + } + + return Mono.fromCallable(() -> { + SystemExecHelper.Result execResult = SystemExecHelper.exec(commands); + McpSchema.CallToolResult.Builder builder = McpSchema.CallToolResult.builder() + .isError(!execResult.isOk()); + List resultList = execResult.getResultList(); + if (resultList != null && !resultList.isEmpty()) { + builder.textContent(resultList); + builder.structuredContent(resultList); + } else { + builder.addTextContent(execResult.getTotal()); + builder.structuredContent(execResult.getTotal()); + } + return builder.build(); + }).subscribeOn(Schedulers.boundedElastic()); + }; + } + + @Override + @NotNull + protected LocalWatchServiceBuild.InitLoader buildLoad() { + // 从该路径列出已存在的目录,每个目录对应不同的行动程序及描述文件,从描述文件加载程序信息 + return () -> { + Path root = ctx.root; + File file = root.toFile(); + if (file.isFile()) { + throw new ActionInitFailedException("未找到目录: " + root); + } + File[] files = file.listFiles(); + if (files == null) { + throw new ActionInitFailedException("未正常读取目录: " + root); + } + for (File dir : files) { + if (!normalPath(dir.toPath())) { + continue; + } + addAction(dir.getName(), dir.toPath()); + } + }; + } + + private McpStatelessServerFeatures.AsyncToolSpecification buildAsyncToolSpecification(MetaActionInfo + info, File program, String actionKey, String name) { + Map additional = Map.of("pre", info.getPreActions(), + "post", info.getPostActions(), + "strict_pre", info.isStrictDependencies(), + "io", info.isIo()); + McpSchema.Tool tool = McpSchema.Tool.builder() + .name(name) + .description(info.getDescription()) + .inputSchema(McpJsonMapper.getDefault(), JSONObject.toJSONString(info.getParams())) + .outputSchema(info.getResponseSchema()) + .title(actionKey) + .meta(additional) + .build(); + return McpStatelessServerFeatures.AsyncToolSpecification.builder() + .tool(tool) + .callHandler(buildToolHandler(program)) + .build(); + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildModify() { + return (thisDir, context) -> { + // 查看当前目录是否为空或者能否正常读取 + if (!normalPath(thisDir)) { + return; + } + // 对应本地程序或者描述文件的修改行为 + modify(thisDir, context); + }; + } + + private void modify(Path thisDir, Path context) { + String fileName = context.getFileName().toString(); + if (fileName.equals("desc.json")) { + handleMetaModify(thisDir); + } + if (fileName.startsWith("run.")) { + handleProgramModify(thisDir); + } + } + + private void handleProgramModify(Path thisDir) { + String name = thisDir.getFileName().toString(); + String actionKey = "local::" + name; + // 检查是否存在当前 program 对应的 Tool + if (existedMetaActions.containsKey(actionKey)) { + return; + } + if (!addAction(name, thisDir)) { + removeAction(name); + } + } + + private void handleMetaModify(Path thisDir) { + // 检查是否除了描述文件外还存在别的可执行文件 + String name = thisDir.getFileName().toString(); + if (!addAction(name, thisDir)) { + removeAction(name); + } + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildCreate() { + return (thisDir, context) -> { + if (thisDir.equals(ctx.root) && Files.isDirectory(context)) { + try { + context.register(ctx.watchService, ctx.kinds.toArray(WatchEvent.Kind[]::new)); + } catch (IOException e) { + log.error("监听目录注册失败: {}", context); + } + } + if (normalPath(thisDir)) { + modify(thisDir, context); + } + if (Files.isDirectory(context) && normalPath(context)) { + File[] files = context.toFile().listFiles(); + if (files == null) { + log.warn("目录无法访问: {}", context); + return; + } + for (File f : files) { + modify(context, f.toPath()); + } + } + }; + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildDelete() { + return (thisDir, context) -> { + // 如果发生在 root,且context为目录,则需要移除对应的 action + if (thisDir.equals(ctx.root)) { + String name = context.getFileName().toString(); + Path candidate = ctx.root.resolve(name); + + // 如果 root 下仍然存在一个同名目录 + if (Files.isDirectory(candidate)) { + // 说明删的是同名文件,不是 action 目录 + return; + } + + removeAction(name); + + AtomicReference toRemove = new AtomicReference<>(); + ctx.watchKeys.forEach((key, path) -> { + if (path.getFileName().toString().equals(name)) { + key.cancel(); + toRemove.set(key); + } + }); + if (toRemove.get() != null) { + ctx.watchKeys.remove(toRemove.get()); + } + return; + } + + // 如果发生在非 root 目录内且 context 不符合 action 目录特征 + // 由于只会监听 root 目录与 action 目录 + // 所以此时则证明当前目录对应的行动已不可靠,需要移除 + if (!thisDir.equals(ctx.root) && !normalPath(thisDir)) { + // 未通过校验则删除对应的 action,并在 DynamicActonMcpServer 中删除对应的工具 + String name = thisDir.getFileName().toString(); + removeAction(name); + } + }; + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildOverflow() { + return (thisDir, context) -> { + // 直接从 existedMetaActions 中拿取现有的 key,上游也从这里发现可用工具 + Set existed = existedMetaActions.keySet().stream().map(actionKey -> actionKey.split("::")[1]).collect(Collectors.toSet()); + Set currentDirs = new HashSet<>(); + // 按照预期 root 目录下有效 path 只包括各个 action 目录 + // 排除非目录 path + try (Stream stream = Files.list(ctx.root).filter(Files::isDirectory)) { + stream.forEach(path -> { + String name = path.getFileName().toString(); + currentDirs.add(name); + + boolean contains = existed.contains(name); + boolean normal = normalPath(path); + + // 如果该目录对应 action 已被记录,且符合 action 目录要求,则无处理 + // 如果已被记录,但不符合,则移除行动 + // 此时必定被监听 + if (contains && !normal) { + removeAction(name); + } + + // 如果 action 没有记录,但符合要求,由于此时必定尚未被监听,则注册监听且添加新 action + // 如果未被记录,且不符合要求,则只注册监听 + if (!contains) { + boolean alreadyWatching = ctx.watchKeys.values().stream() + .anyMatch(p -> p.equals(path)); + if (!alreadyWatching) { + try { + WatchKey watchKey = path.register(ctx.watchService, ctx.kinds.toArray(WatchEvent.Kind[]::new)); + ctx.watchKeys.put(watchKey, path); + } catch (IOException e) { + log.error("监听目录注册失败: {}", path); + } + } + + if (normal) { + addAction(name, path); + } + } + }); + } catch (IOException e) { + log.error("目录无法读取: {}", ctx.root); + return; + } + for (String existedName : existed) { + if (!currentDirs.contains(existedName)) { + removeAction(existedName); + } + } + }; + } + } + + private static final class Desc extends LocalWatchEventProcessor { + + private final McpStatelessAsyncServer mcpDescServer; + private final ConcurrentHashMap descCache = new ConcurrentHashMap<>(); + + private Desc(ConcurrentHashMap existedMetaActions, McpStatelessAsyncServer mcpDescServer, WatchContext ctx) { + super(existedMetaActions, ctx); + this.mcpDescServer = mcpDescServer; + } + + private McpStatelessServerFeatures.@NotNull AsyncResourceSpecification buildAsyncResourceSpecification(String name, String uri) { + McpSchema.Resource resource = McpSchema.Resource.builder() + .name(name) + .title(name) + .description("Action descriptor for " + name) + .mimeType("application/json") + .uri(uri) + .build(); + BiFunction> readHandler = (context, request) -> { + String requestUri = request.uri(); + String result = descCache.get(requestUri); + if (result == null) { + return Mono.error(new NotFoundException("未找到 Resource: " + requestUri)); + } + return Mono.just(new McpSchema.ReadResourceResult(List.of(new McpSchema.TextResourceContents(requestUri, "application/json", result)))); + }; + return new McpStatelessServerFeatures.AsyncResourceSpecification(resource, readHandler); + } + + private boolean normal(String fileName) { + return fileName.endsWith(".desc.json") && fileName.contains("::"); + } + + private boolean normal(File file) { + String name = file.getName(); + return normal(name); + } + + private boolean normal(Path path) { + return normal(path.toFile()); + } + + private boolean addResource(File file) { + String name = file.getName(); + if (!normal(name)) { + return false; + } + // 读取并解析为 MetaActionInfo,存入 resources + try { + MetaActionInfo info = JSONUtil.readJSONObject(file, StandardCharsets.UTF_8).toBean(MetaActionInfo.class); + String uri = ctx.root.resolve(name).toUri().toString(); + descCache.put(uri, JSONObject.toJSONString(info)); + mcpDescServer.addResource(buildAsyncResourceSpecification(name, uri)).block(); + String actionKey = name.replace(".desc.json", ""); + if (existedMetaActions.containsKey(actionKey)) { + existedMetaActions.put(actionKey, info); + } + } catch (Exception e) { + log.error("desc.json 解析失败: {}", file.getAbsolutePath()); + return false; + } + return true; + } + + private void removeResource(Path path) { + String uri = path.toUri().toString(); + String actionKey = path.getFileName().toString().replace(".desc.json", ""); + + descCache.remove(uri); + mcpDescServer.removeResource(uri).block(); + if (existedMetaActions.containsKey(actionKey)) { + resetMetaActionInfo(existedMetaActions.get(actionKey)); + } + } + + @Override + @NotNull + protected LocalWatchServiceBuild.InitLoader buildLoad() { + return () -> { + // DescMcp 的加载逻辑只负责读取已有的 *.desc.json 并注册为 resources + // 正常来讲 root 直接对应 MCP_DESC_PATH,先检查 root 是否为目录,否则拒绝启动 + val files = loadFiles(ctx.root); + for (File file : files) { + addResource(file); + } + }; + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildModify() { + return (thisDir, context) -> { + // 排除目录事件、名称不符合要求的文件 + String fileName = context.getFileName().toString(); + if (!Files.isRegularFile(context) || !normal(fileName)) { + return; + } + + if (!addResource(context.toFile())) { + removeResource(context); + } + }; + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildCreate() { + return buildModify(); + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildDelete() { + return (thisDir, context) -> { + // 排除被删除文件名称不符合要求的事件 + String fileName = context.getFileName().toString(); + if (!normal(fileName)) { + return; + } + + // DELETE 事件发生后,需要移除对应的 descCache 条目; + // 如果存在对应的 info,也需要将其中的额外信息进行重置,只保留 Tools 自身的信息 + removeResource(context); + }; + } + + private void resetMetaActionInfo(MetaActionInfo info) { + info.setIo(false); + info.getTags().clear(); + info.getPreActions().clear(); + info.getPostActions().clear(); + info.setStrictDependencies(false); + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildOverflow() { + return (thisDir, context) -> { + // 对于 OVERFLOW 事件,需要依据当前目录下的所有 *.desc.json 针对现有内容进行修复 + List files; + try (Stream stream = Files.list(ctx.root)) { + files = stream.filter(Files::isRegularFile).filter(this::normal).map(Path::toFile).toList(); + } catch (IOException e) { + log.error("目录无法访问: {}", ctx.root); + return; + } + Set currentUriStr = new HashSet<>(); + + for (File file : files) { + MetaActionInfo info = null; + try { + info = JSONUtil.readJSONObject(file, StandardCharsets.UTF_8).toBean(MetaActionInfo.class); + } catch (Exception e) { + log.warn("desc.json 读取失败: {}", file.toPath()); + } + + boolean available = info != null; + + // 如果读取成功,则更新 descCache + // 若在 existedMetaActions 中存在,则更新对应 info + String uriStr = file.toURI().toString(); + currentUriStr.add(uriStr); + + if (available) { + // 由于涉及内容均为 map,所以额外判断没有必要,直接进行 add 行为即可 + addResource(file); + } else { + // 如果读取失败,则移除对应 descCache 条目 + // 若在 existedMetaActions 中存在,则重置对应 info + removeResource(file.toPath()); + } + + } + + List serverUris = mcpDescServer.listResources() + .map(McpSchema.Resource::uri) + .collectList() + .block(); + if (serverUris == null) { + log.error("无法获取 DescMcpServer 持有的资源列表"); + return; + } + for (String uri : serverUris) { + if (!currentUriStr.contains(uri)) { + removeResource(Paths.get(URI.create(uri))); + } + } + }; + } + } + + private static final class Common extends LocalWatchEventProcessor { + + private final Map mcpClients; + private final Map mcpConfigFileCache = new HashMap<>(); + private final McpSyncClient descClient; + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + private boolean normalFile(File file) { + return file.exists() && file.isFile() && file.getName().endsWith(".json"); + } + + private Common(ConcurrentHashMap existedMetaActions, Map mcpClients, McpSyncClient descClient, WatchContext ctx) { + super(existedMetaActions, ctx); + this.mcpClients = mcpClients; + this.descClient = descClient; + } + + /** + * 该部分主要发生在扫描到新的MCP Server描述文件时出现的注册逻辑 + * + * @param id MCP Client 的 id + * @param mcpClientTransportParams MCP Server 的参数 + */ + private void registerMcpClient(String id, McpClientTransportParams mcpClientTransportParams) { + // 如果已存在同名 client,则需要先获取并关闭 + val old = mcpClients.get(id); + val clientTransport = createTransport(mcpClientTransportParams); + val timeout = mcpClientTransportParams.timeout; + val client = McpClient.sync(clientTransport) + .requestTimeout(Duration.ofSeconds(timeout)) + .clientInfo(new McpSchema.Implementation(id, "PARTNER")) + .build(); + + try { + for (McpSchema.Tool tool : client.listTools().tools()) { + val metaActionInfo = buildMetaActionInfo(id, tool); + existedMetaActions.put(id + "::" + tool.name(), metaActionInfo); + } + mcpClients.put(id, client); + + if (old != null) { + old.close(); + } + } catch (Exception e) { + log.warn("[{}] MCP client init failed, skipped (probably non-stdio-safe)", id, e); + client.close(); + } + + } + + /** + * 构建 MetaActionInfo + * + * @param id MCP Client id + * @param tool 待构建 MetaActionInfo 的 MCP Tool + * @return MetaActionInfo 信息 + */ + private @NotNull MetaActionInfo buildMetaActionInfo(String id, McpSchema.Tool tool) { + // 先检查是否存在对应的描述文件 + val toolName = tool.name(); //格式: mcpName::toolName + for (McpSchema.Resource resource : descClient.listResources().resources()) { + val resourceName = resource.name(); + if (resourceName.equals(toolName) && resourceName.split("::")[0].equals(id)) { + val resourceContent = descClient.readResource(resource).contents().getFirst(); + if (resourceContent instanceof McpSchema.TextResourceContents r) { + try { + return JSONObject.parseObject(r.text(), MetaActionInfo.class); + } catch (Exception e) { + log.error("序列化描述文件资源失败", e); + log.error("序列化描述文件资源失败, uri: {}", r.uri()); + log.error("序列化描述文件资源失败, text: {}", r.text()); + } + } + } + } + + MetaActionInfo info = new MetaActionInfo(); + info.setDescription(tool.description()); + Map outputSchema = tool.outputSchema(); + info.setResponseSchema(outputSchema == null ? JSONObject.of() : JSONObject.from(outputSchema)); + info.setParams(tool.inputSchema().properties()); + + val meta = tool.meta(); + if (meta != null) { + JSONObject metaJson = JSONObject.from(meta); + info.setIo(metaJson.getBoolean("io")); + info.setPreActions(metaJson.getList("pre", String.class)); + info.setPostActions(metaJson.getList("post", String.class)); + info.setStrictDependencies(metaJson.getBoolean("strict")); + info.setTags(metaJson.getList("tag", String.class)); + } + return info; + } + + private McpClientTransport createTransport(McpClientTransportParams mcpClientTransportParams) { + return switch (mcpClientTransportParams) { + case McpClientTransportParams.Stdio params -> { + val serverParameters = ServerParameters.builder(params.command).env(params.env).args(params.args).build(); + yield new StdioClientTransport(serverParameters, McpJsonMapper.getDefault()); + } + case McpClientTransportParams.Http params -> { + val customizer = new McpSyncHttpClientRequestCustomizer() { + @Override + public void customize(HttpRequest.Builder builder, String method, URI endpoint, String body, McpTransportContext context) { + params.headers.forEach(builder::setHeader); + } + }; + yield HttpClientSseClientTransport.builder(params.baseUri).httpRequestCustomizer(customizer).sseEndpoint(params.endpoint).build(); + } + }; + } + + @Override + @NotNull + protected LocalWatchServiceBuild.InitLoader buildLoad() { + return () -> { + // For CommonMcp, we need to list all files in MCP_SERVER_PATH, + // and search for files with extend name .json, + // and then reading them as JSONObject to get McpClientTransportParams. + val files = loadFiles(ctx.root); + + for (File file : files) { + if (!normalFile(file)) { + continue; + } + loadAndRegisterMcpClientsFromFile(file); + } + }; + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildModify() { + /* + 发现文件更改事件时,读取该文件中存放的mcp配置,与现有的 MCP 记录对比 + 根据其是否发生配置变动等,针对对应的 client 进行调整 + 如果额外维护一个 文件-clientIds 的映射,可以解决删除某一mcp的情况 + 但如果对于极端场景:从某一文件剪切并粘贴至另一文件,但后者先于前者保存 + 此时就会出现问题,重复client无法被注册 + 建议对于这种‘分布式’的配置存放方式,每个文件变更最好都触发全量加载 + */ + return (thisDir, context) -> checkAndReload(true); + } + + private cn.hutool.json.JSONObject readJson(File file) { + try { + return JSONUtil.readJSONObject(file, StandardCharsets.UTF_8); + } catch (Exception ignored) { + return null; + } + } + + private cn.hutool.json.JSONObject readMcp(cn.hutool.json.JSONObject json, String id) { + try { + return json.getJSONObject(id); + } catch (Exception ignored) { + return null; + } + } + + @SuppressWarnings("unchecked") + private McpClientTransportParams readParams(cn.hutool.json.JSONObject mcp) { + val stdioKeys = Set.of("command", "args", "env"); + val httpKeys = Set.of("uri", "endpoint", "headers"); + val httpKey = Set.of("url"); + val keys = mcp.keySet(); + val timeout = mcp.getInt("timeout", 30); + + if (keys.equals(stdioKeys)) { + val command = mcp.getStr("command"); + val env = mcp.getBean("env", Map.class); + val args = mcp.getBeanList("args", String.class); + if (command == null || env == null || args == null) { + return null; + } + return new McpClientTransportParams.Stdio(timeout, command, env, args); + } + + if (keys.equals(httpKeys)) { + val uri = mcp.getStr("uri"); + val endpoint = mcp.getStr("endpoint"); + val headers = mcp.getBean("headers", Map.class); + if (uri == null || endpoint == null || headers == null) { + return null; + } + return new McpClientTransportParams.Http(timeout, uri, endpoint, headers); + } + + if (keys.equals(httpKey)) { + val url = mcp.getStr("url"); + if (url == null) { + return null; + } + return new McpClientTransportParams.Http(timeout, url, "", Map.of()); + } + + return null; + } + + private void checkAndReload(boolean trustCache) { + /* + for each file cannot present all mcp configurations, + we need to load all at once, and then compare them with existed records. + we will record existing mcp paramsCacheMap and id-params map for which is changed. + + recording changedMap only cannot figure out which mcp was deleted, + so existingMcpIdSet attr is required + */ + val changedMap = new HashMap(); + val existingMcpIdSet = new HashSet(); + + val files = loadFiles(ctx.root); + for (File file : files) { + if (!normalFile(file)) { + continue; + } + + // check if necessary stats changed, null record is seen as file changed + val fileRecord = mcpConfigFileCache.get(file); + boolean fileRecordExists = fileRecord != null; + if (fileRecordExists && !fileChanged(file, fileRecord) && trustCache) { + existingMcpIdSet.addAll(fileRecord.paramsCacheMap().keySet()); + continue; + } + + // if changed, read file and load mcp configurations + val mcpConfigJson = readJson(file); + if (mcpConfigJson == null) { + // uses old records to avoid abnormal deletion + if (fileRecordExists) { + existingMcpIdSet.addAll(fileRecord.paramsCacheMap().keySet()); + } + continue; + } + + val newFileRecord = new McpConfigFileRecord(file.lastModified(), file.length(), new HashMap<>()); + for (String id : mcpConfigJson.keySet()) { + val mcp = readMcp(mcpConfigJson, id); + if (mcp == null) { + continue; + } + + val params = readParams(mcp); + if (params == null) { + continue; + } + + existingMcpIdSet.add(id); + newFileRecord.paramsCacheMap().put(id, params); + + if (fileRecordExists) { + val paramsCache = fileRecord.paramsCacheMap().get(id); + if (paramsCache != null && paramsCache.equals(params)) { + continue; + } + } + + changedMap.put(id, params); + } + mcpConfigFileCache.put(file, newFileRecord); + } + + updateMcpClients(changedMap, existingMcpIdSet); + } + + private void updateMcpClients(HashMap changedMap, HashSet existingMcpIdSet) { + // following attr changedMap, update or insert mcp clients + changedMap.forEach((id, params) -> { + // close outdated clients if exists + val oldClient = mcpClients.get(id); + if (oldClient != null) { + oldClient.close(); + } + // create new clients + registerMcpClient(id, params); + }); + + // following attr existingMcpIdSet, align mcp clients + // new mcp clients and outdated clients has been updated in above logic + // this part focus on removing non-existing mcp + mcpClients.keySet().removeIf(id -> !existingMcpIdSet.contains(id)); + // clear relevant tools' action info + existedMetaActions.keySet().removeIf(id -> !existingMcpIdSet.contains(id.split("::")[0])); + } + + private boolean fileChanged(File file, McpConfigFileRecord fileRecord) { + val lastModified = file.lastModified(); + val length = file.length(); + + return fileRecord.lastModified() != lastModified || fileRecord.length() != length; + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildOverflow() { + return (thisDir, context) -> checkAndReload(false); + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildCreate() { + return (thisDir, context) -> { + val file = context.toFile(); + if (!normalFile(file)) { + return; + } + + loadAndRegisterMcpClientsFromFile(file); + }; + } + + private void loadAndRegisterMcpClientsFromFile(File file) { + val mcpConfigJson = readJson(file); + if (mcpConfigJson == null) { + return; + } + + val newFileRecord = new McpConfigFileRecord(file.lastModified(), file.length()); + for (String id : mcpConfigJson.keySet()) { + val mcp = readMcp(mcpConfigJson, id); + if (mcp == null) { + continue; + } + + val params = readParams(mcp); + if (params == null) { + continue; + } + + registerMcpClient(id, params); + newFileRecord.paramsCacheMap().put(id, params); + } + mcpConfigFileCache.put(file, newFileRecord); + } + + @Override + @NotNull + protected LocalWatchServiceBuild.EventHandler buildDelete() { + return (thisDir, context) -> { + val file = context.toFile(); + if (!file.getName().endsWith(".json")) { + return; + } + + val fileRecord = mcpConfigFileCache.remove(file); + if (fileRecord == null) { + return; + } + + // clear from existedMetaActions and mcpClients + // client id comes from fileRecord.paramsCache + // actionKey from `id::toolName` + val clientIdSet = fileRecord.paramsCacheMap().keySet(); + for (String clientId : clientIdSet) { + val client = mcpClients.remove(clientId); + if (client == null) { + continue; + } + + val tools = client.listTools().tools(); + for (McpSchema.Tool tool : tools) { + val actionKey = clientId + "::" + tool.name(); + existedMetaActions.remove(actionKey); + } + client.close(); + } + }; + } + + private record McpConfigFileRecord(long lastModified, long length, + Map paramsCacheMap) { + public McpConfigFileRecord(long lastModified, long length) { + this(lastModified, length, new HashMap<>()); + } + } + } + } + + private sealed abstract static class McpClientTransportParams permits McpClientTransportParams.Http, McpClientTransportParams.Stdio { + private final int timeout; + + private McpClientTransportParams(int timeout) { + this.timeout = timeout; + } + + private final static class Http extends McpClientTransportParams { + private final String baseUri; + private final String endpoint; + private final Map headers; + + private Http(int timeout, String baseUri, String endpoint, Map header) { + super(timeout); + this.baseUri = baseUri; + this.endpoint = endpoint; + this.headers = header; + } + } + + private final static class Stdio extends McpClientTransportParams { + private final String command; + private final Map env; + private final List args; + + private Stdio(int timeout, String command, Map env, List args) { + super(timeout); + this.command = command; + this.env = env; + this.args = args; + } + } + } + + private static class SystemExecHelper { + + //TODO 后续需在加载时、或者通过配置文件获取可用命令并注册匹配 + private static String[] buildCommands(String ext, Map params, String absolutePath) { + String command = switch (ext) { + case "py" -> "python"; + case "sh" -> "bash"; + default -> null; + }; + if (command == null) { + return null; + } + int paramSize = params == null ? 0 : params.size(); + String[] commands = new String[paramSize + 2]; + commands[0] = command; + commands[1] = absolutePath; + AtomicInteger paramCount = new AtomicInteger(2); + if (params != null) { + params.forEach((param, value) -> commands[paramCount.getAndIncrement()] = "--" + param + "=" + value); + } + return commands; + } + + private static Result exec(String... command) { + Result result = new Result(); + List output = new ArrayList<>(); + List error = new ArrayList<>(); + + try { + Process process = new ProcessBuilder(command) + .redirectErrorStream(false) // 分开读 + .start(); + + Thread stdoutThread = new Thread(() -> { + try (BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = r.readLine()) != null) { + output.add(line); + } + } catch (Exception ignored) { + } + }); + + Thread stderrThread = new Thread(() -> { + try (BufferedReader r = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + String line; + while ((line = r.readLine()) != null) { + error.add(line); + } + } catch (Exception ignored) { + } + }); + + stdoutThread.start(); + stderrThread.start(); + + int exitCode = process.waitFor(); + stdoutThread.join(); + stderrThread.join(); + + result.setOk(exitCode == 0); + result.setResultList(output.isEmpty() ? error : output); + result.setTotal(String.join("\n", output.isEmpty() ? error : output)); + + } catch (Exception e) { + result.setOk(false); + result.setTotal(e.getMessage()); + } + + return result; + } + + @Data + private static class Result { + private boolean ok; + private String total; + private List resultList; + } + } + +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/runner/RunnerClient.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/runner/RunnerClient.java new file mode 100644 index 00000000..ddc32673 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/runner/RunnerClient.java @@ -0,0 +1,107 @@ +package work.slhaf.partner.core.action.runner; + +import com.alibaba.fastjson2.JSONObject; +import io.modelcontextprotocol.server.McpStatelessAsyncServer; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.jetbrains.annotations.Nullable; +import work.slhaf.partner.core.action.entity.ActionFileMetaData; +import work.slhaf.partner.core.action.entity.MetaAction; +import work.slhaf.partner.core.action.entity.MetaAction.Result; +import work.slhaf.partner.core.action.entity.MetaActionInfo; +import work.slhaf.partner.core.action.exception.ActionInitFailedException; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; + +import static work.slhaf.partner.common.Constant.Path.DATA; +import static work.slhaf.partner.common.util.PathUtil.buildPathStr; + +/** + * 执行客户端抽象类 + *
+ * 只负责暴露序列化、执行等相应接口,具体逻辑交给下游实现 + *
+ * 默认存在两类实现,{@link LocalRunnerClient} 和 {@link SandboxRunnerClient} + *
    + * LocalRunnerClient: + *
  1. + * 对应本地运行环境,可在本地启动 MCP 客户端将 RunnerClient 暴露的能力接口转发至本地 MCP Client 并执行 + *
  2. + * SandboxRunnerClient: + *
  3. + * 对应沙盒运行环境,该 Client 仅作为沙盒环境的客户端,不持有额外能力,仅保持远端连接已存在行动的内容更新 + *
  4. + *
+ */ +@Slf4j +public abstract class RunnerClient { + + protected final String ACTION_PATH; + + protected final ConcurrentHashMap existedMetaActions; + protected final ExecutorService executor; + //TODO 仍可提供内部 MCP,但调用方式需要结合 AgentContext来获取,否则生命周期不合 + protected McpStatelessAsyncServer innerMcpServer; + + /** + * ActionCore 将注入虚拟线程池 + */ + public RunnerClient(ConcurrentHashMap existedMetaActions, ExecutorService executor, @Nullable String baseActionPath) { + this.existedMetaActions = existedMetaActions; + this.executor = executor; + baseActionPath = baseActionPath == null ? DATA : baseActionPath; + this.ACTION_PATH = buildPathStr(baseActionPath, "action"); + + createPath(ACTION_PATH); + } + + /** + * 执行行动程序 + */ + public void submit(MetaAction metaAction) { + // 获取已存在行动列表 + Result result = metaAction.getResult(); + if (!result.getStatus().equals(Result.Status.WAITING)) { + return; + } + RunnerResponse response = doRun(metaAction); + result.setData(response.getData()); + result.setStatus(response.isOk() ? Result.Status.SUCCESS : Result.Status.FAILED); + } + + protected abstract RunnerResponse doRun(MetaAction metaAction); + + public abstract String buildTmpPath(String actionKey, String codeType); + + public abstract void tmpSerialize(MetaAction tempAction, String code, String codeType) throws IOException; + + public abstract void persistSerialize(MetaActionInfo metaActionInfo, ActionFileMetaData fileMetaData); + + protected void createPath(String pathStr) { + val path = Path.of(pathStr); + try { + Files.createDirectory(path); + } catch (IOException e) { + if (!Files.exists(path)) { + throw new ActionInitFailedException("目录创建失败: " + pathStr, e); + } + } + } + + /** + * 列出执行环境下的系统依赖情况 + */ + public abstract JSONObject listSysDependencies(); + + @Data + public static class RunnerResponse { + private boolean ok; + private String data; + } + +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/runner/SandboxRunnerClient.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/runner/SandboxRunnerClient.java new file mode 100644 index 00000000..7bc34fcf --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/runner/SandboxRunnerClient.java @@ -0,0 +1,57 @@ +package work.slhaf.partner.core.action.runner; + +import com.alibaba.fastjson2.JSONObject; +import work.slhaf.partner.core.action.entity.ActionFileMetaData; +import work.slhaf.partner.core.action.entity.MetaAction; +import work.slhaf.partner.core.action.entity.MetaActionInfo; + +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; + +/** + * 基于 Http 与 WebSocket 的沙盒执行器客户端,负责: + *
    + *
  • + * 发送行动单元数据 + *
  • + *
  • + * 实时更新获取已存在行动列表 + *
  • + *
  • + * 向传入的 MetaAction 回写执行结果 + *
  • + *
+ */ +public class SandboxRunnerClient extends RunnerClient { + + public SandboxRunnerClient(ConcurrentHashMap existedMetaActions, ExecutorService executor) { // 连接沙盒执行器(websocket) + super(existedMetaActions, executor, null); + } + + protected RunnerResponse doRun(MetaAction metaAction) { + // 调用沙盒执行器 + return null; + } + + @Override + public JSONObject listSysDependencies() { + return null; + } + + @Override + public String buildTmpPath(String actionKey, String codeType) { + throw new UnsupportedOperationException("Unimplemented method 'buildTmpPath'"); + } + + @Override + public void tmpSerialize(MetaAction tempAction, String code, String codeType) throws IOException { + throw new UnsupportedOperationException("Unimplemented method 'tmpSerialize'"); + } + + @Override + public void persistSerialize(MetaActionInfo metaActionInfo, ActionFileMetaData fileMetaData) { + throw new UnsupportedOperationException("Unimplemented method 'persistSerialize'"); + } + +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/cognation/CognationCapability.java b/Partner-Main/src/main/java/work/slhaf/partner/core/cognation/CognationCapability.java index 81c4b290..4f9ac125 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/cognation/CognationCapability.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/cognation/CognationCapability.java @@ -13,7 +13,6 @@ import java.util.concurrent.locks.Lock; public interface CognationCapability { List getChatMessages(); - void setChatMessages(List chatMessages); void cleanMessage(List messages); Lock getMessageLock(); void addMetaMessage(String userId, MetaMessage metaMessage); diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/cognation/CognationCore.java b/Partner-Main/src/main/java/work/slhaf/partner/core/cognation/CognationCore.java index 1157c1a8..675a7e6a 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/cognation/CognationCore.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/cognation/CognationCore.java @@ -63,11 +63,6 @@ public class CognationCore extends PartnerCore { return currentMemoryId; } - @CapabilityMethod - public void setChatMessages(List chatMessages) { - this.chatMessages = chatMessages; - } - @CapabilityMethod public void cleanMessage(List messages) { messageLock.lock(); diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/memory/MemoryCore.java b/Partner-Main/src/main/java/work/slhaf/partner/core/memory/MemoryCore.java index 46924c05..3bd4be03 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/memory/MemoryCore.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/memory/MemoryCore.java @@ -198,9 +198,9 @@ public class MemoryCore extends PartnerCore { //尝试更新缓存 updateCache(topicPath, memoryResult); } catch (Exception e) { - log.error("[CoordinatedManager] selectMemory error: ", e); - log.error("[CoordinatedManager] 路径: {}", topicPathStr); - log.error("[CoordinatedManager] 主题树: {}", getTopicTree()); + log.error("[{}] selectMemory error: ", getCoreKey(), e); + log.error("[{}] 路径: {}", getCoreKey(), topicPathStr); + log.error("[{}] 主题树: {}", getCoreKey(), getTopicTree()); memoryResult = new MemoryResult(); memoryResult.setRelatedMemorySliceResult(new ArrayList<>()); memoryResult.setMemorySliceResult(new CopyOnWriteArrayList<>()); @@ -211,7 +211,7 @@ public class MemoryCore extends PartnerCore { @CapabilityMethod public void updateActivatedSlices(String userId, List memorySlices) { cache.activatedSlices.put(userId, memorySlices); - log.debug("[CoordinatedManager] 已更新激活切片, userId: {}", userId); + log.debug("[{}] 已更新激活切片, userId: {}", getCoreKey(), userId); } @CapabilityMethod @@ -488,7 +488,7 @@ public class MemoryCore extends PartnerCore { return targetParentNode; } - public void updateCacheCounter(List topicPath) { + private void updateCacheCounter(List topicPath) { ConcurrentHashMap, Integer> memoryNodeCacheCounter = cache.memoryNodeCacheCounter; if (memoryNodeCacheCounter.containsKey(topicPath)) { Integer tempCount = memoryNodeCacheCounter.get(topicPath); diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/common/entity/AppendPromptData.java b/Partner-Main/src/main/java/work/slhaf/partner/module/common/entity/AppendPromptData.java index 050158c0..8abd56b0 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/common/entity/AppendPromptData.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/common/entity/AppendPromptData.java @@ -5,7 +5,7 @@ import lombok.EqualsAndHashCode; import work.slhaf.partner.api.common.entity.PersistableObject; import java.io.Serial; -import java.util.HashMap; +import java.util.Map; @EqualsAndHashCode(callSuper = true) @Data @@ -15,5 +15,5 @@ public class AppendPromptData extends PersistableObject { private static final long serialVersionUID = 1L; private String moduleName; - private HashMap appendedPrompt; + private Map appendedPrompt; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/common/module/PostRunningModule.java b/Partner-Main/src/main/java/work/slhaf/partner/module/common/module/PostRunningModule.java index f3c5f01f..dacd83fb 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/common/module/PostRunningModule.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/common/module/PostRunningModule.java @@ -8,7 +8,7 @@ public abstract class PostRunningModule extends AgentRunningModule map = getPromptDataMap(context); + Map map = getPromptDataMap(context); data.setAppendedPrompt(map); context.setAppendedPrompt(data); } @@ -24,7 +24,7 @@ public abstract class PreRunningModule extends AgentRunningModule getPromptDataMap(PartnerRunningFlowContext context); + protected abstract Map getPromptDataMap(PartnerRunningFlowContext context); /** * 用于在CoreModule接收到的模块Prompt中标识模块名称 @@ -40,5 +40,4 @@ public abstract class PreRunningModule extends AgentRunningModule { + String userId = context.getUserId(); + val preparedActions = actionCapability.listActions(ActionData.ActionStatus.PREPARE, userId); + // 分类成PLANNING和IMMEDIATE两类 + Set scheduledActions = new HashSet<>(); + Set immediateActions = new HashSet<>(); + for (ActionData preparedAction : preparedActions) { + if (preparedAction instanceof ScheduledActionData actionInfo) { + scheduledActions.add(actionInfo); + } else if (preparedAction instanceof ImmediateActionData actionInfo) { + immediateActions.add(actionInfo); + } + } + actionExecutor.execute(new ActionExecutorInput(immediateActions)); + actionScheduler.execute(scheduledActions); + }); + } + + @Override + protected boolean relyOnMessage() { + return false; + } + +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionCorrector.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionCorrector.java new file mode 100644 index 00000000..481f851b --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionCorrector.java @@ -0,0 +1,52 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor; + +import com.alibaba.fastjson2.JSONObject; +import lombok.val; +import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.CorrectorInput; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.CorrectorResult; + +/** + * 负责在单组行动执行后,根据行动意图与结果检查后续行动是否符合目的,必要时直接调整行动链,或发起自对话请求进行干预 + */ +@AgentSubModule +public class ActionCorrector extends AgentRunningSubModule implements ActivateModel { + + @Override + public CorrectorResult execute(CorrectorInput input) { + val prompt = buildPrompt(input); + val chatResponse = singleChat(prompt); + return JSONObject.parseObject(chatResponse.getMessage(), CorrectorResult.class); + } + + private String buildPrompt(CorrectorInput input) { + val prompt = new JSONObject(); + prompt.put("[行动来源]", input.getSource()); + prompt.put("[行动倾向]", input.getTendency()); + prompt.put("[行动描述]", input.getDescription()); + prompt.put("[行动原因]", input.getReason()); + + val messages = prompt.putArray("[近期对话]"); + messages.addAll(input.getRecentMessages()); + + val memory = prompt.putArray("[已激活记忆]"); + memory.addAll(input.getActivatedSlices()); + + val history = prompt.putArray("[已执行情况]"); + history.addAll(input.getHistory()); + return prompt.toJSONString(); + } + + @Override + public String modelKey() { + return "action_corrector"; + } + + @Override + public boolean withBasicPrompt() { + return false; + } + +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java new file mode 100644 index 00000000..28b46149 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java @@ -0,0 +1,322 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor; + +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; +import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; +import work.slhaf.partner.api.agent.factory.module.annotation.Init; +import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; +import work.slhaf.partner.core.action.ActionCapability; +import work.slhaf.partner.core.action.ActionCore; +import work.slhaf.partner.core.action.entity.*; +import work.slhaf.partner.core.action.entity.ActionData.ActionStatus; +import work.slhaf.partner.core.action.runner.RunnerClient; +import work.slhaf.partner.core.cognation.CognationCapability; +import work.slhaf.partner.core.memory.MemoryCapability; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.*; +import work.slhaf.partner.module.modules.action.dispatcher.scheduler.ActionScheduler; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Phaser; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +@Slf4j +@AgentSubModule +public class ActionExecutor extends AgentRunningSubModule { + + @InjectCapability + private ActionCapability actionCapability; + @InjectCapability + private MemoryCapability memoryCapability; + @InjectCapability + private CognationCapability cognationCapability; + + @InjectModule + private ParamsExtractor paramsExtractor; + @InjectModule + private ActionRepairer actionRepairer; + @InjectModule + private ActionCorrector actionCorrector; + @InjectModule + private ActionScheduler actionScheduler; + + private ExecutorService virtualExecutor; + private ExecutorService platformExecutor; + private RunnerClient runnerClient; + + private final AssemblyHelper assemblyHelper = new AssemblyHelper(); + + @Init + public void init() { + virtualExecutor = actionCapability.getExecutor(ActionCore.ExecutorType.VIRTUAL); + platformExecutor = actionCapability.getExecutor(ActionCore.ExecutorType.PLATFORM); + runnerClient = actionCapability.runnerClient(); + } + + /** + * 执行行动 + * + * @param input ActionExecutor 输入内容 + * @return 无返回,执行结果回写至 input 内部携带的 actionData 中 + */ + @Override + public Void execute(ActionExecutorInput input) { + val actions = input.getActions(); + // 异步执行所有行动 + for (ActionData actionData : actions) { + platformExecutor.execute(() -> { + val source = actionData.getSource(); + if (actionData.getStatus() != ActionStatus.PREPARE) { + return; + } + val actionChain = actionData.getActionChain(); + if (actionChain.isEmpty()) { + actionData.setStatus(ActionStatus.FAILED); + actionData.setResult("行动链为空"); + return; + } + // 注册执行中行动 + val phaser = new Phaser(); + val phaserRecord = actionCapability.putPhaserRecord(phaser, actionData); + actionData.setStatus(ActionStatus.EXECUTING); + + // 开始执行 + val stageCursor = new Object() { + int stageCount; + boolean executingStageUpdated; + boolean stageCountUpdated; + + void init() { + stageCount = 0; + executingStageUpdated = false; + stageCountUpdated = false; + update(); + } + + void requestAdvance() { + if (!stageCountUpdated) { + stageCount++; + stageCountUpdated = true; + } + + if (stageCount < actionChain.size() && !executingStageUpdated) { + update(); + executingStageUpdated = true; + } + } + + boolean next() { + executingStageUpdated = false; + stageCountUpdated = false; + return stageCount < actionChain.size(); + } + + void update() { + val orderList = new ArrayList<>(actionChain.keySet()); + orderList.sort(Integer::compareTo); + actionData.setExecutingStage(orderList.get(stageCount)); + } + }; + + stageCursor.init(); + do { + val metaActions = actionChain.get(actionData.getExecutingStage()); + + val listeningRecord = executeAndListening(metaActions, phaserRecord, source); + phaser.awaitAdvance(listeningRecord.phase()); + + // synchronized 同步防止 accepting 循环间、phase guard 判定后发生 stage 推进 + // 导致新行动的 phaser 投放阶段错乱无法阻塞的场景 + // 该 synchronized 将阶段推进与 accepting 监听 loop 捆绑为互斥的原子事件,避免了细粒度的 phaser 阶段竞态问题 + synchronized (listeningRecord.accepting()) { + listeningRecord.accepting().set(false); + + // 立即尝试推进,本次推进中,如果前方仍有未执行 stage,将执行一次阶段推进 + stageCursor.requestAdvance(); + } + + try { + // 针对行动链进行修正,修正需要传入执行历史、行动目标等内容 + // 如果后续运行 corrector 触发频率较高,可考虑增加重试机制 + val correctorInput = assemblyHelper.buildCorrectorInput(actionData, source); + val correctorResult = actionCorrector.execute(correctorInput); + actionCapability.handleInterventions(correctorResult.getMetaInterventionList(), actionData); + } catch (Exception ignored) { + } + + // 第二次尝试进行阶段推进,本次负责补充上一次在不存在 stage时,但 corrector 执行期间发生了 actionChain 的插入事件 + // 如果第一次已经推进完毕,本次将会跳过 + stageCursor.requestAdvance(); + } while (stageCursor.next()); + + // 结束 + actionCapability.removePhaserRecord(phaser); + if (actionData.getStatus() != ActionStatus.FAILED) { + // 如果是 ScheduledActionData, 则重置 ActionData 内容,记录执行历史与最终结果 + if (actionData instanceof ScheduledActionData scheduledActionData) { + scheduledActionData.recordAndReset(); + actionScheduler.execute(Set.of(scheduledActionData)); + } else { + actionData.setStatus(ActionStatus.SUCCESS); + } + } + }); + + } + return null; + + } + + private MetaActionsListeningRecord executeAndListening(List metaActions, PhaserRecord phaserRecord, String source) { + AtomicBoolean accepting = new AtomicBoolean(true); + AtomicInteger cursor = new AtomicInteger(); + + CountDownLatch latch = new CountDownLatch(1); + val phaser = phaserRecord.phaser(); + val phase = phaser.register(); + platformExecutor.execute(() -> { + boolean first = true; + while (accepting.get()) { + synchronized (accepting) { + MetaAction next = null; + + synchronized (metaActions) { + if (cursor.get() < metaActions.size()) { + next = metaActions.get(cursor.getAndIncrement()); + } + } + + if (next == null) { + Thread.onSpinWait(); + continue; + } + + if (phaser.getPhase() != phase) { + metaActions.remove(next); + log.warn("行动阶段已推进,丢弃该行动: {}", next); + continue; + } + + ExecutorService executor = next.getIo() ? virtualExecutor : platformExecutor; + executor.execute(buildMataActionTask(next, phaserRecord, source)); + + if (first) { + phaser.arriveAndDeregister(); + latch.countDown(); + first = false; + } + } + } + }); + try { + // 确保执行一次,防止没来得及注册任务就已经结束 + latch.await(); + } catch (InterruptedException ignored) { + } + return new MetaActionsListeningRecord(accepting, phase); + } + + private Runnable buildMataActionTask(MetaAction metaAction, PhaserRecord phaserRecord, String source) { + val phaser = phaserRecord.phaser(); + phaser.register(); + return () -> { + val actionKey = metaAction.getKey(); + try { + val result = metaAction.getResult(); + do { + val actionData = phaserRecord.actionData(); + val executingStage = actionData.getExecutingStage(); + val historyActionResults = actionData.getHistory().get(executingStage); + val additionalContext = actionData.getAdditionalContext().get(executingStage); + val extractorInput = assemblyHelper.buildExtractorInput(metaAction, source, historyActionResults, additionalContext); + val extractorResult = paramsExtractor.execute(extractorInput); + + if (extractorResult.isOk()) { + metaAction.getParams().putAll(extractorResult.getParams()); + runnerClient.submit(metaAction); + val historyAction = new HistoryAction(actionKey, actionCapability.loadMetaActionInfo(actionKey).getDescription(), metaAction.getResult().getData()); + actionData.getHistory() + .computeIfAbsent(executingStage, integer -> new ArrayList<>()) + .add(historyAction); + } else { + val repairerInput = assemblyHelper.buildRepairerInput(historyActionResults, metaAction, source); + val repairerResult = actionRepairer.execute(repairerInput); + switch (repairerResult.getStatus()) { + // 如果本次修复被认为成功,则将补充的信息添加至 additionalContext + case RepairerResult.RepairerStatus.OK -> { + additionalContext.addAll(repairerResult.getFixedData()); + result.setStatus(MetaAction.Result.Status.WAITING); + } + // 此处的修复失败来自系统内部的执行失败:其余方式均不可行时将回退至当前分支 + case RepairerResult.RepairerStatus.FAILED -> { + result.setStatus(MetaAction.Result.Status.FAILED); + result.setData("行动执行失败"); + } + // 此处对应已在 repairer 内发起外部请求,故在此处进行阻塞 + case RepairerResult.RepairerStatus.ACQUIRE -> { + phaserRecord.interrupt(); + result.setStatus(MetaAction.Result.Status.WAITING); + } + } + } + } while (result.getStatus().equals(MetaAction.Result.Status.WAITING)); + } catch (Exception e) { + log.error("Action executing failed: {}", actionKey, e); + } finally { + phaser.arriveAndDeregister(); + } + }; + } + + private record MetaActionsListeningRecord(AtomicBoolean accepting, int phase) { + } + + @SuppressWarnings("InnerClassMayBeStatic") + private class AssemblyHelper { + + private AssemblyHelper() { + } + + private RepairerInput buildRepairerInput(List historyActionsResults, MetaAction action, String userId) { + RepairerInput input = new RepairerInput(); + MetaActionInfo metaActionInfo = actionCapability.loadMetaActionInfo(action.getKey()); + input.setHistoryActionResults(historyActionsResults); + input.setParams(metaActionInfo.getParams()); + input.setRecentMessages(cognationCapability.getChatMessages()); + input.setActionDescription(metaActionInfo.getDescription()); + input.setUserId(userId); + return input; + } + + private ExtractorInput buildExtractorInput(MetaAction action, String source, List historyActionResults, + List additionalContext) { + ExtractorInput input = new ExtractorInput(); + input.setEvaluatedSlices(memoryCapability.getActivatedSlices(source)); + input.setRecentMessages(cognationCapability.getChatMessages()); + input.setMetaActionInfo(actionCapability.loadMetaActionInfo(action.getKey())); + input.setHistoryActionResults(historyActionResults); + input.setAdditionalContext(additionalContext); + return input; + } + + private CorrectorInput buildCorrectorInput(ActionData actionData, String source) { + return CorrectorInput.builder() + .tendency(actionData.getTendency()) + .source(actionData.getSource()) + .reason(actionData.getReason()) + .description(actionData.getDescription()) + .history(actionData.getHistory().get(actionData.getExecutingStage())) + .status(actionData.getStatus()) + .recentMessages(cognationCapability.getChatMessages()) + .activatedSlices(memoryCapability.getActivatedSlices(source)) + .build(); + } + } + +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionRepairer.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionRepairer.java new file mode 100644 index 00000000..c5496b8a --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionRepairer.java @@ -0,0 +1,228 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.TypeReference; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; +import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; +import work.slhaf.partner.api.agent.factory.module.annotation.Init; +import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; +import work.slhaf.partner.api.chat.pojo.ChatResponse; +import work.slhaf.partner.core.action.ActionCapability; +import work.slhaf.partner.core.action.ActionCore.ExecutorType; +import work.slhaf.partner.core.action.entity.MetaAction; +import work.slhaf.partner.core.action.entity.MetaAction.Result; +import work.slhaf.partner.core.action.runner.RunnerClient; +import work.slhaf.partner.core.cognation.CognationCapability; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.GeneratorInput; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.GeneratorResult; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.RepairerInput; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.RepairerResult; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.RepairerResult.RepairerStatus; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 负责识别行动链的修复 + *
    + *
  1. + * 可通过协调 {@link DynamicActionGenerator} 生成新的行动单元并调用,获取所需的参数信息(必要时持久化); + *
  2. + *
  3. + * 也可以直接调用已存在的行动程序获取信息; + *
  4. + *
  5. + * 如果上述都无法满足,将发起自对话借助干预模块进行操作或者借助自对话通道向用户发起沟通请求,该请求的目的一般为行动程序生成/调用指导或者用户侧的信息补充,后续还需要再走一遍参数修复流程 + *
  6. + *
+ */ +@Slf4j +@AgentSubModule +public class ActionRepairer extends AgentRunningSubModule implements ActivateModel { + + @InjectCapability + private ActionCapability actionCapability; + @InjectCapability + private CognationCapability cognationCapability; + + @InjectModule + private DynamicActionGenerator dynamicActionGenerator; + + private final AssemblyHelper assemblyHelper = new AssemblyHelper(); + private RunnerClient runnerClient; + + @Init + void init() { + runnerClient = actionCapability.runnerClient(); + } + + @Override + public RepairerResult execute(RepairerInput data) { + RepairerResult result; + try { + String prompt = assemblyHelper.buildPrompt(data, null); + ChatResponse response = this.singleChat(prompt); + RepairerData repairerData = JSONObject.parseObject(response.getMessage(), RepairerData.class); + result = switch (repairerData.getRepairerType()) { + case ACTION_GENERATION -> + handleActionGeneration(JSONObject.parseObject(repairerData.getData(), GeneratorInput.class)); + case ACTION_INVOCATION -> handleActionInvocation( + JSONObject.parseObject(repairerData.getData(), new TypeReference>() { + })); + case USER_INTERACTION -> handleUserInteraction(repairerData.getData()); + }; + if (!repairerData.getRepairerType().equals(RepairerType.USER_INTERACTION) + && result.getStatus().equals(RepairerResult.RepairerStatus.FAILED)) { + log.warn("常规行动修复失败,将尝试自对话通道"); + prompt = assemblyHelper.buildPrompt(data, "常规行动修复失败,请尝试通过自对话通道获取必要的信息以完成行动参数的修复"); + response = this.singleChat(prompt); + repairerData = JSONObject.parseObject(response.getMessage(), RepairerData.class); + handleUserInteraction(repairerData.getData()); + } + } catch (Exception e) { + result = new RepairerResult(); + result.setStatus(RepairerStatus.FAILED); + } + return result; + } + + /** + * 负责根据输入内容进行行动单元的参数信息修复 + * + * @param generatorInput 生成的行动单元参考内容,最好包含行动单元的执行逻辑 + * @return 修复后的行动单元结果 + */ + private RepairerResult handleActionGeneration(GeneratorInput generatorInput) { + RepairerResult result = new RepairerResult(); + GeneratorResult generatorResult = dynamicActionGenerator.execute(generatorInput); + MetaAction tempAction = generatorResult.getTempAction(); + if (tempAction == null) { + result.setStatus(RepairerStatus.FAILED); + return result; + } + + runnerClient.submit(tempAction); + // 根据 tempAction 的执行状态设置修复结果 + Result actionResult = tempAction.getResult(); + if (actionResult.getStatus() != MetaAction.Result.Status.SUCCESS) { + result.setStatus(RepairerStatus.FAILED); + return result; + } + + result.setStatus(RepairerStatus.OK); + result.getFixedData().add(actionResult.getData()); + return result; + } + + /** + * 负责根据输入内容进行行动单元的参数信息修复 + * + * @param actionKeys 需要调用的行动单元Key列表 + * @return 修复后的行动单元结果 + */ + private RepairerResult handleActionInvocation(List actionKeys) { + RepairerResult result = new RepairerResult(); + CountDownLatch latch = new CountDownLatch(actionKeys.size()); + ExecutorService virtual = actionCapability.getExecutor(ExecutorType.VIRTUAL); + ExecutorService platform = actionCapability.getExecutor(ExecutorType.PLATFORM); + ExecutorService executor; + AtomicInteger failedCount = new AtomicInteger(0); + for (String key : actionKeys) { + MetaAction action = actionCapability.loadMetaAction(key); + executor = action.getIo() ? virtual : platform; + executor.execute(() -> { + try { + runnerClient.submit(action); + result.getFixedData().add(action.getResult().getData()); + } catch (Exception e) { + log.error("行动单元执行失败: {}", key, e); + failedCount.incrementAndGet(); + } finally { + latch.countDown(); + } + }); + } + try { + latch.await(); + } catch (Exception e) { + log.warn("CountDownLatch 已中断"); + } + if (actionKeys.size() - failedCount.get() > 0) { + result.setStatus(RepairerStatus.OK); + } else { + result.setStatus(RepairerStatus.FAILED); + } + return result; + } + + private RepairerResult handleUserInteraction(String acquireContent) { + RepairerResult result = new RepairerResult(); + result.setStatus(RepairerStatus.ACQUIRE); + // 发送自对话请求 + return result; + } + + @Override + public String modelKey() { + return "action_repairer"; + } + + @Override + public boolean withBasicPrompt() { + return false; + } + + @SuppressWarnings("InnerClassMayBeStatic") + @Data + private class RepairerData { + private RepairerType repairerType; + private String data; + } + + private enum RepairerType { + ACTION_GENERATION, + ACTION_INVOCATION, + USER_INTERACTION + } + + @SuppressWarnings("InnerClassMayBeStatic") + private class AssemblyHelper { + private AssemblyHelper() { + } + + private String buildPrompt(RepairerInput data, String specialInstruction) { + JSONObject prompt = new JSONObject(); + + JSONObject actionData = prompt.putObject("[本次行动信息]"); + actionData.put("[行动描述]", data.getActionDescription()); + JSONObject actionParamsData = actionData.putObject("[行动参数说明]"); + actionParamsData.putAll(data.getParams()); + + JSONArray historyData = prompt.putArray("[历史行动执行结果]"); + data.getHistoryActionResults().forEach(historyAction -> { + JSONObject historyItem = new JSONObject(); + historyItem.put("[行动Key]", historyAction.actionKey()); + historyItem.put("[行动描述]", historyAction.description()); + historyItem.put("[行动结果]", historyAction.result()); + historyData.add(historyItem); + }); + + JSONArray messageData = prompt.putArray("[最近消息列表]"); + messageData.addAll(data.getRecentMessages()); + + if (specialInstruction != null) { + prompt.put("[特殊指令]", specialInstruction); + } + + return prompt.toString(); + } + + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/DynamicActionGenerator.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/DynamicActionGenerator.java new file mode 100644 index 00000000..e366198b --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/DynamicActionGenerator.java @@ -0,0 +1,91 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor; + +import com.alibaba.fastjson2.JSONObject; +import lombok.val; +import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; +import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; +import work.slhaf.partner.api.agent.factory.module.annotation.Init; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; +import work.slhaf.partner.api.chat.pojo.ChatResponse; +import work.slhaf.partner.common.util.ExtractUtil; +import work.slhaf.partner.core.action.ActionCapability; +import work.slhaf.partner.core.action.entity.GeneratedData; +import work.slhaf.partner.core.action.entity.MetaAction; +import work.slhaf.partner.core.action.runner.RunnerClient; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.GeneratorInput; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.GeneratorResult; + +/** + * 负责依据输入内容生成可执行的动态行动单元,并选择是否持久化至 SandboxRunner 容器内 + */ +@AgentSubModule +public class DynamicActionGenerator extends AgentRunningSubModule + implements ActivateModel { + + @InjectCapability + private ActionCapability actionCapability; + + private RunnerClient runnerClient; + + @Init + void init() { + runnerClient = actionCapability.runnerClient(); + } + + @Override + public GeneratorResult execute(GeneratorInput input) { + GeneratorResult result = new GeneratorResult(); + try { + // 由于 SCRIPT 类型程序都是在 SandboxRunner 内部的磁盘上加载然后执行的, + // 所以此处的输入内容也只需要指定输入参数、临时key、是否持久化即可,路径将按照指定规则统一构建,不可交给LLM生成 + String prompt = buildPrompt(input); + + // 响应结果需要包含几个特殊数据: 依赖项、代码内容、是否序列化、响应数据释义 + ChatResponse response = this.singleChat(prompt); + GeneratedData generatorData = JSONObject + .parseObject(ExtractUtil.extractJson(response.getMessage()), GeneratedData.class); + + val location = runnerClient.buildTmpPath(input.getActionName(), generatorData.getCodeType()); + MetaAction tempAction = new MetaAction( + input.getActionName(), + true, + MetaAction.Type.ORIGIN, + location + ); + // 将临时行动单元序列化至临时文件夹,并设置程序路径、放置在队列中,等待执行状态变化,并根据序列化选项选择是否补充 MetaActionInfo 并持久序列化 + // 通过 ActionCapability 暴露的接口,序列化至临时文件夹,同时返回Path对象并设置。队列建议交给 SandboxRunner + // 持有,包括监听与序列化线程 + runnerClient.tmpSerialize(tempAction, generatorData.getCode(), generatorData.getCodeType()); + if (generatorData.isSerialize()) { + waitingSerialize(); + } + result.setTempAction(tempAction); + } catch (Exception e) { + result.setTempAction(null); + } + return result; + } + + private void waitingSerialize() { + throw new UnsupportedOperationException("Unimplemented method 'waitingSerialize'"); + } + + private String buildPrompt(GeneratorInput data) { + JSONObject prompt = new JSONObject(); + prompt.put("[行动描述]", data.getDescription()); + // prompt.putObject("[行动参数]").putAll(data.getParams()); + prompt.putObject("[行动参数描述]").putAll(data.getParamsDescription()); + return prompt.toString(); + } + + @Override + public String modelKey() { + return "dynamic_generator"; + } + + @Override + public boolean withBasicPrompt() { + return false; + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ParamsExtractor.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ParamsExtractor.java new file mode 100644 index 00000000..9caf2686 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ParamsExtractor.java @@ -0,0 +1,75 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; +import work.slhaf.partner.api.chat.pojo.ChatResponse; +import work.slhaf.partner.core.action.entity.MetaActionInfo; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ExtractorInput; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ExtractorResult; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.HistoryAction; + +import java.util.HashMap; +import java.util.List; + +/** + * 负责依据输入内容进行行动单元的参数信息提取 + */ +@Slf4j +@AgentSubModule +public class ParamsExtractor extends AgentRunningSubModule implements ActivateModel { + + @Override + public ExtractorResult execute(ExtractorInput input) { + String prompt = buildPrompt(input); + ChatResponse response = this.singleChat(prompt); + ExtractorResult result; + try { + result = JSONObject.parseObject(response.getMessage(), ExtractorResult.class); + } catch (Exception e) { + log.error("ParamsExtractor解析结果失败,返回内容:{}", response.getMessage(), e); + result = new ExtractorResult(); + result.setOk(false); + result.setParams(new HashMap<>()); + } + return result; + } + + private String buildPrompt(ExtractorInput input) { + JSONObject prompt = new JSONObject(); + + JSONObject actionData = prompt.putObject("[本次行动信息]"); + MetaActionInfo actionInfo = input.getMetaActionInfo(); + actionData.put("[行动描述]", actionInfo.getDescription()); + actionData.put("[行动参数说明]", actionInfo.getParams()); + + JSONArray historyData = prompt.putArray("[历史行动执行结果]"); + List historyActions = input.getHistoryActionResults(); + for (HistoryAction historyAction : historyActions) { + JSONObject historyItem = new JSONObject(); + historyItem.put("[行动Key]", historyAction.actionKey()); + historyItem.put("[行动描述]", historyAction.description()); + historyItem.put("[行动结果]", historyAction.result()); + historyData.add(historyItem); + } + + JSONArray messageData = prompt.putArray("[最近消息列表]"); + messageData.addAll(input.getRecentMessages()); + + return prompt.toString(); + } + + @Override + public String modelKey() { + return "params_extractor"; + } + + @Override + public boolean withBasicPrompt() { + return false; + } + +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ActionExecutorInput.kt b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ActionExecutorInput.kt new file mode 100644 index 00000000..f21db99d --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ActionExecutorInput.kt @@ -0,0 +1,5 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.entity + +import work.slhaf.partner.core.action.entity.ActionData + +data class ActionExecutorInput(val actions: Set) diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/CorrectorInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/CorrectorInput.java new file mode 100644 index 00000000..1c2c9af8 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/CorrectorInput.java @@ -0,0 +1,24 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; + +import lombok.Builder; +import lombok.Data; +import work.slhaf.partner.api.chat.pojo.Message; +import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.memory.pojo.EvaluatedSlice; + +import java.util.List; + +@Data +@Builder +public class CorrectorInput { + private String tendency; + private String source; + private String reason; + private String description; + + private List history; + private ActionData.ActionStatus status; + + private List recentMessages; + private List activatedSlices; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/CorrectorResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/CorrectorResult.java new file mode 100644 index 00000000..a2c267e2 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/CorrectorResult.java @@ -0,0 +1,11 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; + +import lombok.Data; +import work.slhaf.partner.module.modules.action.interventor.entity.MetaIntervention; + +import java.util.List; + +@Data +public class CorrectorResult { + private List metaInterventionList; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ExtractorInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ExtractorInput.java new file mode 100644 index 00000000..4a99b457 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ExtractorInput.java @@ -0,0 +1,32 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; + +import lombok.Data; +import work.slhaf.partner.api.chat.pojo.Message; +import work.slhaf.partner.core.action.entity.MetaActionInfo; +import work.slhaf.partner.core.memory.pojo.EvaluatedSlice; + +import java.util.List; + +@Data +public class ExtractorInput { + /** + * 目标 MetaActionInfo + */ + private MetaActionInfo metaActionInfo; + /** + * 可参考的记忆切片 + */ + private List evaluatedSlices; + /** + * 历史行动执行结果 + */ + private List historyActionResults; + /** + * 最近的消息列表 + */ + private List recentMessages; + /** + * 额外的上下文信息(可来自修复器等) + */ + private List additionalContext; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ExtractorResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ExtractorResult.java new file mode 100644 index 00000000..aefb5ba1 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ExtractorResult.java @@ -0,0 +1,11 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; + +import lombok.Data; + +import java.util.Map; + +@Data +public class ExtractorResult { + private boolean ok; + private Map params; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/GeneratorInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/GeneratorInput.java new file mode 100644 index 00000000..67c9094a --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/GeneratorInput.java @@ -0,0 +1,13 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; + +import lombok.Data; + +import java.util.Map; + +@Data +public class GeneratorInput { + private String actionName; + private Map params; + private String description; + private Map paramsDescription; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/GeneratorResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/GeneratorResult.java new file mode 100644 index 00000000..0b8572fb --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/GeneratorResult.java @@ -0,0 +1,9 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; + +import lombok.Data; +import work.slhaf.partner.core.action.entity.MetaAction; + +@Data +public class GeneratorResult { + private MetaAction tempAction; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/HistoryAction.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/HistoryAction.java new file mode 100644 index 00000000..cf36f1ed --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/HistoryAction.java @@ -0,0 +1,4 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; + +public record HistoryAction(String actionKey, String description, String result) { +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/RepairerInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/RepairerInput.java new file mode 100644 index 00000000..dd470a13 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/RepairerInput.java @@ -0,0 +1,17 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; + +import lombok.Data; +import work.slhaf.partner.api.chat.pojo.Message; + +import java.util.List; +import java.util.Map; + +@Data +public class RepairerInput { + + private String userId; + private List recentMessages; + private Map params; + private String actionDescription; + private List historyActionResults; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/RepairerResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/RepairerResult.java new file mode 100644 index 00000000..c6e2c999 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/RepairerResult.java @@ -0,0 +1,30 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; + +import lombok.Data; + +import java.util.List; + +/** + * 行动修复结果,包含行动状态和修复后的参数 + */ +@Data +public class RepairerResult { + + private RepairerStatus status; + private List fixedData; + + public enum RepairerStatus { + /** + * 成功修复: 携带修复后参数; 此种情况对应 Repairer 通过某种方式获取到了完整的参数(调用额外的行动) + */ + OK, + /** + * 发送了自对话请求干预行动,这类一般是补充信息或者提供行动指导,后续必须再步入修复进程,但需要设置层级 + */ + ACQUIRE, + /** + * 修复失败(简单修复、自对话通道均出现错误,正常情况不应该出现) + */ + FAILED + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/exception/ActionExecutingFailedException.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/exception/ActionExecutingFailedException.java new file mode 100644 index 00000000..f10273d1 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/exception/ActionExecutingFailedException.java @@ -0,0 +1,14 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor.exception; + +import work.slhaf.partner.api.agent.runtime.exception.AgentRuntimeException; + +public class ActionExecutingFailedException extends AgentRuntimeException { + + public ActionExecutingFailedException(String message) { + super(message); + } + + public ActionExecutingFailedException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt new file mode 100644 index 00000000..2c867e4a --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt @@ -0,0 +1,400 @@ +package work.slhaf.partner.module.modules.action.dispatcher.scheduler + +import com.cronutils.model.CronType +import com.cronutils.model.definition.CronDefinition +import com.cronutils.model.definition.CronDefinitionBuilder +import com.cronutils.model.time.ExecutionTime +import com.cronutils.parser.CronParser +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import org.slf4j.LoggerFactory +import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability +import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule +import work.slhaf.partner.api.agent.factory.module.annotation.Init +import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule +import work.slhaf.partner.core.action.ActionCapability +import work.slhaf.partner.core.action.entity.ActionData +import work.slhaf.partner.core.action.entity.ScheduledActionData +import work.slhaf.partner.module.modules.action.dispatcher.executor.ActionExecutor +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput +import java.io.Closeable +import java.time.Duration +import java.time.ZonedDateTime +import java.time.temporal.ChronoUnit +import java.util.stream.Collectors +import kotlin.jvm.optionals.getOrNull + +@AgentSubModule +class ActionScheduler : AgentRunningSubModule, Void>() { + + @InjectCapability + private lateinit var actionCapability: ActionCapability + + @InjectModule + private lateinit var actionExecutor: ActionExecutor + + private lateinit var timeWheel: TimeWheel + + private val schedulerScope = + CoroutineScope(Dispatchers.Default + SupervisorJob() + CoroutineName("ActionScheduler")) + + companion object { + private val log = LoggerFactory.getLogger(ActionScheduler::class.java) + } + + @Init + fun init() { + val listScheduledActions: () -> Set = { + actionCapability.listActions(null, null) + .stream() + .filter { it is ScheduledActionData } + .map { it as ScheduledActionData } + .collect(Collectors.toSet()) + } + + val onTrigger: (Set) -> Unit = { actionExecutor.execute(ActionExecutorInput(it)) } + + timeWheel = TimeWheel(listScheduledActions, onTrigger) + + setupShutdownHook() + } + + private fun setupShutdownHook() { + Runtime.getRuntime().addShutdownHook(Thread { + timeWheel.close() + schedulerScope.cancel() + }) + } + + override fun execute(scheduledActionDataSet: Set?): Void? { + schedulerScope.launch { + scheduledActionDataSet?.run { + for (scheduledActionData in scheduledActionDataSet) { + log.debug("New action to schedule: {}", scheduledActionData) + actionCapability.putAction(scheduledActionData) + timeWheel.schedule(scheduledActionData) + } + } + } + return null + } + + private class TimeWheel( + val listScheduledActions: () -> Set, + val onTrigger: (toTrigger: Set) -> Unit + ) : Closeable { + + private val actionsGroupByHour = Array>(24) { mutableSetOf() } + private val wheel = Array>(60 * 60) { mutableSetOf() } + private var recordHour: Int = -1 + private var recordDay: Int = -1 + private val state = MutableStateFlow(WheelState.SLEEPING) + + private val wheelActionsLock = Mutex() + private val timeWheelScope = CoroutineScope(SupervisorJob() + Dispatchers.Default + CoroutineName("TimeWheel")) + + private val cronDefinition: CronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ) + private val cronParser: CronParser = CronParser(cronDefinition) + + /** + * 根据 primaryActions 建立时间轮,并只加载当天任务,同时启动 tick 线程 + */ + init { + // 启动时间轮 + launchWheel() + } + + suspend fun schedule(actionData: ScheduledActionData) { + if (actionData.status != ActionData.ActionStatus.PREPARE) { + return + } + + checkThenExecute { + val parseToZonedDateTime = parseToZonedDateTime( + actionData.scheduleType, + actionData.scheduleContent, + it + ) ?: run { + logFailedStatus(actionData) + return@checkThenExecute + } + log.debug("Action next execution time: {}", parseToZonedDateTime) + + val hour = parseToZonedDateTime.hour + actionsGroupByHour[hour].add(actionData) + log.debug("Action scheduled at {}", hour) + + if (it.hour == hour) { + val wheelOffset = parseToZonedDateTime.minute * 60 + parseToZonedDateTime.second + wheel[wheelOffset].add(actionData) + state.value = WheelState.ACTIVE + log.debug("Action scheduled at wheel offset {}", wheelOffset) + } + + } + } + + private fun launchWheel() { + + fun collectToTrigger(tick: Int, previousTick: Int, triggerHour: Int): Set? { + if (tick > previousTick) { + val toTrigger = mutableSetOf() + for (i in previousTick..tick) { + val bucket = wheel[i] + if (bucket.isNotEmpty()) { + toTrigger.addAll(bucket) + val bucketUuids = bucket.asSequence().map { it.uuid }.toHashSet() + actionsGroupByHour[triggerHour].removeIf { it.uuid in bucketUuids } + bucket.clear() // 避免重复触发 + } + } + return toTrigger + } + return null + } + + suspend fun CoroutineScope.wheel(launchingTime: ZonedDateTime, primaryTickAdvanceTime: Long) { + val launchingHour = launchingTime.hour + var tick = launchingTime.minute * 60 + launchingTime.second + + // 让节拍器从“启动时刻的下一秒”开始(避免立即 step=0) + var nextTickNanos = primaryTickAdvanceTime + 1_000_000_000L + + while (isActive) { + // 1) 计算落后多少秒:至少 1(正常推进),也可能 >1(追赶) + val now0 = System.nanoTime() + val lagNanos = now0 - nextTickNanos + val step = if (lagNanos < 0) 1 else (lagNanos / 1_000_000_000L).toInt() + 1 + + val previousTick = tick + tick = (tick + step).coerceAtMost(wheel.lastIndex) + + // 2) 推进节拍器:按“理论秒”前进 step 次 + nextTickNanos += step.toLong() * 1_000_000_000L + + var shouldBreak = false + var toTrigger: Set? = null + + checkThenExecute(false) { + if (it.hour != launchingHour) { + shouldBreak = true + toTrigger = collectToTrigger(wheel.lastIndex, previousTick, launchingHour) + log.debug( + "Hour changed, previousTick: {}, tick: {}, toTriggerSize: {}", + previousTick, + tick, + toTrigger?.size + ) + return@checkThenExecute + } + + toTrigger = collectToTrigger(tick, previousTick, launchingHour) + + if (tick >= wheel.lastIndex || actionsGroupByHour[launchingHour].isEmpty()) { + state.value = WheelState.SLEEPING + shouldBreak = true + return@checkThenExecute + } + } + + toTrigger?.takeIf { it.isNotEmpty() }?.let { + onTrigger(it) + log.debug("Executing action at hour {} tick {}", launchingHour, tick) + } + + if (shouldBreak) { + log.debug("Wheel stopped at tick {}", tick) + break + } + + // 3) 精确睡到下一次理论 tick(用最新 nanoTime) + val now1 = System.nanoTime() + val sleepNanos = nextTickNanos - now1 + if (sleepNanos > 0) { + delay(sleepNanos / 1_000_000L) // 毫秒级 delay 足够;剩余 nanos 不必忙等 + } + } + } + + suspend fun wait(currentTime: ZonedDateTime) { + val nextHour = currentTime.truncatedTo(ChronoUnit.HOURS).plusHours(1) + val seconds = Duration.between( + currentTime, nextHour + ).toMillis() + // withTimeoutOrNull 内部已处理 seconds 小于 0 的情况 + log.debug("Start waiting {} ms at {}, target time: {}", seconds, currentTime, nextHour) + withTimeoutOrNull(seconds) { + state.first { it == WheelState.ACTIVE } + } + log.debug("Waiting ended at {}", ZonedDateTime.now()) + } + + timeWheelScope.launch { + while (isActive) { + // 判断是否该步入下一小时 + var shouldWait: Boolean? = null + var currentTime: ZonedDateTime? = null + var primaryTickAdvanceTime: Long? = null + checkThenExecute { + currentTime = it + shouldWait = actionsGroupByHour[it.hour].isEmpty() + // 由于 wheel 的启动时间可能存在延迟,而时内推进由 nanoTime 保证不会漏发, + // 正常的时序结束又由 tick 是否触顶、当前时是否存在额外任务触发, + // 而启动时无触发保障,此时一并初始化 tick 推进时间,足以应对 check 与 wheel 间的这段时间间隔 + primaryTickAdvanceTime = System.nanoTime() + } + + // 如果该时无任务则等待,插入事件可提前唤醒 + if (shouldWait!!) { + // 计算距离下一小时的时间,等待 + currentTime?.let { wait(it) } + continue + } + + // 唤醒进行时间轮循环 + wheel(currentTime!!, primaryTickAdvanceTime!!) + } + } + } + + suspend fun checkThenExecute(finallyToExecute: Boolean = true, then: (currentTime: ZonedDateTime) -> Unit) = + wheelActionsLock.withLock { + fun loadActions( + source: Set, + now: ZonedDateTime, + load: (latestExecutingTime: ZonedDateTime, actionData: ScheduledActionData) -> Unit, + repair: () -> Unit + ) { + val runLoading = { + for (actionData in source) { + val nextExecutingTime = + parseToZonedDateTime( + actionData.scheduleType, + actionData.scheduleContent, + now + ) ?: run { + logFailedStatus(actionData) + continue + } + + load(nextExecutingTime, actionData) + } + } + + repair() + runLoading() + } + + fun loadHourActions(currentTime: ZonedDateTime) { + val load: (ZonedDateTime, ScheduledActionData) -> Unit = { latestExecutionTime, actionData -> + val secondsTime = latestExecutionTime.minute * 60 + latestExecutionTime.second + wheel[secondsTime].add(actionData) + log.debug("Action loaded to hour: {}", actionData) + } + + val repair: () -> Unit = { + for (set in wheel) { + set.clear() + } + } + + loadActions(actionsGroupByHour[currentTime.hour], currentTime, load, repair) + } + + fun loadDayActions(currentTime: ZonedDateTime) { + val load: (ZonedDateTime, ScheduledActionData) -> Unit = { latestExecutingTime, actionData -> + actionsGroupByHour[latestExecutingTime.hour].add(actionData) + log.debug("Action loaded to day: {}", actionData) + } + + val repair: () -> Unit = { + for (set in actionsGroupByHour) { + set.clear() + } + } + + loadActions(listScheduledActions(), currentTime, load, repair) + } + + fun refreshIfNeeded(now: ZonedDateTime) { + val d = now.dayOfMonth + val h = now.hour + if (d != recordDay) { + recordDay = d + recordHour = h + loadDayActions(now) + loadHourActions(now) + } else if (h != recordHour) { + recordHour = h + loadHourActions(now) + } + } + + val now = ZonedDateTime.now() + + if (finallyToExecute) { + refreshIfNeeded(now) + then(now) + } else { + then(now) + refreshIfNeeded(now) + } + } + + private fun parseToZonedDateTime( + scheduleType: ScheduledActionData.ScheduleType, + scheduleContent: String, + now: ZonedDateTime + ): ZonedDateTime? { + return when (scheduleType) { + ScheduledActionData.ScheduleType.CYCLE + -> { + val cron = try { + cronParser.parse(scheduleContent).validate() + } catch (_: Exception) { + return null + } + val executionTime = ExecutionTime.forCron(cron) + executionTime.nextExecution(now).getOrNull() + } + + ScheduledActionData.ScheduleType.ONCE -> { + val executionTime = try { + ZonedDateTime.parse(scheduleContent) + } catch (_: Exception) { + return null + } + if (executionTime.plusSeconds(1).isBefore(now) || executionTime.dayOfMonth != now.dayOfMonth) + null + else + executionTime + } + + } + + } + + private fun logFailedStatus(actionData: ScheduledActionData) { + log.warn( + "行动未加载,uuid: {}, source: {}, tendency: {}, scheduleContent: {}", + actionData.uuid, + actionData.source, + actionData.tendency, + actionData.scheduleContent, + ) + } + + override fun close() { + timeWheelScope.cancel() + } + + private enum class WheelState { + ACTIVE, + SLEEPING, + } + } +} \ No newline at end of file diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/ActionInterventor.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/ActionInterventor.java new file mode 100644 index 00000000..f81f1e88 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/ActionInterventor.java @@ -0,0 +1,251 @@ +package work.slhaf.partner.module.modules.action.interventor; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import lombok.val; +import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; +import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule; +import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; +import work.slhaf.partner.core.action.ActionCapability; +import work.slhaf.partner.core.action.ActionCore; +import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.PhaserRecord; +import work.slhaf.partner.core.cognation.CognationCapability; +import work.slhaf.partner.core.memory.MemoryCapability; +import work.slhaf.partner.module.common.module.PreRunningModule; +import work.slhaf.partner.module.modules.action.interventor.entity.InterventionType; +import work.slhaf.partner.module.modules.action.interventor.entity.MetaIntervention; +import work.slhaf.partner.module.modules.action.interventor.evaluator.InterventionEvaluator; +import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorInput; +import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorResult; +import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorResult.EvaluatedInterventionData; +import work.slhaf.partner.module.modules.action.interventor.recognizer.InterventionRecognizer; +import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.RecognizerInput; +import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.RecognizerResult; +import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +/** + * 负责识别潜在的行动干预信息,作用于正在进行或已存在的行动池中内容 + */ +@AgentModule(name = "action_identifier", order = 2) +public class ActionInterventor extends PreRunningModule implements ActivateModel { + + @InjectModule + private InterventionRecognizer interventionRecognizer; + @InjectModule + private InterventionEvaluator interventionEvaluator; + + @InjectCapability + private ActionCapability actionCapability; + @InjectCapability + private CognationCapability cognationCapability; + @InjectCapability + private MemoryCapability memoryCapability; + + private final AssemblyHelper assemblyHelper = new AssemblyHelper(); + private final PromptHelper promptHelper = new PromptHelper(); + + /** + * 键: 本次调用uuid; + * 值:本次调用对应的prompt; + */ + private final Map> interventionPrompt = new HashMap<>(); + + @Override + protected void doExecute(PartnerRunningFlowContext context) { + // 综合当前正在进行的行动链信息、用户交互历史、激活的记忆切片,尝试识别出是否存在行动干预意图 + // 首先通过recognizer进行快速意图识别,识别成功则步入评估阶段,评估成功则直接作用于目标行动链 + // 进行快速意图识别时必须结合近期对话与进行中行动链情况 + + // 干预意图识别 + String uuid = context.getUuid(); + String userId = context.getUserId(); + RecognizerResult recognizerResult = interventionRecognizer + .execute(assemblyHelper.buildRecognizerInput(userId, context.getInput())); // 此处的输入内容携带了所有 PhaserRecord + if (!recognizerResult.isOk()) { + promptHelper.setupNoInterventionPrompt(uuid); + return; + } + + // 干预意图评估 + EvaluatorResult evaluatorResult = interventionEvaluator + .execute(assemblyHelper.buildEvaluatorInput(recognizerResult, userId)); + List executingDataList = evaluatorResult.getExecutingDataList(); + List preparedDataList = evaluatorResult.getPreparedDataList(); + + // 意图评估结果处理 + if (evaluatorResult.isOk()) { + // 对存在‘异常ActionKey’的评估结果列表进行过滤 + invalidActionKeysFilter(executingDataList); + invalidActionKeysFilter(preparedDataList); + + // 同步写入prompt,异步处理干预行为,‘异步’在处理流程中体现 + promptHelper.setupInterventionPrompt(uuid, executingDataList, preparedDataList); + handleInterventions(executingDataList, recognizerResult.getExecutingInterventions()); + handleInterventions(preparedDataList, recognizerResult.getPreparedInterventions()); + } else { + promptHelper.setupInterventionIgnoredPrompt(uuid, executingDataList, preparedDataList); + } + + } + + private void handleInterventions(List interventionDataList, Map interventionDataMap) { + val executor = actionCapability.getExecutor(ActionCore.ExecutorType.PLATFORM); + executor.execute(() -> { + for (EvaluatedInterventionData interventionData : interventionDataList) { + // 此处拿到的为 ActionData 或者 PhaserRecord, 来自 Recognizer 的封装 + val data = interventionDataMap.get(interventionData.getTendency()); + actionCapability.handleInterventions(interventionData.getMetaInterventionList(), data); + } + }); + } + + private void invalidActionKeysFilter(List interventions) { + + List toRemove = new ArrayList<>(); + + for (EvaluatedInterventionData intervention : interventions) { + List interventionData = intervention.getMetaInterventionList(); + List actions = new ArrayList<>(); + for (MetaIntervention metaData : interventionData) { + actions.addAll(metaData.getActions()); + } + // 如果存在异常行动key,则可视为该评估结果存在问题,直接忽略该结果 + if (!actionCapability.checkExists(actions.toArray(String[]::new))) { + toRemove.add(intervention); + } + + // 针对 REBUILD 类型进行特殊校验, REBUILD 类型必须满足所有 MetaIntervention 的类型均为 REBUILD + if (!checkRebuildType(interventionData)) { + toRemove.add(intervention); + } + } + + interventions.removeAll(toRemove); + } + + private boolean checkRebuildType(List interventionData) { + boolean hasRebuild = false; + for (MetaIntervention meta : interventionData) { + if (meta.getType() == InterventionType.REBUILD) { + hasRebuild = true; + } else if (hasRebuild) { + // 已经存在REBUILD类型,但又发现了非REBUILD类型,不合法 + return false; + } + } + + return true; + } + + @Override + public String modelKey() { + return "action_identifier"; + } + + @Override + public boolean withBasicPrompt() { + return false; + } + + @Override + protected Map getPromptDataMap(PartnerRunningFlowContext context) { + return interventionPrompt.remove(context.getUuid()); + } + + @Override + protected String moduleName() { + return "[行动干预识别模块]"; + } + + private final class AssemblyHelper { + private AssemblyHelper() { + } + + private RecognizerInput buildRecognizerInput(String userId, String input) { + RecognizerInput recognizerInput = new RecognizerInput(); + recognizerInput.setInput(input); + recognizerInput.setUserDialogMapStr(memoryCapability.getUserDialogMapStr(userId)); + // 参考的对话列表大小或需调整 + recognizerInput.setRecentMessages(cognationCapability.getChatMessages()); + recognizerInput.setExecutingActions(actionCapability.listPhaserRecords().stream().map(PhaserRecord::actionData).toList()); + recognizerInput.setPreparedActions(actionCapability.listActions(ActionData.ActionStatus.PREPARE, userId).stream().toList()); + return recognizerInput; + } + + private EvaluatorInput buildEvaluatorInput(RecognizerResult recognizerResult, String userId) { + EvaluatorInput input = new EvaluatorInput(); + input.setExecutingInterventions(recognizerResult.getExecutingInterventions()); + input.setPreparedInterventions(recognizerResult.getPreparedInterventions()); + input.setRecentMessages(cognationCapability.getChatMessages()); + input.setActivatedSlices(memoryCapability.getActivatedSlices(userId)); + return input; + } + } + + private final class PromptHelper { + private PromptHelper() { + } + + private void setupInterventionIgnoredPrompt(String uuid, List executingDataList, List preparedDataList) { + List total = Stream.concat(executingDataList.stream(), preparedDataList.stream()).toList(); + + JSONArray reasons = new JSONArray(); + + for (EvaluatedInterventionData data : total) { + JSONObject reason = reasons.addObject(); + reason.put("[干预倾向]", data.getTendency()); + reason.put("[未采用原因]", data.getDescription()); + } + + synchronized (interventionPrompt) { + interventionPrompt.put(uuid, Map.of( + "[识别状态] <是否识别到干预已存在行动的意图>", "识别到,但都未采用", + "[忽略原因] <各个意图被忽略的原因>", reasons.toString(), + "[干预行动] <将对已存在行动做出的行为>", "无行为")); + } + } + + private void setupInterventionPrompt(String uuid, List executingDataList, + List preparedDataList) { + JSONArray contents = new JSONArray(); + List temp = Stream.concat(executingDataList.stream(), preparedDataList.stream()).toList(); + + for (EvaluatedInterventionData data : temp) { + if (!data.isOk()) { + continue; + } + String tendency = data.getTendency(); + JSONObject newElement = contents.addObject(); + newElement.put("[干预倾向]", tendency); + JSONArray changes = newElement.putArray("[行动链变动情况]"); + + for (MetaIntervention intervention : data.getMetaInterventionList()) { + JSONObject change = changes.addObject(); + change.put("[干预类型]", intervention.getType()); + change.put("[干预序号]", intervention.getOrder()); + change.putArray("[干预内容]").addAll(intervention.getActions()); + } + } + + synchronized (interventionPrompt) { + interventionPrompt.put(uuid, Map.of( + "[识别状态] <是否识别到干预已存在行动的意图>", "识别到,将采用", + "[干预内容] <将对已存在行动做出的行为>", contents.toString())); + } + } + + private void setupNoInterventionPrompt(String uuid) { + interventionPrompt.put(uuid, Map.of( + "[识别状态] <是否识别到干预已存在行动的意图>", "未识别到干预意图", + "[干预行动] <将对已存在行动做出的行为>", "无行动")); + } + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/entity/InterventionType.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/entity/InterventionType.java new file mode 100644 index 00000000..19164c1a --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/entity/InterventionType.java @@ -0,0 +1,28 @@ +package work.slhaf.partner.module.modules.action.interventor.entity; + +public enum InterventionType { + /** + * 追加行动: 追加至指定行动链序列之后才执行 + */ + APPEND, + + /** + * 插入行动: 指定行动链序列执行过程中即时新增并执行 + */ + INSERT, + + /** + * 重建行动: 重建指定行动链序列之后的所有行动内容 + */ + REBUILD, + + /** + * 删除行动: 删除指定行动链序列上的指定行动单元 + */ + DELETE, + + /** + * 取消行动链: 中断并取消指定行动链的执行 + */ + CANCEL +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/entity/MetaIntervention.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/entity/MetaIntervention.java new file mode 100644 index 00000000..0984548d --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/entity/MetaIntervention.java @@ -0,0 +1,21 @@ +package work.slhaf.partner.module.modules.action.interventor.entity; + +import lombok.Data; + +import java.util.List; + +@Data +public class MetaIntervention { + /** + * 干预数据类型 + */ + private InterventionType type; + /** + * 干预数据对应的行动链序列 + */ + private int order; + /** + * 干预数据所需的行动key列表 + */ + private List actions; +} \ No newline at end of file diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/InterventionEvaluator.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/InterventionEvaluator.java new file mode 100644 index 00000000..f0675e9f --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/InterventionEvaluator.java @@ -0,0 +1,99 @@ +package work.slhaf.partner.module.modules.action.interventor.evaluator; + +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; +import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; +import work.slhaf.partner.api.chat.pojo.ChatResponse; +import work.slhaf.partner.api.chat.pojo.Message; +import work.slhaf.partner.core.action.ActionCapability; +import work.slhaf.partner.core.action.ActionCore.ExecutorType; +import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.memory.pojo.EvaluatedSlice; +import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorInput; +import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorResult; +import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorResult.EvaluatedInterventionData; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; + +@Slf4j +@AgentSubModule +public class InterventionEvaluator extends AgentRunningSubModule + implements ActivateModel { + + @InjectCapability + private ActionCapability actionCapability; + + /** + * 基于干预意图、记忆切片、交互上下文、已有行动程序综合评估,尝试评估并选取出合适的行动程序,交付给 ActionInterventor + */ + @Override + public EvaluatorResult execute(EvaluatorInput input) { + // 获取必须数据 + ExecutorService executor = actionCapability.getExecutor(ExecutorType.VIRTUAL); + Map executingInterventions = input.getExecutingInterventions(); + Map preparedInterventions = input.getPreparedInterventions(); + CountDownLatch latch = new CountDownLatch(executingInterventions.size() + preparedInterventions.size()); + + // 创建结果容器 + EvaluatorResult result = new EvaluatorResult(); + List executingDataList = result.getExecutingDataList(); + List preparedDataList = result.getPreparedDataList(); + + // 并发评估 + evaluateIntervention(executingDataList, executingInterventions, input, executor, latch); + evaluateIntervention(preparedDataList, preparedInterventions, input, executor, latch); + + try { + latch.await(); + } catch (InterruptedException e) { + log.warn("CountDownLatch阻塞已中断"); + } + + return result; + } + + private void evaluateIntervention(List evaluatedDataList, Map interventionMap, EvaluatorInput input, ExecutorService executor, CountDownLatch latch) { + interventionMap.forEach((tendency, actionData) -> executor.execute(() -> { + try { + String prompt = buildPrompt(input.getRecentMessages(), input.getActivatedSlices(), actionData, tendency); + + ChatResponse response = this.singleChat(prompt); + EvaluatedInterventionData evaluatedData = JSONObject.parseObject(response.getMessage(), + EvaluatedInterventionData.class); + synchronized (evaluatedDataList) { + evaluatedDataList.add(evaluatedData); + } + } catch (Exception e) { + log.error("干预意图评估出错: {}", tendency, e); + } finally { + latch.countDown(); + } + })); + } + + private String buildPrompt(List recentMessages, List activatedSlices, + ActionData actionData, String tendency) { + JSONObject json = new JSONObject(); + json.put("干预倾向", tendency); + json.putArray("近期对话").addAll(recentMessages); + json.putArray("参考记忆").addAll(activatedSlices); + json.put("将干预的行动", JSONObject.toJSONString(actionData)); + return json.toJSONString(); + } + + @Override + public String modelKey() { + return "intervention_evaluator"; + } + + @Override + public boolean withBasicPrompt() { + return false; + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/entity/EvaluatorInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/entity/EvaluatorInput.java new file mode 100644 index 00000000..d25d8729 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/entity/EvaluatorInput.java @@ -0,0 +1,17 @@ +package work.slhaf.partner.module.modules.action.interventor.evaluator.entity; + +import lombok.Data; +import work.slhaf.partner.api.chat.pojo.Message; +import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.memory.pojo.EvaluatedSlice; + +import java.util.List; +import java.util.Map; + +@Data +public class EvaluatorInput { + private Map executingInterventions; + private Map preparedInterventions; + private List activatedSlices; + private List recentMessages; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/entity/EvaluatorResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/entity/EvaluatorResult.java new file mode 100644 index 00000000..bd249426 --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/entity/EvaluatorResult.java @@ -0,0 +1,33 @@ +package work.slhaf.partner.module.modules.action.interventor.evaluator.entity; + +import lombok.Data; +import work.slhaf.partner.module.modules.action.interventor.entity.MetaIntervention; + +import java.util.List; + +/** + * 干预倾向评估结果,包含评估通过的倾向文本、对行动链的行为、指定操作的行动单元key、未通过的原因 + */ +@Data +public class EvaluatorResult { + /** + * 是否存在通过的干预倾向 + */ + private boolean ok; + private List executingDataList; + private List preparedDataList; + + @Data + public static class EvaluatedInterventionData { + /** + * 是否通过 + */ + private boolean ok; + private String tendency; + /** + * 描述信息(包括通过、失败原因) + */ + private String description; + private List metaInterventionList; + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/InterventionRecognizer.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/InterventionRecognizer.java new file mode 100644 index 00000000..b809f35d --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/InterventionRecognizer.java @@ -0,0 +1,102 @@ +package work.slhaf.partner.module.modules.action.interventor.recognizer; + +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; +import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; +import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; +import work.slhaf.partner.api.chat.pojo.ChatResponse; +import work.slhaf.partner.core.action.ActionCapability; +import work.slhaf.partner.core.action.ActionCore; +import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.MetaRecognizerResult; +import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.RecognizerInput; +import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.RecognizerResult; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; + +@Slf4j +@AgentSubModule +public class InterventionRecognizer extends AgentRunningSubModule implements ActivateModel { + + @InjectCapability + private ActionCapability actionCapability; + + @Override + public RecognizerResult execute(RecognizerInput input) { + // 获取必须数据 + ExecutorService executor = actionCapability.getExecutor(ActionCore.ExecutorType.VIRTUAL); + List executingActions = input.getExecutingActions(); + List preparedActions = input.getPreparedActions(); + CountDownLatch countDownLatch = new CountDownLatch(executingActions.size() + preparedActions.size()); + + // 创建结果容器 + RecognizerResult recognizerResult = new RecognizerResult(); + Map executingInterventions = recognizerResult.getExecutingInterventions(); + Map preparedInterventions = recognizerResult.getPreparedInterventions(); + + // 执行识别操作 + recognizeIntervention(executingInterventions, executingActions, executor, input, countDownLatch); + recognizeIntervention(preparedInterventions, preparedActions, executor, input, countDownLatch); + + try { + countDownLatch.await(); + } catch (InterruptedException e) { + log.warn("CountDownLatch阻塞已中断"); + } + return recognizerResult; + } + + private void recognizeIntervention(Map interventionsMap, List actions, ExecutorService executor, RecognizerInput input, CountDownLatch latch) { + for (ActionData data : actions) { + executor.execute(() -> { + try { + String prompt = buildPrompt(data, input); + ChatResponse response = this.singleChat(prompt); + MetaRecognizerResult result = JSONObject.parseObject(response.getMessage(), MetaRecognizerResult.class); + if (result.isOk()) { + synchronized (interventionsMap) { + interventionsMap.put(result.getIntervention(), data); + } + } + } catch (Exception e) { + log.error("LLM干预意图提取出错", e); + } finally { + latch.countDown(); + } + }); + } + } + + private String buildPrompt(ActionData actionData, RecognizerInput input) { + JSONObject json = new JSONObject(); + + JSONObject actionInfo = json.putObject("行动信息"); + actionInfo.put("行动倾向", actionData.getTendency()); + actionInfo.put("行动原因", actionData.getReason()); + actionInfo.put("行动描述", actionData.getDescription()); + actionInfo.put("行动状态", actionData.getStatus()); + actionInfo.put("行动来源", actionData.getSource()); + + JSONObject interactionInfo = json.putObject("交互信息"); + interactionInfo.put("用户输入", input.getInput()); + interactionInfo.put("当前对话", input.getRecentMessages()); + interactionInfo.put("近期对话", input.getUserDialogMapStr()); + + return json.toString(); + } + + @Override + public String modelKey() { + return "intervention_recognizer"; + } + + @Override + public boolean withBasicPrompt() { + return false; + } +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/MetaRecognizerResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/MetaRecognizerResult.java new file mode 100644 index 00000000..4c81233b --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/MetaRecognizerResult.java @@ -0,0 +1,9 @@ +package work.slhaf.partner.module.modules.action.interventor.recognizer.entity; + +import lombok.Data; + +@Data +public class MetaRecognizerResult { + private boolean ok; + private String intervention; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/RecognizerInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/RecognizerInput.java new file mode 100644 index 00000000..9deca7cf --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/RecognizerInput.java @@ -0,0 +1,22 @@ +package work.slhaf.partner.module.modules.action.interventor.recognizer.entity; + +import lombok.Data; +import work.slhaf.partner.api.chat.pojo.Message; +import work.slhaf.partner.core.action.entity.ActionData; + +import java.util.List; + +@Data +public class RecognizerInput { + private String input; + private List recentMessages; + /** + * 当前用户对应的近两日对话缓存 + */ + private String userDialogMapStr; + /** + * 正在执行的行动-Phaser记录列表,在Recognizer中结合本次输入并发评估(考虑到不同行动链之间对LLM的影响) + */ + private List executingActions; + private List preparedActions; +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/RecognizerResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/RecognizerResult.java new file mode 100644 index 00000000..e05511ec --- /dev/null +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/RecognizerResult.java @@ -0,0 +1,29 @@ +package work.slhaf.partner.module.modules.action.interventor.recognizer.entity; + +import lombok.Data; +import work.slhaf.partner.core.action.entity.ActionData; + +import java.util.HashMap; +import java.util.Map; + +@Data +public class RecognizerResult { + + private boolean ok; + + /** + *

将被干预的‘执行中行动’

+ * key: 干预倾向 + *
+ * value: 干预倾向将作用的行动数据 + */ + private Map executingInterventions = new HashMap<>(); + + /** + *

将被干预的‘等待中行动’

+ * key: 干预倾向 + *
+ * value: 干预倾向将作用的行动数据 + */ + private Map preparedInterventions = new HashMap<>(); +} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java index abfbe049..4456406a 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java @@ -1,15 +1,19 @@ package work.slhaf.partner.module.modules.action.planner; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.jetbrains.annotations.NotNull; import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; -import work.slhaf.partner.api.agent.factory.module.annotation.AfterExecute; import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule; import work.slhaf.partner.api.agent.factory.module.annotation.Init; import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule; import work.slhaf.partner.api.chat.pojo.Message; -import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor; import work.slhaf.partner.common.vector.VectorClient; import work.slhaf.partner.core.action.ActionCapability; +import work.slhaf.partner.core.action.ActionCore; import work.slhaf.partner.core.action.entity.*; +import work.slhaf.partner.core.action.entity.cache.CacheAdjustData; +import work.slhaf.partner.core.action.entity.cache.CacheAdjustMetaData; import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.memory.MemoryCapability; import work.slhaf.partner.core.perceive.PerceiveCapability; @@ -25,15 +29,15 @@ import work.slhaf.partner.module.modules.action.planner.extractor.entity.Extract import work.slhaf.partner.module.modules.action.planner.extractor.entity.ExtractorResult; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicBoolean; /** * 负责针对本次输入生成基础的行动计划,在主模型传达意愿后,执行行动或者放入计划池 */ +@Slf4j @AgentModule(name = "action_planner", order = 2) public class ActionPlanner extends PreRunningModule { @@ -53,21 +57,25 @@ public class ActionPlanner extends PreRunningModule { @InjectModule private ActionConfirmer actionConfirmer; - private InteractionThreadPoolExecutor executor; - private ActionAssemblyHelper assemblyHelper; + private ExecutorService executor; + + private final ActionAssemblyHelper assemblyHelper = new ActionAssemblyHelper(); @Init public void init() { - executor = InteractionThreadPoolExecutor.getInstance(); - assemblyHelper = new ActionAssemblyHelper(); + executor = actionCapability.getExecutor(ActionCore.ExecutorType.VIRTUAL); } @Override protected void doExecute(PartnerRunningFlowContext context) { - List> tasks = new ArrayList<>(); - addConfirmTask(tasks, context); - addNewActionTask(tasks, context); - executor.invokeAll(tasks); + try { + List> tasks = new ArrayList<>(); + addConfirmTask(tasks, context); + addNewActionTask(tasks, context); + executor.invokeAll(tasks); + } catch (Exception e) { + log.error("执行异常", e); + } } /** @@ -84,14 +92,15 @@ public class ActionPlanner extends PreRunningModule { return null; } EvaluatorInput evaluatorInput = assemblyHelper.buildEvaluatorInput(extractorResult, context.getUserId()); - List evaluatorResults = actionEvaluator.execute(evaluatorInput); //并发操作均为访问 - setupActionInfo(evaluatorResults, context); + List evaluatorResults = actionEvaluator.execute(evaluatorInput); // 并发操作均为访问 + putActionData(evaluatorResults, context); + updateTendencyCache(evaluatorResults, context.getInput(), extractorResult); return null; }); } - @AfterExecute - private void updateTendencyCache(List evaluatorResults, String input, ExtractorResult extractorResult) { + private void updateTendencyCache(List evaluatorResults, String input, + ExtractorResult extractorResult) { if (!VectorClient.status) { return; } @@ -123,72 +132,69 @@ public class ActionPlanner extends PreRunningModule { tasks.add(() -> { ConfirmerInput confirmerInput = assemblyHelper.buildConfirmerInput(context); ConfirmerResult result = actionConfirmer.execute(confirmerInput); - setupPendingActionInfo(context, result); + setupConfirmedActionInfo(context, result); return null; }); } - private void setupPendingActionInfo(PartnerRunningFlowContext context, ConfirmerResult result) { - //TODO 需考虑未确认任务的失效或者拒绝时机 + private void setupConfirmedActionInfo(PartnerRunningFlowContext context, ConfirmerResult result) { + // TODO 需考虑未确认任务的失效或者拒绝时机,在action core中实现 List uuids = result.getUuids(); if (uuids == null) { return; } - String contextUuid = context.getUuid(); - List pendingActions = actionCapability.popPendingAction(context.getUserId()); - for (MetaActionInfo actionInfo : pendingActions) { - if (uuids.contains(actionInfo.getUuid())) { - actionCapability.putPreparedAction(contextUuid, actionInfo); + List pendingActions = actionCapability.popPendingAction(context.getUserId()); + for (ActionData actionData : pendingActions) { + if (uuids.contains(actionData.getUuid())) { + actionCapability.putAction(actionData); } } } - - private void setupActionInfo(List evaluatorResults, PartnerRunningFlowContext context) { + private void putActionData(List evaluatorResults, PartnerRunningFlowContext context) { for (EvaluatorResult evaluatorResult : evaluatorResults) { - MetaActionInfo metaActionInfo = assemblyHelper.buildMetaActionInfo(evaluatorResult); + ActionData actionData = assemblyHelper.buildActionData(evaluatorResult, context.getUserId()); if (evaluatorResult.isNeedConfirm()) { - actionCapability.putPendingActions(context.getUserId(), metaActionInfo); + actionCapability.putPendingActions(context.getUserId(), actionData); } else { - actionCapability.putPreparedAction(context.getUuid(), metaActionInfo); + actionCapability.putAction(actionData); } } } - @Override - protected HashMap getPromptDataMap(PartnerRunningFlowContext context) { + protected Map getPromptDataMap(PartnerRunningFlowContext context) { HashMap map = new HashMap<>(); - setupPendingActions(map, context.getUserId()); - setupPreparedActions(map, context.getUuid()); + String userId = context.getUserId(); + setupPendingActions(map, userId); + setupPreparedActions(map, userId); return map; } private void setupPendingActions(HashMap map, String userId) { - List actionInfos = actionCapability.listPendingAction(userId); - if (actionInfos == null || actionInfos.isEmpty()) { - map.put("[待确认行动] <待确认行动信息>", "无待确认行动"); + List actionData = actionCapability.listPendingAction(userId); + if (actionData == null || actionData.isEmpty()) { + map.put("[待确认行动] <等待用户确认的行动信息>", "无待确认行动"); return; } - for (int i = 0; i < actionInfos.size(); i++) { - map.put("[待确认行动 " + (i + 1) + " ]", generateActionStr(actionInfos.get(i))); + for (int i = 0; i < actionData.size(); i++) { + map.put("[待确认行动 " + (i + 1) + " ] <等待用户确认的行动信息>", generateActionStr(actionData.get(i))); } } - private void setupPreparedActions(HashMap map, String uuid) { - List actionInfos = actionCapability.listPreparedAction(uuid); - if (actionInfos == null || actionInfos.isEmpty()) { - map.put("[预备行动] <预备行动信息>", "无预备行动"); + private void setupPreparedActions(HashMap map, String userId) { + val preparedActions = actionCapability.listActions(ActionData.ActionStatus.PREPARE, userId).stream().toList(); + if (preparedActions.isEmpty()) { + map.put("[预备行动] <预备执行或放入计划池的行动信息>", "无预备行动"); return; } - for (int i = 0; i < actionInfos.size(); i++) { - map.put("[预备行动 " + (i + 1) + " ]", generateActionStr(actionInfos.get(i))); + for (int i = 0; i < preparedActions.size(); i++) { + map.put("[预备行动 " + (i + 1) + " ] <预备执行或放入计划池的行动信息>", generateActionStr(preparedActions.get(i))); } } - private String generateActionStr(MetaActionInfo metaActionInfo) { - ActionData actionData = metaActionInfo.getActionData(); - return "<行动倾向>" + " : " + metaActionInfo.getTendency() + + private String generateActionStr(ActionData actionData) { + return "<行动倾向>" + " : " + actionData.getTendency() + "<行动原因>" + " : " + actionData.getReason() + "<工具描述>" + " : " + actionData.getDescription(); } @@ -198,7 +204,7 @@ public class ActionPlanner extends PreRunningModule { return "[行动模块]"; } - private class ActionAssemblyHelper { + private final class ActionAssemblyHelper { private ActionAssemblyHelper() { } @@ -225,31 +231,109 @@ public class ActionPlanner extends PreRunningModule { return input; } - private MetaActionInfo buildMetaActionInfo(EvaluatorResult evaluatorResult) { + private ActionData buildActionData(EvaluatorResult evaluatorResult, String userId) { + Map> actionChain = getActionChain(evaluatorResult); return switch (evaluatorResult.getType()) { - case PLANNING -> { - ScheduledActionInfo actionInfo = new ScheduledActionInfo(); - actionInfo.setActionData(evaluatorResult.getActionData()); - actionInfo.setScheduleContent(evaluatorResult.getScheduleContent()); - actionInfo.setStatus(ActionStatus.PREPARE); - actionInfo.setUuid(UUID.randomUUID().toString()); - yield actionInfo; - } - case IMMEDIATE -> { - ImmediateActionInfo actionInfo = new ImmediateActionInfo(); - actionInfo.setActionData(evaluatorResult.getActionData()); - actionInfo.setStatus(ActionStatus.PREPARE); - actionInfo.setUuid(UUID.randomUUID().toString()); - yield actionInfo; - } + case PLANNING -> new ScheduledActionData( + evaluatorResult.getTendency(), + actionChain, + evaluatorResult.getReason(), + evaluatorResult.getDescription(), + userId, + evaluatorResult.getScheduleType(), + evaluatorResult.getScheduleContent() + ); + case IMMEDIATE -> new ImmediateActionData( + evaluatorResult.getTendency(), + actionChain, + evaluatorResult.getReason(), + evaluatorResult.getDescription(), + userId + ); }; } + private @NotNull Map> getActionChain(EvaluatorResult evaluatorResult) { + Map> actionChain = new HashMap<>(); + Map> primaryActionChain = evaluatorResult.getPrimaryActionChain(); + fixDependencies(primaryActionChain); + primaryActionChain.forEach((order, actionKeys) -> { + List metaActions = actionKeys.stream() + .map(actionKey -> actionCapability.loadMetaAction(actionKey)) + .toList(); + actionChain.put(order, metaActions); + }); + return actionChain; + } + + private void fixDependencies(Map> primaryActionChain) { + // 先将 primaryActionChain 的节点序号修正为从1开始依次增大 + fixOrder(primaryActionChain); + List fixedOrders = new ArrayList<>(primaryActionChain.keySet().stream().toList()); + AtomicBoolean fixed = new AtomicBoolean(false); + do { + Set tempOrders = new HashSet<>(); + fixedOrders.sort(Integer::compareTo); + for (Integer fixedOrder : fixedOrders) { + int lastOrder = fixedOrder - 1; + List actionKeys = primaryActionChain.get(fixedOrder); + for (String actionKey : actionKeys) { + // 根据 actionKey 加载行动信息,并检查是否存在必需前置依赖 + MetaActionInfo metaActionInfo = actionCapability.loadMetaActionInfo(actionKey); + List preActions = metaActionInfo.getPreActions(); + boolean preActionsExist = preActions != null && !preActions.isEmpty(); + if (!preActionsExist) { + continue; + } + if (!metaActionInfo.isStrictDependencies()) { + continue; + } + if (checkDependenciesExist(lastOrder, preActions, primaryActionChain)) { + continue; + } + + // 如果存在前置依赖,则将其放置在当前order之前的位置, + // 放置位置优先选择已存在的上一节点,如果不存在(行动链的头节点时)则需要向行动链新增order + // 不需要检查行动链的当前节点的已存在 Action 是否为新 Action 的依赖项,因为这些 Action 实际来自 LLM + // 的评估结果,并非作为依赖项存在 + fixed.set(true); + List actionsInChain = primaryActionChain.computeIfAbsent(lastOrder, + list -> new ArrayList<>()); + preActions = new ArrayList<>(preActions); + preActions.removeAll(actionsInChain); + actionsInChain.addAll(preActions); + tempOrders.add(lastOrder); + } + } + fixedOrders.clear(); + fixedOrders.addAll(tempOrders); + } while (fixed.getAndSet(false)); + } + + private void fixOrder(Map> primaryActionChain) { + Map> tempChain = new HashMap<>(primaryActionChain); + primaryActionChain.clear(); + int chainSize = tempChain.size(); + for (int i = 0; i < chainSize; i++) { + primaryActionChain.put(i, tempChain.get(i)); + } + } + + private boolean checkDependenciesExist(int lastOrder, List preActions, + Map> primaryActionChain) { + if (!primaryActionChain.containsKey(lastOrder)) { + return false; + } + List existActions = primaryActionChain.get(lastOrder); + //noinspection SlowListContainsAll + return existActions.containsAll(preActions); + } + private ConfirmerInput buildConfirmerInput(PartnerRunningFlowContext context) { ConfirmerInput confirmerInput = new ConfirmerInput(); confirmerInput.setInput(context.getInput()); - List pendingActions = actionCapability.listPendingAction(context.getUserId()); - confirmerInput.setActionInfos(pendingActions); + List pendingActions = actionCapability.listPendingAction(context.getUserId()); + confirmerInput.setActionData(pendingActions); return confirmerInput; } } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/ActionConfirmer.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/ActionConfirmer.java index 4dbb5a2b..693cef18 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/ActionConfirmer.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/ActionConfirmer.java @@ -1,16 +1,81 @@ package work.slhaf.partner.module.modules.action.planner.confirmer; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; +import work.slhaf.partner.api.chat.pojo.ChatResponse; +import work.slhaf.partner.api.chat.pojo.Message; +import work.slhaf.partner.core.action.ActionCapability; +import work.slhaf.partner.core.action.ActionCore; +import work.slhaf.partner.core.action.entity.ActionData; import work.slhaf.partner.module.modules.action.planner.confirmer.entity.ConfirmerInput; import work.slhaf.partner.module.modules.action.planner.confirmer.entity.ConfirmerResult; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; + +import static work.slhaf.partner.common.util.ExtractUtil.extractJson; + +@Slf4j @AgentSubModule public class ActionConfirmer extends AgentRunningSubModule implements ActivateModel { + + @InjectCapability + private ActionCapability actionCapability; + @Override public ConfirmerResult execute(ConfirmerInput data) { - return null; + List actionDataList = data.getActionData(); + ExecutorService executor = actionCapability.getExecutor(ActionCore.ExecutorType.VIRTUAL); + CountDownLatch latch = new CountDownLatch(actionDataList.size()); + + ConfirmerResult result = new ConfirmerResult(); + List uuids = result.getUuids(); + + for (ActionData actionData : actionDataList) { + executor.execute(() -> { + try { + String prompt = buildPrompt(actionData, data.getInput(), data.getRecentMessages()); + ChatResponse response = this.singleChat(prompt); + JSONObject tempResult = JSONObject.parseObject(extractJson(response.getMessage())); + if (tempResult.getBoolean("confirmed")) { + actionData.setStatus(ActionData.ActionStatus.PREPARE); + synchronized (uuids) { + uuids.add(actionData.getUuid()); + } + } + } finally { + latch.countDown(); + } + }); + } + try { + latch.await(); + } catch (InterruptedException e) { + log.warn("CountDownLatch阻塞已中断"); + } + return result; + } + + private String buildPrompt(ActionData data, String input, List recentMessages) { + JSONObject prompt = new JSONObject(); + prompt.put("[用户输入]", input); + + JSONObject actionData = prompt.putObject("[行动数据]"); + actionData.put("[行动倾向]", data.getTendency()); + actionData.put("[行动原因]", data.getReason()); + actionData.put("[行动来源]", data.getSource()); + actionData.put("[行动描述]", data.getDescription()); + + JSONArray messageData = prompt.putArray("[近期对话]"); + messageData.addAll(recentMessages); + + return prompt.toString(); } @Override diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerInput.java index 88fc4a9a..40b0b5ac 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerInput.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerInput.java @@ -2,13 +2,13 @@ package work.slhaf.partner.module.modules.action.planner.confirmer.entity; import lombok.Data; import work.slhaf.partner.api.chat.pojo.Message; -import work.slhaf.partner.core.action.entity.MetaActionInfo; +import work.slhaf.partner.core.action.entity.ActionData; import java.util.List; @Data public class ConfirmerInput { private String input; - private List actionInfos; + private List actionData; private List recentMessages; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerResult.java index d1d73f0b..cf61639d 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerResult.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerResult.java @@ -2,9 +2,10 @@ package work.slhaf.partner.module.modules.action.planner.confirmer.entity; import lombok.Data; +import java.util.ArrayList; import java.util.List; @Data public class ConfirmerResult { - private List uuids; + private List uuids = new ArrayList<>(); } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/ActionEvaluator.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/ActionEvaluator.java index 5fd56b9b..8163b97c 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/ActionEvaluator.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/ActionEvaluator.java @@ -1,24 +1,33 @@ package work.slhaf.partner.module.modules.action.planner.evaluator; import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; +import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; import work.slhaf.partner.api.agent.factory.module.annotation.Init; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; import work.slhaf.partner.api.chat.pojo.ChatResponse; import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor; +import work.slhaf.partner.core.action.ActionCapability; +import work.slhaf.partner.core.memory.pojo.EvaluatedSlice; import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorBatchInput; import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorInput; import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorResult; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.Callable; @AgentSubModule public class ActionEvaluator extends AgentRunningSubModule> implements ActivateModel { + @InjectCapability + private ActionCapability actionCapability; + private InteractionThreadPoolExecutor executor; @Init @@ -30,7 +39,7 @@ public class ActionEvaluator extends AgentRunningSubModule execute(EvaluatorInput data) { @@ -39,12 +48,11 @@ public class ActionEvaluator extends AgentRunningSubModule> getTasks(List batchInputs) { List> list = new ArrayList<>(); for (EvaluatorBatchInput batchInput : batchInputs) { list.add(() -> { - ChatResponse response = this.singleChat(JSONObject.toJSONString(batchInput)); + ChatResponse response = this.singleChat(buildPrompt(batchInput)); EvaluatorResult evaluatorResult = JSONObject.parseObject(response.getMessage(), EvaluatorResult.class); evaluatorResult.setTendency(batchInput.getTendency()); return evaluatorResult; @@ -59,11 +67,32 @@ public class ActionEvaluator extends AgentRunningSubModule availableActions = new HashMap<>(); + actionCapability.listAvailableMetaActions().forEach((key, info) -> availableActions.put(key, info.getDescription())); + temp.setAvailableActions(availableActions); list.add(temp); } return list; } + private String buildPrompt(EvaluatorBatchInput batchInput) { + JSONObject prompt = new JSONObject(); + prompt.put("[行动倾向]", batchInput.getTendency()); + + JSONArray memoryData = prompt.putArray("[相关记忆切片]"); + for (EvaluatedSlice evaluatedSlice : batchInput.getActivatedSlices()) { + JSONObject memory = memoryData.addObject(); + memory.put("[日期]", evaluatedSlice.getDate()); + memory.put("[摘要]", evaluatedSlice.getSummary()); + + } + + JSONObject availableActionData = prompt.putObject("[可用行动单元]"); + availableActionData.putAll(batchInput.getAvailableActions()); + + return prompt.toString(); + } + @Override public String modelKey() { return "action_evaluator"; diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorBatchInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorBatchInput.java index 33114b9a..78ee229e 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorBatchInput.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorBatchInput.java @@ -5,10 +5,12 @@ import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice; import java.util.List; +import java.util.Map; @Data public class EvaluatorBatchInput { private List recentMessages; private List activatedSlices; + private Map availableActions; private String tendency; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorResult.java index 797edc1b..f6cf7c01 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorResult.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorResult.java @@ -1,8 +1,10 @@ package work.slhaf.partner.module.modules.action.planner.evaluator.entity; import lombok.Data; -import work.slhaf.partner.core.action.entity.ActionData; -import work.slhaf.partner.core.action.entity.ActionType; +import work.slhaf.partner.core.action.entity.ScheduledActionData; + +import java.util.List; +import java.util.Map; @Data public class EvaluatorResult { @@ -10,6 +12,13 @@ public class EvaluatorResult { private boolean needConfirm; private ActionType type; private String scheduleContent; - private ActionData actionData; + private ScheduledActionData.ScheduleType scheduleType; + private Map> primaryActionChain; private String tendency; + private String reason; + private String description; + + public enum ActionType { + IMMEDIATE, PLANNING + } } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/scheduler/ActionDispatcher.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/scheduler/ActionDispatcher.java deleted file mode 100644 index 7b2c8805..00000000 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/scheduler/ActionDispatcher.java +++ /dev/null @@ -1,4 +0,0 @@ -package work.slhaf.partner.module.modules.action.scheduler; - -public class ActionDispatcher { -} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/scheduler/TaskScheduler.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/scheduler/TaskScheduler.java deleted file mode 100644 index 72e88c4c..00000000 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/scheduler/TaskScheduler.java +++ /dev/null @@ -1,7 +0,0 @@ -package work.slhaf.partner.module.modules.action.scheduler; - -/** - * 负责综合前置模块 - */ -public class TaskScheduler { -} diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/memory/selector/MemorySelector.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/memory/selector/MemorySelector.java index d35bec48..954125ff 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/memory/selector/MemorySelector.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/memory/selector/MemorySelector.java @@ -23,10 +23,7 @@ import work.slhaf.partner.module.modules.memory.selector.extractor.entity.Extrac import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; +import java.util.*; @EqualsAndHashCode(callSuper = true) @Data @@ -133,7 +130,7 @@ public class MemorySelector extends PreRunningModule { } @Override - protected HashMap getPromptDataMap(PartnerRunningFlowContext context) { + protected Map getPromptDataMap(PartnerRunningFlowContext context) { HashMap map = new HashMap<>(); String userId = context.getUserId(); String dialogMapStr = memoryCapability.getDialogMapStr(); @@ -148,7 +145,7 @@ public class MemorySelector extends PreRunningModule { String sliceStr = memoryCapability.getActivatedSlicesStr(userId); if (sliceStr != null && !sliceStr.isEmpty()) { - map.put("[记忆切片] <你与最新一条消息的发送者的相关回忆, 不会与[记忆缓存]重复, 如果有重复你也可以指出来()>", sliceStr); + map.put("[记忆切片] <你与最新一条消息的发送者的相关回忆, 不会与[记忆缓存]重复, 如果有重复你也可以指出来>", sliceStr); } return map; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/memory/updater/MemoryUpdater.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/memory/updater/MemoryUpdater.java index 4b5d1eef..616c1bf8 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/memory/updater/MemoryUpdater.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/memory/updater/MemoryUpdater.java @@ -119,6 +119,11 @@ public class MemoryUpdater extends PostRunningModule { }); } + @Override + protected boolean relyOnMessage() { + return true; + } + private void updateMemory() { log.debug("[MemoryUpdater] 记忆更新流程开始..."); tempMessage = new ArrayList<>(cognationCapability.getChatMessages()); diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/perceive/selector/PerceiveSelector.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/perceive/selector/PerceiveSelector.java index e387e098..d3f12d8e 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/perceive/selector/PerceiveSelector.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/perceive/selector/PerceiveSelector.java @@ -10,6 +10,7 @@ import work.slhaf.partner.module.common.module.PreRunningModule; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import java.util.HashMap; +import java.util.Map; @Slf4j @Setter @@ -24,7 +25,7 @@ public class PerceiveSelector extends PreRunningModule { } @Override - protected HashMap getPromptDataMap(PartnerRunningFlowContext context) { + protected Map getPromptDataMap(PartnerRunningFlowContext context) { HashMap map = new HashMap<>(); User user = perceiveCapability.getUser(context.getUserId()); map.put("[关系] <你与最新聊天用户的关系>", user.getRelation()); diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/perceive/updater/PerceiveUpdater.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/perceive/updater/PerceiveUpdater.java index 206d6798..649c71d9 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/perceive/updater/PerceiveUpdater.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/perceive/updater/PerceiveUpdater.java @@ -70,6 +70,11 @@ public class PerceiveUpdater extends PostRunningModule { }); } + @Override + protected boolean relyOnMessage() { + return true; + } + private void runRelationExtractorAction(PartnerRunningFlowContext context, ReentrantLock userLock, User user) { RelationExtractResult relationExtractResult = relationExtractor.execute(context); userLock.lock(); diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/process/PreprocessExecutor.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/process/PreprocessExecutor.java index de7ff1b6..ab4de789 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/process/PreprocessExecutor.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/process/PreprocessExecutor.java @@ -15,6 +15,7 @@ import work.slhaf.partner.runtime.interaction.data.context.subcontext.CoreContex import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; +import java.util.Map; @EqualsAndHashCode(callSuper = true) @Data @@ -58,7 +59,7 @@ public class PreprocessExecutor extends PreRunningModule { @Override - protected HashMap getPromptDataMap(PartnerRunningFlowContext context) { + protected Map getPromptDataMap(PartnerRunningFlowContext context) { HashMap map = new HashMap<>(); map.put("text", "这部分才是真正的用户输入内容, 就像你之前收到过的输入一样。但...不会是'同一个人'。"); map.put("datetime", "本次用户输入对应的当前时间"); diff --git a/Partner-Main/src/main/java/work/slhaf/partner/runtime/interaction/data/PartnerInputData.java b/Partner-Main/src/main/java/work/slhaf/partner/runtime/interaction/data/PartnerInputData.java index 8e3e2d43..07a26c29 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/runtime/interaction/data/PartnerInputData.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/runtime/interaction/data/PartnerInputData.java @@ -7,7 +7,7 @@ import work.slhaf.partner.api.agent.runtime.interaction.data.AgentInputData; @EqualsAndHashCode(callSuper = true) @Data public class PartnerInputData extends AgentInputData { - private String userNickName; - private String platform; - private boolean single; + protected String userNickName; + protected String platform; + protected boolean single; } diff --git a/Partner-Main/src/test/java/experimental/InProcessMcpTransportTest.java b/Partner-Main/src/test/java/experimental/InProcessMcpTransportTest.java new file mode 100644 index 00000000..c3115f8b --- /dev/null +++ b/Partner-Main/src/test/java/experimental/InProcessMcpTransportTest.java @@ -0,0 +1,41 @@ +package experimental; + +import io.modelcontextprotocol.client.McpClient; +import io.modelcontextprotocol.client.McpSyncClient; +import io.modelcontextprotocol.server.McpServer; +import io.modelcontextprotocol.server.McpStatelessServerFeatures; +import io.modelcontextprotocol.server.McpStatelessSyncServer; +import io.modelcontextprotocol.spec.McpSchema; +import org.junit.jupiter.api.Test; +import work.slhaf.partner.common.mcp.InProcessMcpTransport; + +import java.util.List; + +public class InProcessMcpTransportTest { + @Test + void inProcessMcpTransportTest() { + InProcessMcpTransport.Pair pair = InProcessMcpTransport.pair(); + InProcessMcpTransport clientSide = pair.clientSide(); + InProcessMcpTransport serverSide = pair.serverSide(); + McpStatelessSyncServer server = McpServer.sync(serverSide) + .capabilities(McpSchema.ServerCapabilities.builder().tools(true).build()) + .build(); + server.addTool(McpStatelessServerFeatures.SyncToolSpecification.builder() + .tool(McpSchema.Tool.builder().name("111").build()).callHandler((mcpTransportContext, callToolRequest) -> { + System.out.println(111); + return McpSchema.CallToolResult.builder().addContent(new McpSchema.TextContent("111")).build(); + }).build()); + McpSyncClient client = McpClient.sync(clientSide) + .build(); + + List tools = client.listTools().tools(); + McpSchema.Tool tool = tools.getFirst(); + System.out.println(tool.toString()); + + McpSchema.CallToolResult callToolResult = client.callTool(McpSchema.CallToolRequest.builder().name(tool.name()).build()); + System.out.println(callToolResult.content().toString()); + + client.close(); + server.close(); + } +} diff --git a/Partner-Main/src/test/java/experimental/NetTest.java b/Partner-Main/src/test/java/experimental/NetTest.java new file mode 100644 index 00000000..ad606c1d --- /dev/null +++ b/Partner-Main/src/test/java/experimental/NetTest.java @@ -0,0 +1,17 @@ +package experimental; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import org.junit.jupiter.api.Test; + +public class NetTest { + @Test + void httpTest() { + HttpRequest request = HttpRequest.get("slhaf.work"); + request.setConnectionTimeout(2); + request.setReadTimeout(2); + HttpResponse execute = request.execute(); + System.out.println(execute.toString()); + execute.close(); + } +} diff --git a/Partner-Main/src/test/java/OnnxTest.java b/Partner-Main/src/test/java/experimental/OnnxTest.java similarity index 99% rename from Partner-Main/src/test/java/OnnxTest.java rename to Partner-Main/src/test/java/experimental/OnnxTest.java index b8a545d8..fefee815 100644 --- a/Partner-Main/src/test/java/OnnxTest.java +++ b/Partner-Main/src/test/java/experimental/OnnxTest.java @@ -1,3 +1,5 @@ +package experimental; + import ai.djl.huggingface.tokenizers.Encoding; import ai.djl.huggingface.tokenizers.HuggingFaceTokenizer; import ai.onnxruntime.OnnxTensor; diff --git a/Partner-Main/src/test/java/ReflectionTest.java b/Partner-Main/src/test/java/experimental/ReflectionTest.java similarity index 96% rename from Partner-Main/src/test/java/ReflectionTest.java rename to Partner-Main/src/test/java/experimental/ReflectionTest.java index d316e96d..da543cf8 100644 --- a/Partner-Main/src/test/java/ReflectionTest.java +++ b/Partner-Main/src/test/java/experimental/ReflectionTest.java @@ -1,3 +1,5 @@ +package experimental; + import org.junit.jupiter.api.Test; import work.slhaf.partner.core.memory.MemoryCapability; import work.slhaf.partner.core.memory.pojo.MemoryResult; diff --git a/Partner-Main/src/test/java/RegexTest.kt b/Partner-Main/src/test/java/experimental/RegexTest.kt similarity index 98% rename from Partner-Main/src/test/java/RegexTest.kt rename to Partner-Main/src/test/java/experimental/RegexTest.kt index bc97f9c2..73cf7a77 100644 --- a/Partner-Main/src/test/java/RegexTest.kt +++ b/Partner-Main/src/test/java/experimental/RegexTest.kt @@ -1,3 +1,5 @@ +package experimental + import org.junit.jupiter.api.Test import java.lang.String.join import java.util.regex.Pattern diff --git a/Partner-Main/src/test/java/SelfAwarenessTest.java b/Partner-Main/src/test/java/experimental/SelfAwarenessTest.java similarity index 99% rename from Partner-Main/src/test/java/SelfAwarenessTest.java rename to Partner-Main/src/test/java/experimental/SelfAwarenessTest.java index be2cc518..e6a3fbc1 100644 --- a/Partner-Main/src/test/java/SelfAwarenessTest.java +++ b/Partner-Main/src/test/java/experimental/SelfAwarenessTest.java @@ -1,3 +1,5 @@ +package experimental; + import cn.hutool.json.JSONUtil; import org.junit.jupiter.api.Test; import work.slhaf.partner.api.chat.ChatClient; diff --git a/Partner-Main/src/test/java/experimental/SystemTest.java b/Partner-Main/src/test/java/experimental/SystemTest.java new file mode 100644 index 00000000..8306b481 --- /dev/null +++ b/Partner-Main/src/test/java/experimental/SystemTest.java @@ -0,0 +1,48 @@ +package experimental; + +import com.alibaba.fastjson2.JSONObject; +import org.junit.jupiter.api.Test; +import work.slhaf.partner.core.action.entity.MetaActionInfo; +import work.slhaf.partner.core.action.runner.LocalRunnerClient; +import work.slhaf.partner.core.action.runner.RunnerClient; + +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class SystemTest { + @Test + void execTest() { + // exec("pwd"); + // exec("ls", "-la"); + String r = exec("pip", "st", "--format=freeze"); + System.out.println(r); + } + + private String exec(String... command) { + StringBuilder s = new StringBuilder(); + ProcessBuilder processBuilder = new ProcessBuilder(command); + try { + Process process = processBuilder.start(); + java.io.InputStream inputStream = process.getInputStream(); + java.util.Scanner scanner = new java.util.Scanner(inputStream).useDelimiter("\\A"); + if (scanner.hasNext()) { + s.append(scanner.next()); + } + } catch (IOException e) { + e.printStackTrace(); + } + return s.toString(); + } + + @Test + void localRunnerClientTest() { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + RunnerClient client = new LocalRunnerClient(existedMetaActions, executor, null); + JSONObject res = client.listSysDependencies(); + System.out.println(res.toString()); + } + +} diff --git a/Partner-Main/src/test/java/ThreadPoolTest.java b/Partner-Main/src/test/java/experimental/ThreadPoolTest.java similarity index 97% rename from Partner-Main/src/test/java/ThreadPoolTest.java rename to Partner-Main/src/test/java/experimental/ThreadPoolTest.java index 7488e2f8..d022253d 100644 --- a/Partner-Main/src/test/java/ThreadPoolTest.java +++ b/Partner-Main/src/test/java/experimental/ThreadPoolTest.java @@ -1,3 +1,5 @@ +package experimental; + import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; diff --git a/Partner-Main/src/test/java/timewheel/TimeWheelTest.kt b/Partner-Main/src/test/java/experimental/timewheel/TimeWheelTest.kt similarity index 100% rename from Partner-Main/src/test/java/timewheel/TimeWheelTest.kt rename to Partner-Main/src/test/java/experimental/timewheel/TimeWheelTest.kt diff --git a/Partner-Main/src/test/java/resources/action/tmp/hello_world.py b/Partner-Main/src/test/java/resources/action/tmp/hello_world.py new file mode 100644 index 00000000..d477459e --- /dev/null +++ b/Partner-Main/src/test/java/resources/action/tmp/hello_world.py @@ -0,0 +1,24 @@ +import sys + + +def parse_args(argv): + """ + 将 --key=value 解析成 dict + """ + params = {} + for arg in argv: + if arg.startswith("--") and "=" in arg: + key, value = arg[2:].split("=", 1) + params[key] = value + return params + + +def main(): + params = parse_args(sys.argv[1:]) + + name = params.get("name", "World") + print(f"Hello {name}!") + + +if __name__ == "__main__": + main() diff --git a/Partner-Main/src/test/java/text/relation_input_test.json b/Partner-Main/src/test/java/resources/text/relation_input_test.json similarity index 100% rename from Partner-Main/src/test/java/text/relation_input_test.json rename to Partner-Main/src/test/java/resources/text/relation_input_test.json diff --git a/Partner-Main/src/test/java/text/relation_output_test.json b/Partner-Main/src/test/java/resources/text/relation_output_test.json similarity index 100% rename from Partner-Main/src/test/java/text/relation_output_test.json rename to Partner-Main/src/test/java/resources/text/relation_output_test.json diff --git a/Partner-Main/src/test/java/resources/text/test.json b/Partner-Main/src/test/java/resources/text/test.json new file mode 100644 index 00000000..8fc15c26 --- /dev/null +++ b/Partner-Main/src/test/java/resources/text/test.json @@ -0,0 +1,18 @@ +{ + "keys": [ + { + "d": "H2hNCPdoa3B37PMZBbqlbJ3WZLKRWg3-rHjs5IPVsgERex5X0Etx5VM--lHRrKVjdgjuEbd9AlwUlUmv-UeDsrumaXcZUJN58LbQ7GiMC16pKi7jEIDttZwxJtWMwcwZ6BwO1HCBqruT4aGDL_WP1EX_x4ajsj1B2xs3UryfooR_gMDbDtOj9sxgY5dlCOTuEYxWkVtFZ7u_sGfaLkwMVzVk2bT6O2Hff3D9XXq7ZJvD_ess5z2dbvKb824MENN6ISZ7xNemXQPpM5pjGS8HQR5su5cExImyUhz452Y-Clc6UC_A5buxNwPJzv-3Ooasp3w8YkrXEubUj7lLgYsfSQ", + "dp": "Me4adZbjtq_EhLbiso_OLk-bmlHkoTMs5Nk4oZMDAYZSfh3TtxwbKUM3ycvHJInqNSba33antxQeyY6TXEsghfjZwMWhCz6RzEYWCFFjIv08zm2HGgaEjF2JuDr5i75ym6NC9y5wnvUBHnwm76bbSginrXcpS-2qAuniY7HLzlk", + "dq": "CwcPCdlYRgLmPIezcLLdkDRg2Nh4tBpGn3-nSdUAfwmfKwdPHj6FYnMuP__eFDoCkxZkD8VPYMDuYsALAcGSn8C7I2Vfv_LOvoLds6mcG9cxNHrBGPzpnGsyhNNTOqzmhb51MROs3OCg8H7HEqkBV5HAEzBfi3t9L7d5LI5WivE", + "e": "AQAB", + "kty": "RSA", + "n": "6HaqwtmLP-CkJQlo9aAh-qFFRhh9YTnjXKLtyKejEpkSyJ0_5jBuz_73ynpxB6YlIpNPFAI34dj3pAKjd3ajnoxXopm_MvriETlzqxl4UHQCgsUSAkipYZbP0bQYNZHO8VOCmEJxSJcccNq2gVgpG57MxNgQkB_OSDlQ0lxxIt1R_hpMcLzihPAIBI7lo17Y6oumql8ZHuKRFYgvOV7jx_S6oqpUSLvtyF8hzyLP32LllzzapYlD4UY_ywcHWT2YRS-HfL71F9q-knOiH7cFZf13ydqG3YDuAUnEk6odO2KF_7d3-0LJyFyp6xggWXBeRbVyAOtOt1j_1CHGncAluw", + "p": "_sUrhjSlJNKzJ19rlEKqaqEVpOcvLf970Jrv3xDp2M0inBwZnFbJfqb3kbr53g7N1XKREVS7eGIFNzKQhUWJjJWPdZVc5ewCcs2UVpIgdLnqtN1t7uQlsCf7-B74FONYdSeYkH3NuISqXTmXKA7jPJcxyo97ZcoQb2AEGPU6H4M", + "q": "6ZXuiLgw7eThq28JInIJ2hmSOLQsEMtv2M3CO5juoLE_bumBs1ooIHstG8-FOG_EL70TNZBlHVDZapsJQBbeL5r26LWgysLUQan3mqsWyn3aPje7eCP1hPLWzAafsJRe38_sGox9JlmCqG_UboxUHLf8b-cSr_4Rzmj9MHIbk2k", + "qi": "peNVzNTHxHmWpm-jDh5KnatlJ-4Ian4PKnaUKz6FjB6URXH8rauACX0gJ7-qZe23rq5639WNKeaVVMlADezyVfw4hq0crfURAQnjysyzldQ8kTCcThtw4oN1qyFex6fWNu-6A3VlGMCLgLvD7Pkk3qgnbj8cEtm5teq6srFvdsU", + "use": "sig", + "kid": "b16b20729c3ced11", + "alg": "RS256" + } + ] +} \ No newline at end of file diff --git a/Partner-Main/src/test/java/work/slhaf/partner/core/action/runner/LocalRunnerClientTest.java b/Partner-Main/src/test/java/work/slhaf/partner/core/action/runner/LocalRunnerClientTest.java new file mode 100644 index 00000000..7a31496c --- /dev/null +++ b/Partner-Main/src/test/java/work/slhaf/partner/core/action/runner/LocalRunnerClientTest.java @@ -0,0 +1,874 @@ +package work.slhaf.partner.core.action.runner; + +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import work.slhaf.partner.core.action.entity.MetaAction; +import work.slhaf.partner.core.action.entity.MetaActionInfo; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.BooleanSupplier; +import java.util.function.Predicate; + +import static work.slhaf.partner.core.action.runner.LocalRunnerClientTest.Await.waitForCondition; +import static work.slhaf.partner.core.action.runner.LocalRunnerClientTest.Common.*; +import static work.slhaf.partner.core.action.runner.LocalRunnerClientTest.Fs.*; + +@Slf4j +public class LocalRunnerClientTest { + + @SuppressWarnings("LoggingSimilarMessage") + static class Fs { + static void writeRunFile(Path actionDir) throws IOException { + Path runPath = actionDir.resolve("run.py"); + log.debug("写入路径: {}", runPath); + Files.writeString(runPath, "print('ok')\n"); + } + + static void writeInvalidDescJson(Path actionDir) throws IOException { + Path descPath = actionDir.resolve("desc.json"); + log.debug("写入路径: {}", descPath); + Files.writeString(descPath, "{ invalid json"); + } + + static void writeDescJson(Path actionDir, String description) throws IOException { + Path descPath = actionDir.resolve("desc.json"); + log.debug("写入路径: {}", descPath); + String json = "{\n" + + " \"io\": false,\n" + + " \"params\": {},\n" + + " \"description\": \"" + description + "\",\n" + + " \"tags\": [],\n" + + " \"preActions\": [],\n" + + " \"postActions\": [],\n" + + " \"strictDependencies\": false,\n" + + " \"responseSchema\": {}\n" + + "}\n"; + Files.writeString(descPath, json); + } + + static void writeDescMcpJson(Path descDir, String actionKey, String description) throws IOException { + Path descPath = descDir.resolve(actionKey + ".desc.json"); + log.debug("写入路径: {}", descPath); + String json = "{\n" + + " \"io\": true,\n" + + " \"params\": {},\n" + + " \"description\": \"" + description + "\",\n" + + " \"tags\": [\"tag\"],\n" + + " \"preActions\": [\"pre\"],\n" + + " \"postActions\": [\"post\"],\n" + + " \"strictDependencies\": true,\n" + + " \"responseSchema\": {}\n" + + "}\n"; + Files.writeString(descPath, json); + } + + static void writeInvalidDescMcpJson(Path descDir, String actionKey) throws IOException { + Path descPath = descDir.resolve(actionKey + ".desc.json"); + log.debug("写入路径: {}", descPath); + Files.writeString(descPath, "{ invalid json"); + } + + @SuppressWarnings("SameParameterValue") + static void writeDescJsonAtomic(Path actionDir, String description) throws IOException { + Path descPath = actionDir.resolve("desc.json"); + Path tmpPath = actionDir.resolve("desc.json.tmp"); + String json = "{\n" + + " \"io\": false,\n" + + " \"params\": {},\n" + + " \"description\": \"" + description + "\",\n" + + " \"tags\": [],\n" + + " \"preActions\": [],\n" + + " \"postActions\": [],\n" + + " \"strictDependencies\": false,\n" + + " \"responseSchema\": {}\n" + + "}\n"; + Files.writeString(tmpPath, json); + Files.move(tmpPath, descPath, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING); + } + + static void deleteDirectory(Path dir) throws IOException { + if (!Files.exists(dir)) { + return; + } + try (var stream = Files.walk(dir)) { + stream.sorted(Comparator.reverseOrder()).forEach(path -> { + try { + Files.deleteIfExists(path); + } catch (IOException ignored) { + } + }); + } + } + + static void writeCommonMcpConfig(Path filePath, String content) throws IOException { + Files.writeString(filePath, content); + } + + } + + @SuppressWarnings("BusyWait") + static class Await { + static void waitForCondition(BooleanSupplier supplier, long timeoutMs) throws InterruptedException { + long start = System.currentTimeMillis(); + while (!supplier.getAsBoolean()) { + if (System.currentTimeMillis() - start > timeoutMs) { + break; + } + Thread.sleep(50); + } + } + } + + static class Common { + static MetaActionInfo getMetaActionInfo(ConcurrentHashMap existedMetaActions, + String actionKey) { + return existedMetaActions.get(actionKey); + } + + static boolean hasActionKey(ConcurrentHashMap existedMetaActions, + Predicate predicate) { + return existedMetaActions.keySet().stream().anyMatch(predicate); + } + + static MetaActionInfo buildMetaActionInfo(String description) { + MetaActionInfo info = new MetaActionInfo(); + info.setIo(true); + info.setParams(new HashMap<>()); + info.setDescription(description); + info.setTags(new ArrayList<>(List.of("tag"))); + info.setPreActions(new ArrayList<>(List.of("pre"))); + info.setPostActions(new ArrayList<>(List.of("post"))); + info.setStrictDependencies(true); + return info; + } + + static String buildCommonMcpConfig(String... serverEntries) { + StringBuilder builder = new StringBuilder(); + builder.append("{\n"); + for (int i = 0; i < serverEntries.length; i++) { + builder.append(serverEntries[i]); + if (i < serverEntries.length - 1) { + builder.append(",\n"); + } + } + builder.append("\n}\n"); + return builder.toString(); + } + + static String buildStdioServerEntry(String id, String packageName) { + return " \"" + id + "\": {\n" + + " \"command\": \"npx\",\n" + + " \"args\": [\n" + + " \"-y\",\n" + + " \"" + packageName + "\"\n" + + " ],\n" + + " \"env\": {}\n" + + " }"; + } + + static MetaAction buildMetaAction(MetaAction.Type type, String location, String name, Map params) { + MetaAction metaAction = new MetaAction( + name, + false, + type, + location + ); + metaAction.getParams().putAll(params); + return metaAction; + } + } + + @Nested + class DynamicMcpTest { + + @Test + void testDynamicWatchCreateModifyDelete(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path dynamicRoot = tempDir.resolve("action").resolve("dynamic"); + Path actionDir = dynamicRoot.resolve("demo_action"); + Files.createDirectories(actionDir); + + Fs.writeRunFile(actionDir); + writeDescJson(actionDir, "demo action"); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action"), 2000); + Assertions.assertTrue(existedMetaActions.containsKey("local::demo_action")); + + // 触发一次 modify,确保监听线程能够捕捉到完整的 action 结构 + writeDescJson(actionDir, "demo action updated"); + + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action"), 2000); + Assertions.assertTrue(existedMetaActions.containsKey("local::demo_action")); + + Files.deleteIfExists(actionDir.resolve("run.py")); + waitForCondition(() -> !existedMetaActions.containsKey("local::demo_action"), 2000); + Assertions.assertFalse(existedMetaActions.containsKey("local::demo_action")); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDynamicWatchOutOfOrderEvents(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path dynamicRoot = tempDir.resolve("action").resolve("dynamic"); + + Path actionDir = dynamicRoot.resolve("demo_action_order"); + Files.createDirectories(actionDir); + writeDescJson(actionDir, "desc first"); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action_order"), 500); + Assertions.assertFalse(existedMetaActions.containsKey("local::demo_action_order")); + + writeRunFile(actionDir); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action_order"), 2000); + Assertions.assertTrue(existedMetaActions.containsKey("local::demo_action_order")); + + Path descOnlyDir = dynamicRoot.resolve("demo_action_desc_only"); + Files.createDirectories(descOnlyDir); + writeDescJson(descOnlyDir, "desc only"); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action_desc_only"), 500); + Assertions.assertFalse(existedMetaActions.containsKey("local::demo_action_desc_only")); + + Path runOnlyDir = dynamicRoot.resolve("demo_action_run_only"); + Files.createDirectories(runOnlyDir); + writeRunFile(runOnlyDir); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action_run_only"), 500); + Assertions.assertFalse(existedMetaActions.containsKey("local::demo_action_run_only")); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDynamicWatchAtomicDescOverwrite(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path dynamicRoot = tempDir.resolve("action").resolve("dynamic"); + Path actionDir = dynamicRoot.resolve("demo_action_atomic"); + Files.createDirectories(actionDir); + + writeRunFile(actionDir); + writeDescJson(actionDir, "before"); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action_atomic"), 2000); + Assertions.assertTrue(existedMetaActions.containsKey("local::demo_action_atomic")); + + writeDescJsonAtomic(actionDir, "after"); + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, "local::demo_action_atomic"); + return info != null && "after".equals(info.getDescription()); + }, 2000); + + MetaActionInfo info = getMetaActionInfo(existedMetaActions, "local::demo_action_atomic"); + Assertions.assertNotNull(info); + Assertions.assertEquals("after", info.getDescription()); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDynamicWatchRapidDescModify(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path dynamicRoot = tempDir.resolve("action").resolve("dynamic"); + Path actionDir = dynamicRoot.resolve("demo_action_rapid"); + Files.createDirectories(actionDir); + + writeRunFile(actionDir); + writeDescJson(actionDir, "v0"); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action_rapid"), 2000); + Assertions.assertTrue(existedMetaActions.containsKey("local::demo_action_rapid")); + + String last = "v5"; + for (int i = 1; i <= 5; i++) { + writeDescJson(actionDir, "v" + i); + } + + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, "local::demo_action_rapid"); + return info != null && last.equals(info.getDescription()); + }, 2000); + + MetaActionInfo info = getMetaActionInfo(existedMetaActions, "local::demo_action_rapid"); + Assertions.assertNotNull(info); + Assertions.assertEquals(last, info.getDescription()); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDynamicWatchDeleteBehavior(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path dynamicRoot = tempDir.resolve("action").resolve("dynamic"); + Path actionDir = dynamicRoot.resolve("demo_action_delete"); + Files.createDirectories(actionDir); + Thread.sleep(100); + writeRunFile(actionDir); + writeDescJson(actionDir, "delete test"); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action_delete"), 2000); + Assertions.assertTrue(existedMetaActions.containsKey("local::demo_action_delete")); + + Files.deleteIfExists(actionDir.resolve("run.py")); + waitForCondition(() -> !existedMetaActions.containsKey("local::demo_action_delete"), 2000); + Assertions.assertFalse(existedMetaActions.containsKey("local::demo_action_delete")); + + writeRunFile(actionDir); + writeDescJson(actionDir, "delete test restore"); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action_delete"), 2000); + Assertions.assertTrue(existedMetaActions.containsKey("local::demo_action_delete")); + + deleteDirectory(actionDir); + waitForCondition(() -> !existedMetaActions.containsKey("local::demo_action_delete"), 2000); + Assertions.assertFalse(existedMetaActions.containsKey("local::demo_action_delete")); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDynamicWatchInvalidDescRecovery(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + Thread.sleep(100); + try { + Path dynamicRoot = tempDir.resolve("action").resolve("dynamic"); + Path actionDir = dynamicRoot.resolve("demo_action_invalid"); + Files.createDirectories(actionDir); + + writeRunFile(actionDir); + writeInvalidDescJson(actionDir); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action_invalid"), 500); + Assertions.assertFalse(existedMetaActions.containsKey("local::demo_action_invalid")); + + writeDescJson(actionDir, "fixed"); + waitForCondition(() -> existedMetaActions.containsKey("local::demo_action_invalid"), 2000); + Assertions.assertTrue(existedMetaActions.containsKey("local::demo_action_invalid")); + } finally { + executor.shutdownNow(); + } + } + } + + @Nested + class DescMcpTest { + + @Test + void testDescMcpWatchCreateModifyDelete(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + String actionKey = "local::desc_action"; + existedMetaActions.put(actionKey, buildMetaActionInfo("base")); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path descDir = tempDir.resolve("action").resolve("mcp").resolve("desc"); + Files.createDirectories(descDir); + + writeDescMcpJson(descDir, actionKey, "v1"); + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + return info != null && "v1".equals(info.getDescription()); + }, 2000); + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + Assertions.assertNotNull(info); + Assertions.assertEquals("v1", info.getDescription()); + Assertions.assertTrue(info.isIo()); + Assertions.assertTrue(info.isStrictDependencies()); + Assertions.assertFalse(info.getTags().isEmpty()); + + writeDescMcpJson(descDir, actionKey, "v2"); + waitForCondition(() -> { + MetaActionInfo current = getMetaActionInfo(existedMetaActions, actionKey); + return current != null && "v2".equals(current.getDescription()); + }, 2000); + info = getMetaActionInfo(existedMetaActions, actionKey); + Assertions.assertNotNull(info); + Assertions.assertEquals("v2", info.getDescription()); + + Files.deleteIfExists(descDir.resolve(actionKey + ".desc.json")); + waitForCondition(() -> { + MetaActionInfo current = getMetaActionInfo(existedMetaActions, actionKey); + return current != null + && !current.isIo() + && !current.isStrictDependencies() + && current.getTags().isEmpty() + && current.getPreActions().isEmpty() + && current.getPostActions().isEmpty(); + }, 2000); + info = getMetaActionInfo(existedMetaActions, actionKey); + Assertions.assertNotNull(info); + Assertions.assertFalse(info.isIo()); + Assertions.assertFalse(info.isStrictDependencies()); + Assertions.assertTrue(info.getTags().isEmpty()); + Assertions.assertTrue(info.getPreActions().isEmpty()); + Assertions.assertTrue(info.getPostActions().isEmpty()); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDescMcpInvalidJsonRecovery(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + String actionKey = "local::desc_invalid"; + existedMetaActions.put(actionKey, buildMetaActionInfo("base")); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path descDir = tempDir.resolve("action").resolve("mcp").resolve("desc"); + Files.createDirectories(descDir); + + writeInvalidDescMcpJson(descDir, actionKey); + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + return info != null + && !info.isIo() + && !info.isStrictDependencies() + && info.getTags().isEmpty() + && info.getPreActions().isEmpty() + && info.getPostActions().isEmpty(); + }, 2000); + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + Assertions.assertNotNull(info); + Assertions.assertFalse(info.isIo()); + Assertions.assertFalse(info.isStrictDependencies()); + Assertions.assertTrue(info.getTags().isEmpty()); + Assertions.assertTrue(info.getPreActions().isEmpty()); + Assertions.assertTrue(info.getPostActions().isEmpty()); + + writeDescMcpJson(descDir, actionKey, "fixed"); + waitForCondition(() -> { + MetaActionInfo current = getMetaActionInfo(existedMetaActions, actionKey); + return current != null && "fixed".equals(current.getDescription()); + }, 2000); + info = getMetaActionInfo(existedMetaActions, actionKey); + Assertions.assertNotNull(info); + Assertions.assertEquals("fixed", info.getDescription()); + Assertions.assertTrue(info.isIo()); + Assertions.assertTrue(info.isStrictDependencies()); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDescMcpIgnoreInvalidFileName(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + String actionKey = "local::desc_ignore"; + existedMetaActions.put(actionKey, buildMetaActionInfo("base")); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path descDir = tempDir.resolve("action").resolve("mcp").resolve("desc"); + Files.createDirectories(descDir); + + Files.writeString(descDir.resolve("local-desc.desc.json"), "{ \"description\": \"bad\" }"); + Files.writeString(descDir.resolve(actionKey + ".json"), "{ \"description\": \"bad\" }"); + waitForCondition(() -> existedMetaActions.size() > 1, 500); + + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + Assertions.assertNotNull(info); + Assertions.assertEquals("base", info.getDescription()); + Assertions.assertTrue(info.isIo()); + Assertions.assertEquals(1, existedMetaActions.size()); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDescMcpNoActionKeyPresent(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path descDir = tempDir.resolve("action").resolve("mcp").resolve("desc"); + Files.createDirectories(descDir); + + String actionKey = "local::missing_action"; + writeDescMcpJson(descDir, actionKey, "desc"); + waitForCondition(() -> existedMetaActions.containsKey(actionKey), 500); + Assertions.assertFalse(existedMetaActions.containsKey(actionKey)); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDescMcpRapidCreateDelete(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + String actionKey = "local::desc_rapid"; + existedMetaActions.put(actionKey, buildMetaActionInfo("base")); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path descDir = tempDir.resolve("action").resolve("mcp").resolve("desc"); + Files.createDirectories(descDir); + + writeDescMcpJson(descDir, actionKey, "v1"); + Files.deleteIfExists(descDir.resolve(actionKey + ".desc.json")); + + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + return info != null + && !info.isIo() + && !info.isStrictDependencies() + && info.getTags().isEmpty() + && info.getPreActions().isEmpty() + && info.getPostActions().isEmpty(); + }, 2000); + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + Assertions.assertNotNull(info); + Assertions.assertFalse(info.isIo()); + Assertions.assertFalse(info.isStrictDependencies()); + Assertions.assertTrue(info.getTags().isEmpty()); + Assertions.assertTrue(info.getPreActions().isEmpty()); + Assertions.assertTrue(info.getPostActions().isEmpty()); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDescMcpRapidDeleteCreate(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + String actionKey = "local::desc_rapid_restore"; + existedMetaActions.put(actionKey, buildMetaActionInfo("base")); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path descDir = tempDir.resolve("action").resolve("mcp").resolve("desc"); + Files.createDirectories(descDir); + + writeDescMcpJson(descDir, actionKey, "v1"); + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + return info != null && "v1".equals(info.getDescription()); + }, 2000); + + Files.deleteIfExists(descDir.resolve(actionKey + ".desc.json")); + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + return info != null + && !info.isIo() + && !info.isStrictDependencies() + && info.getTags().isEmpty() + && info.getPreActions().isEmpty() + && info.getPostActions().isEmpty(); + }, 2000); + + writeDescMcpJson(descDir, actionKey, "v2"); + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + return info != null && "v2".equals(info.getDescription()); + }, 2000); + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + Assertions.assertNotNull(info); + Assertions.assertEquals("v2", info.getDescription()); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDescMcpDirDeleteRecreate(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + String actionKey = "local::desc_dir_restore"; + existedMetaActions.put(actionKey, buildMetaActionInfo("base")); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path descDir = tempDir.resolve("action").resolve("mcp").resolve("desc"); + Files.createDirectories(descDir); + + writeDescMcpJson(descDir, actionKey, "v1"); + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + return info != null && "v1".equals(info.getDescription()); + }, 2000); + + Files.deleteIfExists(descDir.resolve(actionKey + ".desc.json")); + deleteDirectory(descDir); + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + return info != null + && !info.isIo() + && !info.isStrictDependencies() + && info.getTags().isEmpty() + && info.getPreActions().isEmpty() + && info.getPostActions().isEmpty(); + }, 2000); + + Files.createDirectories(descDir); + writeDescMcpJson(descDir, actionKey, "v2"); + waitForCondition(() -> { + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + return info != null && "v2".equals(info.getDescription()); + }, 2000); + MetaActionInfo info = getMetaActionInfo(existedMetaActions, actionKey); + Assertions.assertNotNull(info); + Assertions.assertEquals("v2", info.getDescription()); + } finally { + executor.shutdownNow(); + } + } + } + + @Nested + class CommonMcpTest { + + @Test + void testCommonMcpInitialLoad(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + + Path mcpDir = tempDir.resolve("action").resolve("mcp"); + Files.createDirectories(mcpDir); + Path configFile = mcpDir.resolve("servers.json"); + String config = buildCommonMcpConfig( + buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest") + ); + writeCommonMcpConfig(configFile, config); + + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000); + Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::"))); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testCommonMcpCreateModifyDelete(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path mcpDir = tempDir.resolve("action").resolve("mcp"); + Files.createDirectories(mcpDir); + Path configFile = mcpDir.resolve("servers.json"); + + String config = buildCommonMcpConfig( + buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest") + ); + writeCommonMcpConfig(configFile, config); + waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000); + Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::"))); + + String updatedConfig = buildCommonMcpConfig( + buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest"), + buildStdioServerEntry("playwright", "@playwright/mcp@latest") + ); + writeCommonMcpConfig(configFile, updatedConfig); + waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000); + Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::"))); + + Files.deleteIfExists(configFile); + waitForCondition(() -> !hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000); + Assertions.assertFalse(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::"))); + Assertions.assertFalse(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::"))); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testCommonMcpRemoveEntryFromConfig(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path mcpDir = tempDir.resolve("action").resolve("mcp"); + Files.createDirectories(mcpDir); + Path configFile = mcpDir.resolve("servers.json"); + + String config = buildCommonMcpConfig( + buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest"), + buildStdioServerEntry("playwright", "@playwright/mcp@latest") + ); + writeCommonMcpConfig(configFile, config); + waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000); + waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000); + Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::"))); + Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::"))); + + String updatedConfig = buildCommonMcpConfig( + buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest") + ); + writeCommonMcpConfig(configFile, updatedConfig); + + waitForCondition(() -> !hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000); + Assertions.assertFalse(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::"))); + Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::"))); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testCommonMcpInvalidJsonRecovery(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path mcpDir = tempDir.resolve("action").resolve("mcp"); + Files.createDirectories(mcpDir); + Path configFile = mcpDir.resolve("servers.json"); + + writeCommonMcpConfig(configFile, "{ invalid json"); + waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 2000); + Assertions.assertFalse(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::"))); + + String config = buildCommonMcpConfig( + buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest") + ); + writeCommonMcpConfig(configFile, config); + waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000); + Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::"))); + } finally { + executor.shutdownNow(); + } + } + } + + @Nested + class DoRunTest { + + @Test + void testDoRunWithOriginUnknownExt(@TempDir Path tempDir) throws IOException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + LocalRunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path script = tempDir.resolve("run"); + Files.writeString(script, "echo ok\n"); + MetaAction metaAction = buildMetaAction(MetaAction.Type.ORIGIN, script.toString(), "run", Map.of()); + RunnerClient.RunnerResponse response = client.doRun(metaAction); + Assertions.assertNotNull(response); + Assertions.assertFalse(response.isOk()); + Assertions.assertEquals("未知文件类型", response.getData()); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDoRunWithOriginScriptSuccess(@TempDir Path tempDir) throws IOException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + LocalRunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + Path script = tempDir.resolve("run.sh"); + Files.writeString(script, "echo ok\n"); + MetaAction metaAction = buildMetaAction(MetaAction.Type.ORIGIN, script.toString(), "run", Map.of()); + RunnerClient.RunnerResponse response = client.doRun(metaAction); + Assertions.assertNotNull(response); + Assertions.assertTrue(response.isOk()); + Assertions.assertTrue(response.getData().contains("ok")); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDoRunWithMcpMissingClient(@TempDir Path tempDir) { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + LocalRunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + MetaAction metaAction = buildMetaAction(MetaAction.Type.MCP, "missing-client", "missing-tool", Map.of()); + RunnerClient.RunnerResponse response = client.doRun(metaAction); + Assertions.assertNotNull(response); + Assertions.assertFalse(response.isOk()); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDoRunViaRunnerClient(@TempDir Path tempDir) { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + RunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + MetaAction metaAction = buildMetaAction(MetaAction.Type.MCP, "missing-client", "missing-tool", Map.of()); + client.submit(metaAction); + Assertions.assertNotNull(metaAction.getResult().getData()); + } finally { + executor.shutdownNow(); + } + } + + @Test + void testDoRunWithMcpLoadedFromCommonConfig(@TempDir Path tempDir) throws IOException, InterruptedException { + ConcurrentHashMap existedMetaActions = new ConcurrentHashMap<>(); + ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + + Path mcpDir = tempDir.resolve("action").resolve("mcp"); + Files.createDirectories(mcpDir); + Path configFile = mcpDir.resolve("servers.json"); + String config = buildCommonMcpConfig( + buildStdioServerEntry("playwright", "@playwright/mcp@latest") + ); + writeCommonMcpConfig(configFile, config); + + LocalRunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); + + try { + waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000); + Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::"))); + + MetaAction metaAction = buildMetaAction(MetaAction.Type.MCP, "playwright", "browser_navigate", Map.of("url", "https://deepwiki.com/microsoft/vscode")); + client.submit(metaAction); + Assertions.assertNotEquals(MetaAction.Result.Status.WAITING, metaAction.getResult().getStatus()); + } finally { + executor.shutdownNow(); + } + } + } + +} diff --git a/Partner-Main/src/test/java/work/slhaf/partner/core/action/runner/RunnerClientTest.java b/Partner-Main/src/test/java/work/slhaf/partner/core/action/runner/RunnerClientTest.java new file mode 100644 index 00000000..6f0e7fe1 --- /dev/null +++ b/Partner-Main/src/test/java/work/slhaf/partner/core/action/runner/RunnerClientTest.java @@ -0,0 +1,45 @@ +package work.slhaf.partner.core.action.runner; + +import com.alibaba.fastjson2.JSONObject; +import work.slhaf.partner.core.action.entity.ActionFileMetaData; +import work.slhaf.partner.core.action.entity.MetaAction; +import work.slhaf.partner.core.action.entity.MetaActionInfo; + +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; + +public class RunnerClientTest { + + private static class TestRunnerClient extends RunnerClient { + + public TestRunnerClient() { + super(new ConcurrentHashMap<>(), Executors.newVirtualThreadPerTaskExecutor(), null); + } + + @Override + protected RunnerResponse doRun(MetaAction metaAction) { + return null; + } + + @Override + public String buildTmpPath(String actionKey, String codeType) { + return null; + } + + @Override + public void tmpSerialize(MetaAction tempAction, String code, String codeType) throws IOException { + + } + + @Override + public void persistSerialize(MetaActionInfo metaActionInfo, ActionFileMetaData fileMetaData) { + + } + + @Override + public JSONObject listSysDependencies() { + return null; + } + } +} diff --git a/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutorTest.java b/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutorTest.java new file mode 100644 index 00000000..ee4cfe6b --- /dev/null +++ b/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutorTest.java @@ -0,0 +1,453 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor; + +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import work.slhaf.partner.core.action.ActionCapability; +import work.slhaf.partner.core.action.ActionCore; +import work.slhaf.partner.core.action.entity.*; +import work.slhaf.partner.core.action.runner.RunnerClient; +import work.slhaf.partner.core.cognation.CognationCapability; +import work.slhaf.partner.core.memory.MemoryCapability; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.CorrectorResult; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ExtractorResult; +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.RepairerResult; + +import java.util.*; +import java.util.concurrent.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +/** + * 测试矩阵(与文档一致): + * 1) 单行动-单阶段-单MetaAction成功(已覆盖) + * 2) 多行动并发执行(未覆盖:需并发稳定性/线程调度控制) + * 3) status 非 PREPARE 直接返回(已覆盖) + * 4) 多阶段顺序执行(已覆盖) + * 5) IO 行动使用虚拟线程池(已覆盖) + * 6) extractor 失败 -> repairer OK -> 再成功(已覆盖) + * 7) extractor 失败 -> repairer FAILED(已覆盖) + * 8) extractor 失败 -> repairer ACQUIRE 阻塞后恢复(已覆盖) + * 9) runnerClient.submit 抛异常(未覆盖:需更精细的异常吞吐与线程结束校验) + * 10) paramsExtractor.execute 抛异常(未覆盖:与 #9 类似,需更精细的异常吞吐校验) + * 11) corrector.execute 抛异常导致资源未清理(已标记已知缺陷,@Disabled) + * 12) actionChain 为空导致异常与泄漏(已标记已知缺陷,@Disabled) + * 13) metaActions 为空导致 awaitAdvance 阻塞(未覆盖:更适合集成/压测) + * 17) result 状态不更新导致循环不退出(未覆盖:更适合集成/压测) + * 18) 同 stage 多 metaAction 并发完成顺序不固定(未覆盖:更适合集成/压测) + */ +@SuppressWarnings("unused") +@Slf4j +@ExtendWith(MockitoExtension.class) +class ActionExecutorTest { + + @Mock + ActionCapability actionCapability; + @Mock + MemoryCapability memoryCapability; + @Mock + CognationCapability cognationCapability; + @Mock + ParamsExtractor paramsExtractor; + @Mock + ActionRepairer actionRepairer; + @Mock + ActionCorrector actionCorrector; + @Mock + RunnerClient runnerClient; + + @InjectMocks + ActionExecutor actionExecutor; + + @BeforeEach + void setUp() { + lenient().when(cognationCapability.getChatMessages()).thenReturn(Collections.emptyList()); + lenient().when(memoryCapability.getActivatedSlices(anyString())).thenReturn(Collections.emptyList()); + lenient().when(actionCapability.putPhaserRecord(any(Phaser.class), any(ActionData.class))) + .thenAnswer(inv -> new PhaserRecord(inv.getArgument(0), inv.getArgument(1))); + lenient().when(actionCapability.loadMetaActionInfo(anyString())).thenAnswer(inv -> { + MetaActionInfo info = new MetaActionInfo(); + info.setDescription("desc"); + info.setParams(Collections.emptyMap()); + return info; + }); + CorrectorResult correctorResult = new CorrectorResult(); + correctorResult.setMetaInterventionList(Collections.emptyList()); + lenient().when(actionCorrector.execute(any())).thenReturn(correctorResult); + lenient().doNothing().when(actionCapability).handleInterventions(any(), any()); + } + + // 场景1:B1 -> B3 -> B4 -> B7(成功) -> B10。目的:验证正常主路径与资源清理。 + @Test + void execute_singleAction_singleStage_success() { + ExecutorService directExecutor = new DirectExecutorService(); + stubExecutors(directExecutor, directExecutor); + + ImmediateActionData actionData = buildActionData(singleStageChain(false)); + ActionExecutorInput input = buildInput("u1", actionData); + + ExtractorResult extractorResult = new ExtractorResult(); + extractorResult.setOk(true); + when(paramsExtractor.execute(any())).thenReturn(extractorResult); + doAnswer(inv -> { + MetaAction metaAction = inv.getArgument(0); + metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS); + return null; + }).when(runnerClient).submit(any(MetaAction.class)); + + actionExecutor.init(); + actionExecutor.execute(input); + + verify(runnerClient, times(1)).submit(any(MetaAction.class)); + verify(actionCapability, times(1)).removePhaserRecord(any(Phaser.class)); + assertEquals(ActionData.ActionStatus.SUCCESS, actionData.getStatus()); + assertEquals(1, actionData.getHistory().get(0).size()); + } + + // 场景3:B1 -> B2。目的:验证非 PREPARE 不执行任何子任务。 + @Test + void execute_statusNotPrepare_shouldSkip() { + ExecutorService directExecutor = new DirectExecutorService(); + stubExecutors(directExecutor, directExecutor); + + ImmediateActionData actionData = buildActionData(singleStageChain(false)); + actionData.setStatus(ActionData.ActionStatus.EXECUTING); + ActionExecutorInput input = buildInput("u1", actionData); + + actionExecutor.init(); + actionExecutor.execute(input); + + verify(actionCapability, never()).putPhaserRecord(any(Phaser.class), any(ActionData.class)); + verify(runnerClient, never()).submit(any(MetaAction.class)); + } + + // 场景4:B1 -> B3 -> B4(两轮) -> B7(成功) -> B10。目的:验证多阶段顺序执行。 + @Test + void execute_multiStage_success() { + ExecutorService platformExecutor = Executors.newFixedThreadPool(4); + ExecutorService virtualExecutor = Executors.newVirtualThreadPerTaskExecutor(); + stubExecutors(platformExecutor, virtualExecutor); + + Map> chain = new HashMap<>(); + chain.put(0, List.of(buildMetaAction("a1", false))); + chain.put(1, List.of(buildMetaAction("a2", false))); + ImmediateActionData actionData = buildActionData(chain); + ActionExecutorInput input = buildInput("u1", actionData); + + ExtractorResult extractorResult = new ExtractorResult(); + extractorResult.setOk(true); + when(paramsExtractor.execute(any())).thenReturn(extractorResult); + doAnswer(inv -> { + MetaAction metaAction = inv.getArgument(0); + metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS); + log.info("metaAction result:{}", metaAction.getResult().getStatus()); + return null; + }).when(runnerClient).submit(any(MetaAction.class)); + + actionExecutor.init(); + actionExecutor.execute(input); + + verify(runnerClient, timeout(5000).times(2)).submit(any(MetaAction.class)); + verify(actionCorrector, timeout(5000).times(2)).execute(any()); + assertEquals(2, actionData.getHistory().size()); + assertEquals(ActionData.ActionStatus.SUCCESS, actionData.getStatus()); + } + + // 场景5:B4.2。目的:验证 IO 行动使用虚拟线程池。 + @Test + void execute_ioMetaAction_usesVirtualExecutor() { + ExecutorService platformExecutor = Executors.newFixedThreadPool(4); + ExecutorService virtualExecutor = Executors.newVirtualThreadPerTaskExecutor(); + stubExecutors(platformExecutor, virtualExecutor); + + ImmediateActionData actionData = buildActionData(singleStageChain(true)); + ActionExecutorInput input = buildInput("u1", actionData); + + ExtractorResult extractorResult = new ExtractorResult(); + extractorResult.setOk(true); + lenient().when(paramsExtractor.execute(any())).thenReturn(extractorResult); + lenient().doAnswer(inv -> { + MetaAction metaAction = inv.getArgument(0); + metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS); + return null; + }).when(runnerClient).submit(any(MetaAction.class)); + + actionExecutor.init(); + actionExecutor.execute(input); + + verify(actionCapability, times(1)).getExecutor(ActionCore.ExecutorType.VIRTUAL); + shutdownExecutor(virtualExecutor); + } + + // 场景6:B7.2(失败) -> repairer OK -> B7(成功)。目的:验证修复后成功与上下文追加。 + @Test + void execute_extractorFail_thenRepairOk_thenSuccess() { + ExecutorService platformExecutor = Executors.newFixedThreadPool(4); + ExecutorService virtualExecutor = Executors.newVirtualThreadPerTaskExecutor(); + stubExecutors(platformExecutor, virtualExecutor); + + ImmediateActionData actionData = buildActionData(singleStageChain(false)); + ActionExecutorInput input = buildInput("u1", actionData); + + ExtractorResult fail = new ExtractorResult(); + fail.setOk(false); + ExtractorResult ok = new ExtractorResult(); + ok.setOk(true); + when(paramsExtractor.execute(any())).thenReturn(fail, ok); + + RepairerResult repairerResult = new RepairerResult(); + repairerResult.setStatus(RepairerResult.RepairerStatus.OK); + repairerResult.setFixedData(List.of("fix-1")); + when(actionRepairer.execute(any())).thenReturn(repairerResult); + + doAnswer(inv -> { + MetaAction metaAction = inv.getArgument(0); + metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS); + return null; + }).when(runnerClient).submit(any(MetaAction.class)); + + actionExecutor.init(); + actionExecutor.execute(input); + + try { + Thread.sleep(500); + } catch (InterruptedException ignored) { + } + assertEquals(1, actionData.getAdditionalContext().get(0).size()); + verify(runnerClient, timeout(5000).times(1)).submit(any(MetaAction.class)); + } + + // 场景7:B7.2(失败) -> repairer FAILED。目的:验证失败分支不提交外部执行。 + @Test + void execute_extractorFail_thenRepairFailed() { + ExecutorService platformExecutor = Executors.newFixedThreadPool(4); + ExecutorService virtualExecutor = Executors.newVirtualThreadPerTaskExecutor(); + stubExecutors(platformExecutor, virtualExecutor); + + ImmediateActionData actionData = buildActionData(singleStageChain(false)); + ActionExecutorInput input = buildInput("u1", actionData); + + ExtractorResult fail = new ExtractorResult(); + fail.setOk(false); + when(paramsExtractor.execute(any())).thenReturn(fail); + + RepairerResult repairerResult = new RepairerResult(); + repairerResult.setStatus(RepairerResult.RepairerStatus.FAILED); + when(actionRepairer.execute(any())).thenReturn(repairerResult); + + actionExecutor.init(); + actionExecutor.execute(input); + + try { + Thread.sleep(500); + } catch (InterruptedException ignored) { + } + MetaAction metaAction = actionData.getActionChain().get(0).get(0); + assertEquals(MetaAction.Result.Status.FAILED, metaAction.getResult().getStatus()); + verify(runnerClient, never()).submit(any(MetaAction.class)); + } + + // 场景8:B7.2(ACQUIRE) -> interrupt 阻塞 -> 状态恢复 -> B7(成功)。目的:验证阻塞可恢复且不死锁。 + @Test + @Timeout(3) + void execute_extractorFail_thenAcquire_thenResume() throws Exception { + ExecutorService platformExecutor = Executors.newCachedThreadPool(); + ExecutorService virtualExecutor = Executors.newCachedThreadPool(); + stubExecutors(platformExecutor, virtualExecutor); + + ImmediateActionData actionData = buildActionData(singleStageChain(false)); + ActionExecutorInput input = buildInput("u1", actionData); + + ExtractorResult fail = new ExtractorResult(); + fail.setOk(false); + ExtractorResult ok = new ExtractorResult(); + ok.setOk(true); + when(paramsExtractor.execute(any())).thenReturn(fail, ok); + + RepairerResult repairerResult = new RepairerResult(); + repairerResult.setStatus(RepairerResult.RepairerStatus.ACQUIRE); + when(actionRepairer.execute(any())).thenReturn(repairerResult); + + doAnswer(inv -> { + MetaAction metaAction = inv.getArgument(0); + metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS); + return null; + }).when(runnerClient).submit(any(MetaAction.class)); + + CountDownLatch doneLatch = new CountDownLatch(1); + doAnswer(inv -> { + doneLatch.countDown(); + return null; + }).when(actionCapability).removePhaserRecord(any(Phaser.class)); + + ExecutorService resumeExecutor = Executors.newSingleThreadExecutor(); + resumeExecutor.execute(() -> { + while (actionData.getStatus() != ActionData.ActionStatus.INTERRUPTED) { + try { + Thread.sleep(10); + } catch (InterruptedException ignored) { + } + } + actionData.setStatus(ActionData.ActionStatus.EXECUTING); + }); + + actionExecutor.init(); + actionExecutor.execute(input); + + assertTrue(doneLatch.await(2, TimeUnit.SECONDS)); + shutdownExecutor(platformExecutor); + shutdownExecutor(virtualExecutor); + shutdownExecutor(resumeExecutor); + } + + // 场景11:B4.4 异常 -> 资源未清理(已知缺陷)。目的:暴露当前行为。 + // @Disabled("known-issue: corrector 抛异常时未清理 phaser 记录") + // @Tag("known-issue") + @Test + void execute_correctorThrows_shouldLeakPhaserRecord() { + ExecutorService platformExecutor = Executors.newCachedThreadPool(); + ExecutorService virtualExecutor = Executors.newCachedThreadPool(); + stubExecutors(platformExecutor, virtualExecutor); + + ImmediateActionData actionData = buildActionData(singleStageChain(false)); + ActionExecutorInput input = buildInput("u1", actionData); + + ExtractorResult ok = new ExtractorResult(); + ok.setOk(true); + lenient().when(paramsExtractor.execute(any())).thenReturn(ok); + lenient().doAnswer(inv -> { + MetaAction metaAction = inv.getArgument(0); + metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS); + return null; + }).when(runnerClient).submit(any(MetaAction.class)); + + lenient().doThrow(new RuntimeException("boom")).when(actionCorrector).execute(any()); + + actionExecutor.init(); + actionExecutor.execute(input); + + try { + Thread.sleep(500); + } catch (InterruptedException ignored) { + } + verify(actionCapability).removePhaserRecord(any(Phaser.class)); + } + + // 场景12:B4.1 actionChain 为空导致异常(已知缺陷)。目的:暴露当前行为。 + @Disabled("known-issue: actionChain 为空导致 IndexOutOfBounds 与资源未清理") + @Tag("known-issue") + @Test + void execute_emptyActionChain_shouldFail() { + ExecutorService platformExecutor = Executors.newCachedThreadPool(); + ExecutorService virtualExecutor = Executors.newCachedThreadPool(); + stubExecutors(platformExecutor, virtualExecutor); + + ImmediateActionData actionData = buildActionData(new HashMap<>()); + ActionExecutorInput input = buildInput("u1", actionData); + + actionExecutor.init(); + actionExecutor.execute(input); + + try { + Thread.sleep(500); + } catch (InterruptedException ignored) { + } + } + + private void stubExecutors(ExecutorService platformExecutor, ExecutorService virtualExecutor) { + when(actionCapability.getExecutor(ActionCore.ExecutorType.PLATFORM)).thenReturn(platformExecutor); + when(actionCapability.getExecutor(ActionCore.ExecutorType.VIRTUAL)).thenReturn(virtualExecutor); + when(actionCapability.runnerClient()).thenReturn(runnerClient); + } + + private ActionExecutorInput buildInput(String userId, ImmediateActionData actionData) { + return new ActionExecutorInput(Set.of(actionData)); + } + + private ImmediateActionData buildActionData(Map> actionChain) { + val immediateActionData = new ImmediateActionData( + "tendency", + actionChain, + "reason", + "desc", + "source" + ); + immediateActionData.getAdditionalContext().putAll(initAdditionalContext(actionChain)); + return immediateActionData; + } + + private Map> singleStageChain(boolean io) { + Map> chain = new HashMap<>(); + chain.put(0, List.of(buildMetaAction("a1", io))); + return chain; + } + + private MetaAction buildMetaAction(String name, boolean io) { + return new MetaAction( + name, + io, + MetaAction.Type.ORIGIN, + "location" + ); + } + + private Map> initAdditionalContext(Map> actionChain) { + Map> context = new HashMap<>(); + for (Integer stage : actionChain.keySet()) { + context.put(stage, new ArrayList<>()); + } + return context; + } + + private void shutdownExecutor(ExecutorService executor) { + executor.shutdownNow(); + try { + executor.awaitTermination(1, TimeUnit.SECONDS); + } catch (InterruptedException ignored) { + } + } + + private static final class DirectExecutorService extends AbstractExecutorService { + private volatile boolean shutdown; + + @Override + public void shutdown() { + shutdown = true; + } + + @Override + public List shutdownNow() { + shutdown = true; + return Collections.emptyList(); + } + + @Override + public boolean isShutdown() { + return shutdown; + } + + @Override + public boolean isTerminated() { + return shutdown; + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) { + return true; + } + + @Override + public void execute(Runnable command) { + command.run(); + } + } +} diff --git a/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionSchedulerTest.kt b/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionSchedulerTest.kt new file mode 100644 index 00000000..24d9c88c --- /dev/null +++ b/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionSchedulerTest.kt @@ -0,0 +1,315 @@ +package work.slhaf.partner.module.modules.action.dispatcher.executor + +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.MutableStateFlow +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.ArgumentMatchers.any +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.junit.jupiter.MockitoExtension +import org.slf4j.LoggerFactory +import work.slhaf.partner.core.action.ActionCapability +import work.slhaf.partner.core.action.entity.ActionData +import work.slhaf.partner.core.action.entity.ScheduledActionData +import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput +import work.slhaf.partner.module.modules.action.dispatcher.scheduler.ActionScheduler +import java.time.ZonedDateTime +import java.time.temporal.ChronoUnit + +/** + * ActionScheduler.execute(...) 测试矩阵(控制流入口:execute)。 + * + * 场景编号与矩阵对应: + * 1) null 入参早退(B1) + * 2) PREPARE + ONCE 合法时间入轮(B2 → B2.3) + * 3) 非 PREPARE 状态忽略(B2 → B2.1) + * 4) ONCE 过期/跨日解析失败(B2 → B2.2) + * 5) CYCLE cron 非法解析失败(B2 → B2.2) + * 6) putAction 异常传播(B2 异常中断) + * 7) 同小时调度触发 ACTIVE(B2.3 + 状态变更) + * 15) 混合输入(成功/失败/忽略路径混合) + * + * 以下矩阵场景因并发/时间依赖难以稳定复现,仅在文档中标注,不在本类实现: + * 8) withTimeout 超时导致协程取消 + * 9) tick 触发 onTrigger 并调用 ActionExecutor + * 10) tick step<=0 空转延迟 + * 11) loadActions 跨小时修复 + * 13) actionExecutor 阻塞导致调度延迟 + * 14) schedule 与 tick 并发访问竞态 + */ +@ExtendWith(MockitoExtension::class) +class ActionSchedulerTest { + + @Mock + private lateinit var actionExecutor: ActionExecutor + + @Mock + private lateinit var actionCapability: ActionCapability + + @InjectMocks + private lateinit var actionScheduler: ActionScheduler + + companion object { + val log = LoggerFactory.getLogger(ActionSchedulerTest::class.java)!! + } + + @Test + fun `running test`() { + fun buildAction(time: ZonedDateTime): ScheduledActionData { + return ScheduledActionData( + "tendency", + mutableMapOf(), + "reason", + "description", + "source", + ScheduledActionData.ScheduleType.ONCE, + time.toString() + ) + } + + val now = ZonedDateTime.now() + val actions = setOf( + buildAction(now.plusMinutes(1)), + buildAction(now.truncatedTo(ChronoUnit.HOURS).plusHours(1).minusSeconds(1)), + ) + Mockito.`when`(actionCapability.listActions(null, null)) + .thenReturn(actions as Set) + Mockito.`when`(actionExecutor.execute(any())) + .thenAnswer { + val input = it.arguments[0] as ActionExecutorInput + for (actionData in input.actions) { + log.info("Executed action $actionData at ${ZonedDateTime.now()}") + } + null + } + actionScheduler.init() + + + val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default + CoroutineName("ActionSchedulerTest")) + scope.launch { + actionScheduler.execute( + setOf( + buildAction(now.plusSeconds(5)), + ) + ) + } + readlnOrNull() + } + + @Test + fun `execute with null input should return null and no side effects`() { + // 场景编号:1;路径:B1;目的:验证正常早退 + val result = actionScheduler.execute(null) + + assertEquals(null, result) + verify(actionCapability, Mockito.never()).putAction(any(ActionData::class.java)) + } + + @Test + fun `execute should put action and schedule valid ONCE prepare action`() { + // 场景编号:2;路径:B2 → B2.3;目的:验证正常入轮与副作用 + initTimeWheelWithPrimaryActions(emptySet()) + val action = buildScheduledAction( + type = ScheduledActionData.ScheduleType.ONCE, + ZonedDateTime.now().plusHours(1).toString() + ) + + actionScheduler.execute(setOf(action)) + + verify(actionCapability, times(1)).putAction(action) + val timeWheel = timeWheel() + val bucket = actionsGroupByHour(timeWheel)[action.scheduleContentHour()] + assertTrue(bucket.contains(action)) + } + + @Test + fun `execute should ignore non-prepare action for scheduling`() { + // 场景编号:3;路径:B2 → B2.1;目的:验证忽略非 PREPARE 状态 + initTimeWheelWithPrimaryActions(emptySet()) + val action = buildScheduledAction( + type = ScheduledActionData.ScheduleType.ONCE + ) + + actionScheduler.execute(setOf(action)) + + verify(actionCapability, times(1)).putAction(action) + val allScheduled = allScheduledActions(timeWheel()) + assertFalse(allScheduled.contains(action)) + } + + @Test + fun `execute should skip expired ONCE action`() { + // 场景编号:4;路径:B2 → B2.2;目的:验证解析失败被跳过 + initTimeWheelWithPrimaryActions(emptySet()) + val action = buildScheduledAction( + type = ScheduledActionData.ScheduleType.ONCE + ) + + actionScheduler.execute(setOf(action)) + + val allScheduled = allScheduledActions(timeWheel()) + assertFalse(allScheduled.contains(action)) + } + + @Test + fun `execute should skip invalid CYCLE cron`() { + // 场景编号:5;路径:B2 → B2.2;目的:验证 cron 解析失败被跳过 + initTimeWheelWithPrimaryActions(emptySet()) + val action = buildScheduledAction( + type = ScheduledActionData.ScheduleType.CYCLE, + scheduleContentOverride = "invalid-cron" + ) + + actionScheduler.execute(setOf(action)) + + val allScheduled = allScheduledActions(timeWheel()) + assertFalse(allScheduled.contains(action)) + } + + @Test + fun `execute should propagate exception from putAction`() { + // 场景编号:6;路径:B2 异常中断;目的:验证异常传播 + initTimeWheelWithPrimaryActions(emptySet()) + val action = buildScheduledAction( + type = ScheduledActionData.ScheduleType.ONCE + ) + Mockito.doThrow(RuntimeException("boom")) + .`when`(actionCapability) + .putAction(action) + + assertThrows(RuntimeException::class.java) { + actionScheduler.execute(setOf(action)) + } + } + + @Test + fun `execute should activate wheel when scheduling current hour`() { + // 场景编号:7;路径:B2.3;目的:验证同小时调度触发 ACTIVE + initTimeWheelWithPrimaryActions(emptySet()) + val action = buildScheduledAction( + type = ScheduledActionData.ScheduleType.ONCE, + scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString() + ) + + val timeWheel = timeWheel() + val actionHour = action.scheduleContentHour() + setCurrentHour(timeWheel, actionHour) + setWheelState(timeWheel, "SLEEPING") + + actionScheduler.execute(setOf(action)) + + assertEquals("ACTIVE", wheelStateName(timeWheel)) + } + + @Test + fun `execute should handle mixed actions consistently`() { + // 场景编号:15;路径:B2 + B2.1/B2.2/B2.3;目的:验证混合输入行为 + initTimeWheelWithPrimaryActions(emptySet()) + val ok = buildScheduledAction( + type = ScheduledActionData.ScheduleType.ONCE, + scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString() + ) + val nonPrepare = buildScheduledAction( + type = ScheduledActionData.ScheduleType.ONCE, + scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString() + ) + nonPrepare.status = ActionData.ActionStatus.FAILED + val invalid = buildScheduledAction( + type = ScheduledActionData.ScheduleType.CYCLE, + scheduleContentOverride = "invalid-cron" + ) + + actionScheduler.execute(setOf(ok, nonPrepare, invalid)) + + verify(actionCapability, times(1)).putAction(ok) + verify(actionCapability, times(1)).putAction(nonPrepare) + verify(actionCapability, times(1)).putAction(invalid) + val allScheduled = allScheduledActions(timeWheel()) + assertTrue(allScheduled.contains(ok)) + assertFalse(allScheduled.contains(nonPrepare)) + assertFalse(allScheduled.contains(invalid)) + } + + private fun initTimeWheelWithPrimaryActions(actions: Set) { + @Suppress("UNCHECKED_CAST") + Mockito.`when`(actionCapability.listActions(null, null)) + .thenReturn(actions as Set) + actionScheduler.init() + } + + private fun buildScheduledAction( + type: ScheduledActionData.ScheduleType, + scheduleContentOverride: String? = null + ): ScheduledActionData { + val action = ScheduledActionData( + "test", + mutableMapOf(), + "reason", + "description", + "test", + type, + scheduleContentOverride ?: scheduleContentOverride.toString() + ) + return action + } + + private fun ScheduledActionData.scheduleContentHour(): Int { + return ZonedDateTime.parse(this.scheduleContent).hour + } + + private fun timeWheel(): Any { + val field = actionScheduler.javaClass.getDeclaredField("timeWheel") + field.isAccessible = true + return field.get(actionScheduler) + } + + @Suppress("UNCHECKED_CAST") + private fun actionsGroupByHour(timeWheel: Any): Array> { + val field = timeWheel.javaClass.getDeclaredField("actionsGroupByHour") + field.isAccessible = true + return field.get(timeWheel) as Array> + } + + private fun allScheduledActions(timeWheel: Any): Set { + val result = linkedSetOf() + for (bucket in actionsGroupByHour(timeWheel)) { + result.addAll(bucket) + } + return result + } + + private fun setCurrentHour(timeWheel: Any, hour: Int) { + val field = timeWheel.javaClass.getDeclaredField("currentHour") + field.isAccessible = true + field.setInt(timeWheel, hour) + } + + private fun setWheelState(timeWheel: Any, name: String) { + val field = timeWheel.javaClass.getDeclaredField("state") + field.isAccessible = true + @Suppress("UNCHECKED_CAST") + val state = field.get(timeWheel) as MutableStateFlow + state.value = wheelStateEnum(name) + } + + private fun wheelStateName(timeWheel: Any): String { + val field = timeWheel.javaClass.getDeclaredField("state") + field.isAccessible = true + val state = field.get(timeWheel) as MutableStateFlow<*> + val value = state.value as Enum<*> + return value.name + } + + private fun wheelStateEnum(name: String): Any { + @Suppress("UNCHECKED_CAST") + val clazz = Class.forName( + $$"work.slhaf.partner.module.modules.action.dispatcher.scheduler.ActionScheduler$TimeWheel$WheelState" + ) as Class> + return java.lang.Enum.valueOf(clazz, name) + } +} diff --git a/Partner-SandboxRunner/.gitattributes b/Partner-SandboxRunner/.gitattributes new file mode 100644 index 00000000..3b41682a --- /dev/null +++ b/Partner-SandboxRunner/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/Partner-SandboxRunner/.gitignore b/Partner-SandboxRunner/.gitignore new file mode 100644 index 00000000..667aaef0 --- /dev/null +++ b/Partner-SandboxRunner/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/Partner-SandboxRunner/.mvn/wrapper/maven-wrapper.properties b/Partner-SandboxRunner/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000..c0bcafe9 --- /dev/null +++ b/Partner-SandboxRunner/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,3 @@ +wrapperVersion=3.3.4 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/Partner-SandboxRunner/mvnw b/Partner-SandboxRunner/mvnw new file mode 100755 index 00000000..bd8896bf --- /dev/null +++ b/Partner-SandboxRunner/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.4 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/Partner-SandboxRunner/mvnw.cmd b/Partner-SandboxRunner/mvnw.cmd new file mode 100644 index 00000000..92450f93 --- /dev/null +++ b/Partner-SandboxRunner/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.4 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/Partner-SandboxRunner/pom.xml b/Partner-SandboxRunner/pom.xml new file mode 100644 index 00000000..835877c9 --- /dev/null +++ b/Partner-SandboxRunner/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 4.0.0 + + + work.slhaf + Partner-SandboxRunner + 0.0.1-SNAPSHOT + Partner-SandboxRunner + Partner-SandboxRunner + + + + + + + + + + + + + + + 21 + + + + org.springframework.boot + spring-boot-starter-webmvc + + + org.springframework.boot + spring-boot-starter-websocket + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-webmvc-test + test + + + org.springframework.boot + spring-boot-starter-websocket-test + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/Partner-SandboxRunner/src/main/java/work/slhaf/partner/executor/PartnerExecutorApplication.java b/Partner-SandboxRunner/src/main/java/work/slhaf/partner/executor/PartnerExecutorApplication.java new file mode 100644 index 00000000..a593d858 --- /dev/null +++ b/Partner-SandboxRunner/src/main/java/work/slhaf/partner/executor/PartnerExecutorApplication.java @@ -0,0 +1,13 @@ +package work.slhaf.partner.executor; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PartnerExecutorApplication { + + public static void main(String[] args) { + SpringApplication.run(PartnerExecutorApplication.class, args); + } + +} diff --git a/Partner-SandboxRunner/src/main/resources/application.properties b/Partner-SandboxRunner/src/main/resources/application.properties new file mode 100644 index 00000000..ebcac2a1 --- /dev/null +++ b/Partner-SandboxRunner/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.application.name=Partner-Executor diff --git a/Partner-SandboxRunner/src/test/java/work/slhaf/partner/executor/PartnerExecutorApplicationTests.java b/Partner-SandboxRunner/src/test/java/work/slhaf/partner/executor/PartnerExecutorApplicationTests.java new file mode 100644 index 00000000..eb26c3e1 --- /dev/null +++ b/Partner-SandboxRunner/src/test/java/work/slhaf/partner/executor/PartnerExecutorApplicationTests.java @@ -0,0 +1,13 @@ +package work.slhaf.partner.executor; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class PartnerExecutorApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/pom.xml b/pom.xml index a8783473..d2dc3f61 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,8 @@ Partner-Test-Demo Partner-Main Partner-Api + Partner-SandboxRunner + Partner-Common @@ -50,7 +52,8 @@ - + work.slhaf.demo.AgentDemoApplication