mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 08:43:02 +08:00
feat(runner): add execution policy abstract for local running
This commit is contained in:
@@ -7,14 +7,14 @@ import io.modelcontextprotocol.client.transport.customizer.McpSyncHttpClientRequ
|
|||||||
import io.modelcontextprotocol.common.McpTransportContext;
|
import io.modelcontextprotocol.common.McpTransportContext;
|
||||||
import io.modelcontextprotocol.json.McpJsonMapper;
|
import io.modelcontextprotocol.json.McpJsonMapper;
|
||||||
import io.modelcontextprotocol.spec.McpClientTransport;
|
import io.modelcontextprotocol.spec.McpClientTransport;
|
||||||
import work.slhaf.partner.core.action.runner.policy.RunnerExecutionPolicy;
|
import work.slhaf.partner.core.action.runner.policy.ExecutionPolicyRegistry;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
|
|
||||||
public class McpTransportFactory {
|
public class McpTransportFactory {
|
||||||
|
|
||||||
public McpClientTransport create(McpTransportConfig config, RunnerExecutionPolicy policy) {
|
public McpClientTransport create(McpTransportConfig config, ExecutionPolicyRegistry policy) {
|
||||||
return switch (config) {
|
return switch (config) {
|
||||||
case McpTransportConfig.Stdio stdio -> {
|
case McpTransportConfig.Stdio stdio -> {
|
||||||
ServerParameters serverParameters = ServerParameters.builder(stdio.command())
|
ServerParameters serverParameters = ServerParameters.builder(stdio.command())
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package work.slhaf.partner.core.action.runner.policy
|
||||||
|
|
||||||
|
object DirectPolicyProvider : PolicyProvider(
|
||||||
|
policyName = "direct"
|
||||||
|
) {
|
||||||
|
|
||||||
|
override fun prepare(
|
||||||
|
policy: ExecutionPolicy,
|
||||||
|
commands: List<String>
|
||||||
|
): WrappedLaunchSpec {
|
||||||
|
val (command, args) = splitCommands(commands)
|
||||||
|
return WrappedLaunchSpec(
|
||||||
|
command = command,
|
||||||
|
args = args,
|
||||||
|
workingDirectory = policy.workingDirectory,
|
||||||
|
environment = resolveEnvironment(policy)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package work.slhaf.partner.core.action.runner.policy
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet
|
||||||
|
|
||||||
|
object ExecutionPolicyRegistry {
|
||||||
|
|
||||||
|
private const val DEFAULT_PROVIDER = "direct"
|
||||||
|
|
||||||
|
private val policyProviders = ConcurrentHashMap<String, PolicyProvider>().apply {
|
||||||
|
put(DEFAULT_PROVIDER, DirectPolicyProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val listeners = CopyOnWriteArraySet<RunnerExecutionPolicyListener>()
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var currentPolicy = ExecutionPolicy(
|
||||||
|
provider = "direct",
|
||||||
|
mode = ExecutionPolicy.Mode.DIRECT,
|
||||||
|
net = ExecutionPolicy.Network.ENABLE,
|
||||||
|
inheritEnv = true,
|
||||||
|
env = emptyMap(),
|
||||||
|
workingDirectory = null,
|
||||||
|
readOnlyPaths = emptySet(),
|
||||||
|
writablePaths = emptySet(),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun prepare(commands: List<String>): WrappedLaunchSpec {
|
||||||
|
val policy = currentPolicy
|
||||||
|
val provider = policyProviders[policy.provider]
|
||||||
|
?: policyProviders[DEFAULT_PROVIDER]
|
||||||
|
?: error("Default provider '${DEFAULT_PROVIDER}' is not registered")
|
||||||
|
return provider.prepare(policy, commands)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updatePolicy(policy: ExecutionPolicy) {
|
||||||
|
currentPolicy = policy
|
||||||
|
listeners.forEach { it.onPolicyChanged(policy) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addListener(listener: RunnerExecutionPolicyListener) {
|
||||||
|
listeners += listener
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeListener(listener: RunnerExecutionPolicyListener) {
|
||||||
|
listeners -= listener
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerPolicyProvider(policyProvider: PolicyProvider) {
|
||||||
|
val name = policyProvider.policyName
|
||||||
|
if (policyProviders.containsKey(name)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
policyProviders[name] = policyProvider
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ExecutionPolicy(
|
||||||
|
val mode: Mode,
|
||||||
|
val provider: String,
|
||||||
|
val net: Network,
|
||||||
|
val inheritEnv: Boolean,
|
||||||
|
val env: Map<String, String>,
|
||||||
|
val workingDirectory: String?,
|
||||||
|
val readOnlyPaths: Set<String>,
|
||||||
|
val writablePaths: Set<String>,
|
||||||
|
) {
|
||||||
|
|
||||||
|
enum class Mode {
|
||||||
|
DIRECT,
|
||||||
|
SANDBOX
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Network {
|
||||||
|
DISABLE,
|
||||||
|
ENABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data class WrappedLaunchSpec(
|
||||||
|
val command: String,
|
||||||
|
val args: List<String>,
|
||||||
|
val workingDirectory: String? = null,
|
||||||
|
val environment: Map<String, String> = emptyMap()
|
||||||
|
)
|
||||||
|
|
||||||
|
abstract class PolicyProvider(
|
||||||
|
val policyName: String
|
||||||
|
) {
|
||||||
|
|
||||||
|
abstract fun prepare(
|
||||||
|
policy: ExecutionPolicy,
|
||||||
|
commands: List<String>
|
||||||
|
): WrappedLaunchSpec
|
||||||
|
|
||||||
|
protected fun resolveEnvironment(policy: ExecutionPolicy): Map<String, String> {
|
||||||
|
val result = LinkedHashMap<String, String>()
|
||||||
|
if (policy.inheritEnv) {
|
||||||
|
result.putAll(System.getenv())
|
||||||
|
}
|
||||||
|
result.putAll(policy.env)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun splitCommands(commands: List<String>): Pair<String, List<String>> {
|
||||||
|
require(commands.isNotEmpty()) { "commands must not be empty" }
|
||||||
|
return commands.first() to commands.drop(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RunnerExecutionPolicyListener {
|
||||||
|
fun onPolicyChanged(policy: ExecutionPolicy)
|
||||||
|
}
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
package work.slhaf.partner.core.action.runner.policy;
|
|
||||||
|
|
||||||
public interface RunnerExecutionPolicy {
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user