Repository navigation
feat(e2e): run paired continuation workloads with Kimi Code - #2038
Conversation
`paired --host kimi-code` runs both arms with a new Harbor installed agent, because Harbor's kimi-cli agent installs the earlier Python CLI, which has another home, configuration, and plugin format. The agent installs Node 24.21.0 and @moonshot-ai/kimi-code 2.1.1, the versions PowerContext's Kimi Code acceptance workflow tests, writes an OpenRouter model configuration, and runs each session with `kimi -p --output-format stream-json`. OFF has no plugin, mounts, or PowerContext settings. Kimi Code installs plugins only from its interactive interface, so ON writes the copy and registry entry that `powercontext setup kimi-code` writes, configured with the arm's Scope; a test compares the two installations. The plugin takes the Server token without the Bearer scheme, so PluginHost gains an overridable credential setting. It takes the Server only as an origin, so the job rejects another URL before its container starts, and accepts plain HTTP only on loopback, so for a plain-HTTP Server the ON arm relays 127.0.0.1:47731 to it. Before each session in both arms the agent empties Kimi Code's home except its configuration and the installed plugin, and stops if Kimi Code still lists a session. Kimi Code's stream-json carries no usage, so after each session, also after a timeout, the agent copies the session's event logs and sums the usage recorded for each model request of every agent.
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
|
The only failing check, |
Which issue or RFC does this PR close?
Part of #1705. It adds Kimi Code to the paired OFF/ON comparison, after Bub (#1747), Codex (#1779), Claude Code (#1800), OpenCode (#1835), and Pi (#1851), with the OFF definition from #1816.
Rationale for this change
PowerContext now has a Kimi Code integration (#1964): a native plugin whose
UserPromptSubmithook prepares context and captures the prompt, plus HTTP MCP tools for Memory. Kimi Code can therefore run the same continuation workloads, grader, and evidence as the other plugin hosts. Harbor 0.16, which the harness pins, has no agent for it: itskimi-cliagent installs the earlier Python CLI (uv tool install kimi-cli), which has another home, configuration format, and plugin system. So this PR adds the harness's own agent. Harbor added a Kimi Code agent in a later release (harbor-framework/harbor#2403).What changes are included in this PR?
paired --host kimi-coderuns both arms withPowerContextKimiCodeAgent, a Harbor installed agent, andKimiCodeHost, aPluginHost.@moonshot-ai/kimi-code@2.1.1, the versions PowerContext's Kimi Code acceptance workflow tests, with--ignore-scriptsas that workflow does; the package's install script only renames a leftoverkimi-clilauncher. Each session runskimi -p <instruction> --output-format stream-json, which runs every tool without asking.KIMI_CODE_NO_AUTO_UPDATE=1keeps the version.config.toml: an OpenAI-compatible OpenRouter provider withapi_key_env = "OPENROUTER_API_KEY", so the key is never written to the file, the model fromPOWERCONTEXT_E2E_KIMI_CODE_MODELasopenrouter/<model>, and the reasoning effort as Kimi Code's thinking effort, which Kimi Code sends asreasoning_effort(checked against a local OpenAI-compatible endpoint). Telemetry and the extra model request that titles each session are off.POWERCONTEXT_*settings./pluginscommand, so the agent writes the managed copy and theplugins/installed.jsonentry thatpowercontext setup kimi-codewrites, configured with the arm's Scope. The container sees only the plugin'skimi.plugin.json,hooks,scripts,shared, andskills.POWERCONTEXT_KIMI_TOKENwithout the Bearer scheme.PluginHostgets an overridablecredential_environment, whichKimiCodeHostoverrides; the other hosts' settings are unchanged.POWERCONTEXT_KIMI_SERVER_URLthat is not an HTTP or HTTPS origin therefore fails the job before its container starts. For a plain-HTTP origin such ashttp://host-gateway:8000, the ON arm starts a Node TCP relay on127.0.0.1:47731in its container and gives the plugin that address. An HTTPS or loopback origin is used as it is.file-history), a search cache (cache/query-store), and logs under~/.kimi-code, and Harbor does not clear that between the steps of a trial. Before each session in both arms, the agent removes everything there exceptconfig.tomlandplugins/, then stops the arm ifkimi session list --all --archived --jsonstill lists a session.stream-jsonhas no token usage. Kimi Code records each model request once, in the event log of the agent that made it (agents/<agent>/wire.jsonl, subagents included). After each session, also after a timeout, the agent copies those logs into Harbor's agent logs and sums theusage.recordevents. Kimi Code reports no cost, so the report showsn/athere.Are there any user-facing changes?
paired --hostacceptskimi-code.How was this change tested?
Pilot runs
make harness-paired ARGS='--host kimi-code --id project-decision-continuation --trials 2'against a real Server, Harbor, Kimi Code, and model.Qwen 3.7 Flash
openrouter/qwen/qwen3.7-flash, the model of the latest Pi and OpenCode pilots (#2035), on this PR's code:null/null, reward 0OceanBase/12, reward 1null/null, reward 0OceanBase/12, reward 1Report: OFF 0/2 and ON 2/2, with 2 scored pairs and a mean ON minus OFF of +1.00. There were no errors, timeouts, or integration failures.
Treatment evidence (ON): after each capture session the Scope held 1 Source, the user prompt, and 1 Memory entry after the flush. During recall, context requests rose from 1 to 2 and ready preparations from 0 to 1, and both agents answered from the injected context without a tool call.
The plugin's MCP tools: an earlier run with the same settings gave the same result. In one of its ON recall sessions the context request returned nothing, and the agent found the decision by calling the plugin's
search_memorytool twice, in its own Scope.OFF behavior: the Harbor job configs have no mounts and an empty agent environment. Both OFF recall sessions searched the workspace with
GlobandReadand wrotenullfor both values. Neither OFF transcript contains a network command, the Server's address, or a path into Kimi Code's sessions.Token usage (mean per session, summed from Kimi Code's per-request usage records, cached tokens included):
In the capture sessions, where both arms do the same work, ON used 6% more input tokens, for the plugin's three MCP tools, its Skill, and the hook's messages. The ON recall sessions used fewer, because the agents answered from the injected context instead of searching the workspace.
Authentication: the Server ran with
POWERCONTEXT_SERVER_ACCESS_MODE=enforced, and the harness's unauthenticated check got 401. Every ON hook and MCP request succeeded through the relay. Neither the Server token, in full or its first or last characters, nor the OpenRouter key appears in the evidence; Harbor's job config holds only the${...}reference.Hook latency: on the Server, context requests took 0.24 to 0.29 s and captures 13 to 24 ms, inside the plugin's 1 s per-request budget.
Time: OFF arms took 49 to 53 s, and ON arms 68 to 73 s, including the harness's flush, which took 24 to 29 s on the Server.
Kimi K2.7 Code
The first pilot used Moonshot's
openrouter/moonshotai/kimi-k2.7-code:In one capture session of each arm, every request after the first tool call came back with reasoning only and no text or tool call (
APIEmptyResponseError). Kimi Code made 10 attempts over about 2.5 minutes and exited 1, and the harness counted the arm as an error. The other six sessions, and a separate run of a similar ON capture session, completed normally. One of the two failures was an OFF session, so they come from the model's responses rather than from PowerContext. The scored ON run answered after foursearch_memorycalls.Configuration of the runs
reasoning_effortmedium.06794f66, SQLite with the defaultcodingextraction profile and enforced access. Generation usedopenrouter:deepseek/deepseek-v4-pro, and embeddingsopenai/text-embedding-3-small(1536 dimensions) through OpenRouter's OpenAI-compatible endpoint, as in the Pi and OpenCode runs. The agent reached the Server athttp://host-gateway:8765through the relay.python:3.12-slim-bookwormimage.Container checks
Before the pilots, in throwaway containers:
install()andrun(), driven overdocker execinpython:3.12-slim-bookworm:plugins/directory, noPOWERCONTEXT_*variable, and nothing under/opt.config.tomlandplugins/, andkimi session list --all --archived --jsonprinted[].reasoning_effort: "medium"andmax_tokens: 131072.node:24-bookworm: a command that printed 60,000 lines left no file outside~/.kimi-code, and a request rejected for an invalid key madekimi -pexit 1 withprovider.auth_error.Checks
make check,make harness-check(271 tests), andmake unit-test(4,947 passed, 197 skipped) pass.POWERCONTEXT_KIMI_TOKEN. Kimi Code also joins the job-file token, missing-settings, and workload-answer mount tests.powercontext setup kimi-code'sinstall_kimi_pluginwrites, with and without a token, apart from timestamps and paths.loadSettingsaccepts the installed configuration: the relay address forhttp://host-gateway, the URL itself for HTTPS. A Server URL with a path, or with another scheme, fails the job.bashagainst a seeded Kimi Code home, for both arms: sessions, file history, the search cache, logs, and the plugin's observations are gone when the next session starts, while the configuration and plugin stay. A session does not start when Kimi Code still lists a session, or when the earlier step's tests cannot be removed.run(), with a stand-in Kimi Code that leaves event logs: usage sums each request of the main agent and a subagent once, ignoring the copy Kimi Code repeats on each message, also when the session exits with an error. It is unknown when no request was recorded.sessions/, writing the plain-HTTP Server URL instead of the relay, a fixeduse_token, copying the event logs from the wrong directory, an altered Scope in the Skill, and swapped relay arguments each fail a test.Limits
api-contractandrevised-decisionworkloads, MemoryCode, and SWE-bench Pro were not run on Kimi Code.search_memory. This is the Server's recall, the same for every host.127.0.0.1:47731, so a workload that needs that port would conflict. An HTTPS Server needs no relay.openrouter/<model>. Another provider needs an entry inPROVIDERS.powercontext setup kimi-codewrites. The comparison test runs inmake harness-check, so a change to setup fails the harness checks until the agent follows it.AI usage statement
This PR was developed with Claude Code (Claude Opus 5.5), which designed and wrote the change and tests, ran the checks, the container checks, and the pilots above, and analyzed the evidence. The author chose to add Kimi Code, approved the plan, reviewed the change, and provided the pilot environment.