diff --git a/scripts/build-portal-runtime.mjs b/scripts/build-portal-runtime.mjs index 38da84b..7378c43 100755 --- a/scripts/build-portal-runtime.mjs +++ b/scripts/build-portal-runtime.mjs @@ -319,6 +319,10 @@ async function writeMetadata() { path.join(root, 'scripts', 'install-runtime-slo-report-agent.sh'), path.join(runtimeRoot, 'scripts', 'install-runtime-slo-report-agent.sh'), ); + await fs.copyFile( + path.join(root, 'scripts', 'install-agent-run-worker-agent.sh'), + path.join(runtimeRoot, 'scripts', 'install-agent-run-worker-agent.sh'), + ); await fs.copyFile( path.join(root, 'scripts', 'check-tool-runtime.mjs'), path.join(runtimeRoot, 'scripts', 'check-tool-runtime.mjs'), @@ -387,6 +391,7 @@ async function writeMetadata() { ' curl -sk https://mm.tkmind.cn/api/runtime/status # includes toolRuntime.queue', ' node scripts/agent-run-worker.mjs --status', ' node scripts/agent-run-worker.mjs --once', + ' bash scripts/install-agent-run-worker-agent.sh # installs disabled by default', '', ].join('\n'), ); @@ -414,6 +419,7 @@ async function main() { await fs.chmod(path.join(runtimeRoot, 'scripts', 'install-runtime-metrics-agent.sh'), 0o755); await fs.chmod(path.join(runtimeRoot, 'scripts', 'install-runtime-heartbeat-agent.sh'), 0o755); await fs.chmod(path.join(runtimeRoot, 'scripts', 'install-runtime-slo-report-agent.sh'), 0o755); + await fs.chmod(path.join(runtimeRoot, 'scripts', 'install-agent-run-worker-agent.sh'), 0o755); await fs.chmod(path.join(runtimeRoot, 'scripts', 'check-tool-runtime.mjs'), 0o755); await fs.chmod(path.join(runtimeRoot, 'scripts', 'memind-portal-tunnel.sh'), 0o755); console.log(''); diff --git a/scripts/install-agent-run-worker-agent.sh b/scripts/install-agent-run-worker-agent.sh new file mode 100755 index 0000000..c6402da --- /dev/null +++ b/scripts/install-agent-run-worker-agent.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +NODE_BIN="${NODE_BIN:-/opt/homebrew/opt/node@24/bin/node}" +SCRIPT="${MEMIND_AGENT_RUN_WORKER_SCRIPT:-$ROOT/scripts/agent-run-worker.mjs}" +LABEL="${MEMIND_AGENT_RUN_WORKER_LABEL:-cn.tkmind.memind-agent-run-worker}" +PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist" +LOG="${MEMIND_AGENT_RUN_WORKER_LOG:-$HOME/Library/Logs/memind-agent-run-worker.log}" +GUI="gui/$(id -u)" +POLL_MS="${MEMIND_AGENT_RUN_WORKER_POLL_MS:-3000}" +BATCH_SIZE="${MEMIND_AGENT_RUN_WORKER_BATCH_SIZE:-1}" +CONCURRENCY="${MEMIND_AGENT_RUN_QUEUE_CONCURRENCY:-1}" +RUN_TIMEOUT_MS="${MEMIND_AGENT_RUN_TIMEOUT_MS:-900000}" +TOOL_GATEWAY_ENABLED="${MEMIND_TOOL_GATEWAY_ENABLED:-0}" +TOOL_GATEWAY_DRY_RUN="${MEMIND_TOOL_GATEWAY_DRY_RUN:-0}" +START="${MEMIND_AGENT_RUN_WORKER_START:-0}" + +mkdir -p "$HOME/Library/LaunchAgents" "$(dirname "$LOG")" + +if [[ ! -x "$NODE_BIN" ]]; then + NODE_BIN="$(command -v node)" +fi +if [[ ! -f "$SCRIPT" ]]; then + echo "agent run worker script not found: $SCRIPT" >&2 + exit 1 +fi + +cat > "$PLIST" < + + + + Label + $LABEL + ProgramArguments + + $NODE_BIN + $SCRIPT + --poll-ms + $POLL_MS + --limit + $BATCH_SIZE + + WorkingDirectory + $ROOT + RunAtLoad + + KeepAlive + + ThrottleInterval + 10 + StandardOutPath + $LOG + StandardErrorPath + $LOG + EnvironmentVariables + + PATH + /opt/homebrew/bin:/opt/homebrew/opt/node@24/bin:/usr/local/bin:/usr/bin:/bin + MEMIND_AGENT_RUN_AUTODISPATCH + 0 + MEMIND_AGENT_RUN_WORKER_POLL_MS + $POLL_MS + MEMIND_AGENT_RUN_WORKER_BATCH_SIZE + $BATCH_SIZE + MEMIND_AGENT_RUN_QUEUE_CONCURRENCY + $CONCURRENCY + MEMIND_AGENT_RUN_TIMEOUT_MS + $RUN_TIMEOUT_MS + MEMIND_TOOL_GATEWAY_ENABLED + $TOOL_GATEWAY_ENABLED + MEMIND_TOOL_GATEWAY_DRY_RUN + $TOOL_GATEWAY_DRY_RUN + + + +EOF + +plutil -lint "$PLIST" +launchctl bootout "$GUI/$LABEL" 2>/dev/null || true +launchctl bootstrap "$GUI" "$PLIST" + +if [[ "$START" == "1" || "$START" == "true" || "$START" == "yes" ]]; then + launchctl enable "$GUI/$LABEL" + launchctl kickstart -k "$GUI/$LABEL" + state="started" +else + launchctl disable "$GUI/$LABEL" 2>/dev/null || true + state="installed-disabled" +fi + +echo "installed $PLIST" +echo "state: $state" +echo "script: $SCRIPT" +echo "poll_ms: $POLL_MS" +echo "batch_size: $BATCH_SIZE" +echo "concurrency: $CONCURRENCY" +echo "tool_gateway_enabled: $TOOL_GATEWAY_ENABLED" +echo "tool_gateway_dry_run: $TOOL_GATEWAY_DRY_RUN" +echo "log: $LOG" +echo "manual start: launchctl enable $GUI/$LABEL && launchctl kickstart -k $GUI/$LABEL" +echo "manual stop: launchctl bootout $GUI/$LABEL"