mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-28 18:44:58 +00:00
* feat(server): default to kap-server and remove the v1 server package - kimi server run / kimi web now boot kap-server (agent-core-v2 engine) unconditionally; the KIMI_CODE_EXPERIMENTAL_FLAG gate on the server path is gone (the kimi -p print-mode gate stays) - move the OS service manager (svc: launchd/systemd/schtasks) from packages/server into packages/kap-server and export it there - repoint the CLI server subcommands, tests, and dev scripts at kap-server; relabel the web dev backend presets default/multi - delete packages/server and update workspace bookkeeping (flake.nix, pnpm-lock.yaml, changeset ignore docs, AGENTS.md, agent-core-dev skill) * test(server-e2e): remove scenarios that depend on v1 debug endpoints Scenarios 04-stateless-controls, 10-prompt-queue-steer and 12-send-and-cancel assert through the /api/v1/debug/prompts/* introspection routes, which only the deleted v1 server mounted — kap-server's --debug-endpoints is a documented no-op, so these scenarios can only 404 now. The vitest e2e files using the same surface already skip when it is absent.
187 lines
6.8 KiB
Bash
Executable file
187 lines
6.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
PACKAGE_DIR="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
|
|
REPO_ROOT="$(cd -- "${PACKAGE_DIR}/../.." && pwd)"
|
|
|
|
workspace_slug="$(
|
|
basename -- "${REPO_ROOT}" \
|
|
| tr '[:upper:]' '[:lower:]' \
|
|
| tr -cs 'a-z0-9_.-' '-' \
|
|
| sed -e 's/^[^a-z0-9]*//' -e 's/[^a-z0-9]*$//' \
|
|
| cut -c1-48
|
|
)"
|
|
if [[ -z "${workspace_slug}" ]]; then
|
|
workspace_slug="workspace"
|
|
fi
|
|
workspace_hash="$(printf '%s' "${REPO_ROOT}" | cksum | awk '{print $1}')"
|
|
RUN_ID="${KIMI_SERVER_E2E_RUN_ID:-${workspace_slug}-${workspace_hash}}"
|
|
|
|
BASE_IMAGE="${KIMI_SERVER_E2E_BASE_IMAGE:-kimi-server-e2e-base:${RUN_ID}}"
|
|
IMAGE="${KIMI_SERVER_E2E_IMAGE:-kimi-server-e2e:${RUN_ID}}"
|
|
CONTAINER="${KIMI_SERVER_E2E_CONTAINER:-kimi-server-e2e-${RUN_ID}}"
|
|
STATE_ROOT="${KIMI_SERVER_E2E_STATE_ROOT:-${HOME}/.kimi-code-server-dev}"
|
|
PORT="${KIMI_SERVER_E2E_PORT:-58627}"
|
|
|
|
KIMI_HOME_HOST="${KIMI_SERVER_E2E_KIMI_HOME_HOST:-${STATE_ROOT}/docker-e2e/${RUN_ID}/kimi-code-home}"
|
|
KIMI_HOME_CONTAINER="/data/docker-e2e/kimi-code-home"
|
|
SEED_HOME_HOST="${KIMI_SERVER_E2E_SEED_KIMI_HOME_HOST:-${STATE_ROOT}/kimi-home/kimi-code-home}"
|
|
|
|
if [[ -n "${KIMI_SERVER_E2E_REPORT_DIR_HOST:-}" ]]; then
|
|
REPORT_DIR_HOST="${KIMI_SERVER_E2E_REPORT_DIR_HOST}"
|
|
REPORT_ROOT_HOST="$(dirname -- "${REPORT_DIR_HOST}")"
|
|
REPORT_DIR_NAME="$(basename -- "${REPORT_DIR_HOST}")"
|
|
else
|
|
REPORT_ROOT_HOST="${KIMI_SERVER_E2E_REPORT_ROOT_HOST:-${STATE_ROOT}/server-e2e-reports/docker/${RUN_ID}}"
|
|
REPORT_DIR_NAME="latest"
|
|
REPORT_DIR_HOST="${REPORT_ROOT_HOST}/${REPORT_DIR_NAME}"
|
|
fi
|
|
REPORT_ROOT_CONTAINER="/data/server-e2e-reports/docker"
|
|
REPORT_DIR_CONTAINER="${REPORT_ROOT_CONTAINER}/${REPORT_DIR_NAME}"
|
|
TMPDIR_CONTAINER="/data/docker-e2e/tmp"
|
|
|
|
NM_ROOT="${STATE_ROOT}/docker-e2e/${RUN_ID}/nm"
|
|
|
|
workspace_node_modules=(
|
|
"root:/workspace/kimi-code/node_modules"
|
|
"apps_kimi-code:/workspace/kimi-code/apps/kimi-code/node_modules"
|
|
"apps_kimi-web:/workspace/kimi-code/apps/kimi-web/node_modules"
|
|
"apps_vis:/workspace/kimi-code/apps/vis/node_modules"
|
|
"apps_vis_server:/workspace/kimi-code/apps/vis/server/node_modules"
|
|
"apps_vis_web:/workspace/kimi-code/apps/vis/web/node_modules"
|
|
"docs:/workspace/kimi-code/docs/node_modules"
|
|
"pkg_acp-adapter:/workspace/kimi-code/packages/acp-adapter/node_modules"
|
|
"pkg_agent-core:/workspace/kimi-code/packages/agent-core/node_modules"
|
|
"pkg_kap-server:/workspace/kimi-code/packages/kap-server/node_modules"
|
|
"pkg_server-e2e:/workspace/kimi-code/packages/server-e2e/node_modules"
|
|
"pkg_kaos:/workspace/kimi-code/packages/kaos/node_modules"
|
|
"pkg_kosong:/workspace/kimi-code/packages/kosong/node_modules"
|
|
"pkg_migration-legacy:/workspace/kimi-code/packages/migration-legacy/node_modules"
|
|
"pkg_node-sdk:/workspace/kimi-code/packages/node-sdk/node_modules"
|
|
"pkg_oauth:/workspace/kimi-code/packages/oauth/node_modules"
|
|
"pkg_protocol:/workspace/kimi-code/packages/protocol/node_modules"
|
|
"pkg_services:/workspace/kimi-code/packages/services/node_modules"
|
|
"pkg_telemetry:/workspace/kimi-code/packages/telemetry/node_modules"
|
|
)
|
|
|
|
mkdir -p "${STATE_ROOT}" "${KIMI_HOME_HOST}" "${REPORT_DIR_HOST}" "${NM_ROOT}"
|
|
for mount in "${workspace_node_modules[@]}"; do
|
|
mkdir -p "${NM_ROOT}/${mount%%:*}"
|
|
done
|
|
|
|
# Seed only auth/config into the isolated docker-e2e home. Never copy server
|
|
# locks, sessions, uploaded files, or reports from the compose server home.
|
|
if [[ -f "${SEED_HOME_HOST}/config.toml" && ! -f "${KIMI_HOME_HOST}/config.toml" ]]; then
|
|
cp "${SEED_HOME_HOST}/config.toml" "${KIMI_HOME_HOST}/config.toml"
|
|
fi
|
|
if [[ -d "${SEED_HOME_HOST}/credentials" && ! -d "${KIMI_HOME_HOST}/credentials" ]]; then
|
|
cp -R "${SEED_HOME_HOST}/credentials" "${KIMI_HOME_HOST}/credentials"
|
|
fi
|
|
|
|
if [[ "${KIMI_SERVER_E2E_SKIP_BUILD:-0}" != "1" ]]; then
|
|
docker build -t "${BASE_IMAGE}" -f "${REPO_ROOT}/Dockerfile" "${REPO_ROOT}"
|
|
docker build \
|
|
-t "${IMAGE}" \
|
|
-f "${PACKAGE_DIR}/Dockerfile" \
|
|
--build-arg "BASE_IMAGE=${BASE_IMAGE}" \
|
|
"${REPO_ROOT}"
|
|
fi
|
|
|
|
docker rm -f "${CONTAINER}" >/dev/null 2>&1 || true
|
|
|
|
read -r -d '' container_script <<'EOS' || true
|
|
set -euo pipefail
|
|
|
|
cd /workspace/kimi-code
|
|
mkdir -p "${KIMI_CODE_HOME}/server" "${KIMI_SERVER_E2E_REPORT_DIR}" "${TMPDIR}" /data/server-e2e-reports/docker
|
|
rm -f "${KIMI_CODE_HOME}/server/lock"
|
|
|
|
if [[ ! -e /workspace/kimi-code/node_modules/.modules.yaml || ! -e /workspace/kimi-code/packages/server-e2e/node_modules/ws ]]; then
|
|
echo "[server-e2e:docker] installing pnpm deps"
|
|
pnpm install --frozen-lockfile
|
|
else
|
|
echo "[server-e2e:docker] pnpm deps already present"
|
|
fi
|
|
|
|
server_log="/data/server-e2e-reports/docker/server.log"
|
|
: > "${server_log}"
|
|
|
|
echo "[server-e2e:docker] starting server on container-local ${KIMI_SERVER_URL}"
|
|
pnpm dev:server -- \
|
|
--host 127.0.0.1 \
|
|
--port "${KIMI_SERVER_E2E_PORT}" \
|
|
--log-level debug \
|
|
--debug-endpoints \
|
|
>"${server_log}" 2>&1 &
|
|
server_pid=$!
|
|
|
|
cleanup() {
|
|
status=$?
|
|
if kill -0 "${server_pid}" >/dev/null 2>&1; then
|
|
kill "${server_pid}" >/dev/null 2>&1 || true
|
|
wait "${server_pid}" >/dev/null 2>&1 || true
|
|
fi
|
|
exit "${status}"
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
|
|
ready=0
|
|
for attempt in $(seq 1 90); do
|
|
if curl -fsS "${KIMI_SERVER_URL}/api/v1/meta" >/tmp/server-meta.json 2>/tmp/server-curl.err; then
|
|
ready=1
|
|
echo "[server-e2e:docker] server ready: $(cat /tmp/server-meta.json)"
|
|
break
|
|
fi
|
|
if ! kill -0 "${server_pid}" >/dev/null 2>&1; then
|
|
echo "[server-e2e:docker] server exited before readiness" >&2
|
|
tail -n 200 "${server_log}" >&2 || true
|
|
exit 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
if [[ "${ready}" != "1" ]]; then
|
|
echo "[server-e2e:docker] server did not become ready within 90s" >&2
|
|
cat /tmp/server-curl.err >&2 || true
|
|
tail -n 200 "${server_log}" >&2 || true
|
|
exit 1
|
|
fi
|
|
|
|
cd /workspace/kimi-code/packages/server-e2e
|
|
pnpm test:scenarios
|
|
EOS
|
|
|
|
docker_args=(
|
|
run
|
|
--rm
|
|
--init
|
|
--name "${CONTAINER}"
|
|
--workdir /workspace/kimi-code/packages/server-e2e
|
|
--env "KIMI_CODE_HOME=${KIMI_HOME_CONTAINER}"
|
|
--env "KIMI_SERVER_E2E_PORT=${PORT}"
|
|
--env "KIMI_SERVER_URL=http://127.0.0.1:${PORT}"
|
|
--env "KIMI_SERVER_E2E_REPORT_DIR=${REPORT_DIR_CONTAINER}"
|
|
--env "TMPDIR=${TMPDIR_CONTAINER}"
|
|
--env "TERM=xterm-256color"
|
|
--env "TZ=Asia/Shanghai"
|
|
--env "npm_config_store_dir=/workspace/kimi-code/node_modules/.pnpm-store"
|
|
--env "npm_config_package_import_method=copy"
|
|
--volume "${REPO_ROOT}:/workspace/kimi-code:ro"
|
|
--volume "${KIMI_HOME_HOST}:${KIMI_HOME_CONTAINER}"
|
|
--volume "${REPORT_ROOT_HOST}:${REPORT_ROOT_CONTAINER}"
|
|
)
|
|
|
|
for mount in "${workspace_node_modules[@]}"; do
|
|
docker_args+=(--volume "${NM_ROOT}/${mount%%:*}:${mount#*:}")
|
|
done
|
|
|
|
echo "[server-e2e:docker] running ${IMAGE} without host port publishing"
|
|
set +e
|
|
docker "${docker_args[@]}" "${IMAGE}" bash -lc "${container_script}"
|
|
status=$?
|
|
set -e
|
|
|
|
echo "[server-e2e:docker] report: ${REPORT_DIR_HOST}/index.html"
|
|
echo "[server-e2e:docker] server log: ${REPORT_ROOT_HOST}/server.log"
|
|
exit "${status}"
|