Skip to content

feat(e2e): run paired continuation workloads with Kimi Code - #2038

Merged
hidb4ai merged 1 commit into
oceanbase:masterfrom
Fengzdadi:feat/e2e-kimi-code-paired
Oct 19, 2026
Merged

hidb4ai merged 1 commit into
oceanbase:masterfrom
Fengzdadi:feat/e2e-kimi-code-paired

Conversation

@Fengzdadi

Copy link
Copy Markdown
Contributor

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 UserPromptSubmit hook 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: its kimi-cli agent 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?

  • Kimi Code host: paired --host kimi-code runs both arms with PowerContextKimiCodeAgent, a Harbor installed agent, and KimiCodeHost, a PluginHost.
  • Install: the agent installs Node 24.21.0 and @moonshot-ai/kimi-code@2.1.1, the versions PowerContext's Kimi Code acceptance workflow tests, with --ignore-scripts as that workflow does; the package's install script only renames a leftover kimi-cli launcher. Each session runs kimi -p <instruction> --output-format stream-json, which runs every tool without asking. KIMI_CODE_NO_AUTO_UPDATE=1 keeps the version.
  • Model configuration: both arms get the same config.toml: an OpenAI-compatible OpenRouter provider with api_key_env = "OPENROUTER_API_KEY", so the key is never written to the file, the model from POWERCONTEXT_E2E_KIMI_CODE_MODEL as openrouter/<model>, and the reasoning effort as Kimi Code's thinking effort, which Kimi Code sends as reasoning_effort (checked against a local OpenAI-compatible endpoint). Telemetry and the extra model request that titles each session are off.
  • Arms:
    • OFF follows fix(e2e): keep PowerContext out of the OFF arm #1816: no plugin, no mounts, and no POWERCONTEXT_* settings.
    • ON: Kimi Code installs plugins only from its interactive /plugins command, so the agent writes the managed copy and the plugins/installed.json entry that powercontext setup kimi-code writes, configured with the arm's Scope. The container sees only the plugin's kimi.plugin.json, hooks, scripts, shared, and skills.
    • Token: the plugin's hook and Kimi Code's MCP connection read POWERCONTEXT_KIMI_TOKEN without the Bearer scheme. PluginHost gets an overridable credential_environment, which KimiCodeHost overrides; the other hosts' settings are unchanged.
    • Server address: the plugin takes the Server only as an origin and accepts plain HTTP only on loopback; otherwise it stays inactive. A POWERCONTEXT_KIMI_SERVER_URL that is not an HTTP or HTTPS origin therefore fails the job before its container starts. For a plain-HTTP origin such as http://host-gateway:8000, the ON arm starts a Node TCP relay on 127.0.0.1:47731 in its container and gives the plugin that address. An HTTPS or loopback origin is used as it is.
  • Kimi Code's own session data: Kimi Code keeps sessions, the files they edited (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 except config.toml and plugins/, then stops the arm if kimi session list --all --archived --json still lists a session.
  • Usage: Kimi Code's stream-json has 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 the usage.record events. Kimi Code reports no cost, so the report shows n/a there.
  • README: documents the arms, settings, relay, and run command.

Are there any user-facing changes?

  • paired --host accepts kimi-code.
  • Bub, Codex, Claude Code, OpenCode, and Pi runs are unchanged, and so are the acceptance command, its manifests, and its CI.

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:

Trial Order OFF recall ON recall
1 OFF, ON null / null, reward 0 OceanBase / 12, reward 1
2 ON, OFF null / null, reward 0 OceanBase / 12, reward 1
  • Report: 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_memory tool 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 Glob and Read and wrote null for 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):

    Session OFF input tokens ON input tokens OFF output tokens ON output tokens
    Capture 61,203 64,932 208 197
    Recall 72,006 43,582 523 213

    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:

Trial Order OFF ON
1 OFF, ON reward 0 error in capture
2 ON, OFF error in capture reward 1

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 four search_memory calls.

Configuration of the runs

  • Agent: Harbor 0.16.1, Kimi Code 2.1.1 on Node 24.21.0, reasoning_effort medium.
  • Server: local, on upstream 06794f66, SQLite with the default coding extraction profile and enforced access. Generation used openrouter:deepseek/deepseek-v4-pro, and embeddings openai/text-embedding-3-small (1536 dimensions) through OpenRouter's OpenAI-compatible endpoint, as in the Pi and OpenCode runs. The agent reached the Server at http://host-gateway:8765 through the relay.
  • Runtime: OrbStack on macOS, with the task's python:3.12-slim-bookworm image.

Container checks

Before the pilots, in throwaway containers:

  • The agent's own install() and run(), driven over docker exec in python:3.12-slim-bookworm:
    • ON: the hook resolved the Scope and captured the prompt. In a fresh session after a flush it injected the decision, which the model repeated. The plugin's three MCP tools were listed and worked through the relay with the token.
    • OFF: no plugins/ directory, no POWERCONTEXT_* variable, and nothing under /opt.
    • Between sessions, the clear left only config.toml and plugins/, and kimi session list --all --archived --json printed [].
    • A session stopped by a 12 s timeout still had its usage copied and summed.
    • With the generated configuration pointed at a local OpenAI-compatible endpoint, Kimi Code's request carried reasoning_effort: "medium" and max_tokens: 131072.
  • Kimi Code 2.1.1 itself, in node:24-bookworm: a command that printed 60,000 lines left no file outside ~/.kimi-code, and a request rejected for an invalid key made kimi -p exit 1 with provider.auth_error.

Checks

  • make check, make harness-check (271 tests), and make unit-test (4,947 passed, 197 skipped) pass.
  • New and generalized tests:
    • The plugin-host tests now include Kimi Code: OFF has no mounts or environment, and ON gets the mounts, the Scope, and the raw token in POWERCONTEXT_KIMI_TOKEN. Kimi Code also joins the job-file token, missing-settings, and workload-answer mount tests.
    • The ON installation, run with Node from the files the container mounts, equals what powercontext setup kimi-code's install_kimi_plugin writes, with and without a token, apart from timestamps and paths.
    • The plugin's own loadSettings accepts the installed configuration: the relay address for http://host-gateway, the URL itself for HTTPS. A Server URL with a path, or with another scheme, fails the job.
    • The relay, run with Node in front of a local HTTP server, returns a 300 KB request body whole.
    • The session clear runs in a real bash against 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.
    • Through 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.
    • Both arms run the same install commands, and ON adds only the plugin's.
    • Mutation checks: keeping sessions/, writing the plain-HTTP Server URL instead of the relay, a fixed use_token, copying the event logs from the wrong directory, an altered Scope in the Skill, and swapped relay arguments each fail a test.

Limits

  • Pilot scope: one task and two trials per arm for each model validate the pipeline and its evidence; they do not measure PowerContext's effect. The api-contract and revised-decision workloads, MemoryCode, and SWE-bench Pro were not run on Kimi Code.
  • Kimi K2.7 Code through OpenRouter: 2 of its 8 sessions failed as described above. Runs with that model should expect such errors, which the report leaves out.
  • Context for this recall prompt: the Server's context request often returns nothing for this task's recall prompt. It did in 3 of the 6 ON recall sessions of the runs here, and in 3 of the 4 Pi and OpenCode ON recall sessions of the feat(e2e): leave out ON runs that reached another trial's Scope #2035 pilots on the same Server version. ON then depends on the model calling search_memory. This is the Server's recall, the same for every host.
  • Hook budget: the plugin gives each Server request 1 s and the whole hook 4 s. With the embedding provider here, context requests in the Qwen runs took at most 0.3 s; a slower provider makes the hook skip context or capture.
  • Relay port: in the ON arm the relay holds 127.0.0.1:47731, so a workload that needs that port would conflict. An HTTPS Server needs no relay.
  • One provider: the agent configures only OpenRouter models, named openrouter/<model>. Another provider needs an entry in PROVIDERS.
  • Copied setup: the agent repeats what powercontext setup kimi-code writes. The comparison test runs in make harness-check, so a change to setup fails the harness checks until the agent follows it.
  • What the plugin captures: like the other plugin hosts, it captures only user prompts.
  • Harbor version: the agent is written for Harbor 0.16, which the harness pins. Moving the harness to a Harbor with its own Kimi Code agent is a separate change for every host.
  • Not run: the fixed Compose harness, Docker on Linux, and other models and providers. CI does not run Kimi Code through Harbor.

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.

`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.
Copilot AI balanced review requested due to automatic review settings October 17, 2026 06:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Fengzdadi

Copy link
Copy Markdown
Contributor Author

The only failing check, tests (3.11, unit), is test_flush_persists_copied_usage_with_unknown_tokens_and_original_date[False] in tests/builtin/runtime/test_model_usage_recorder.py: the recorder's flush timed out ("Model usage flush timed out; continuing without statistics"), so no row was written. This PR changes only e2e/bub; the same test passes on 3.12, 3.13, and 3.14 in this run and 5 times out of 5 locally. Could a maintainer rerun the failed job?

@AlexStocks AlexStocks added the 1.4.1 v1.4.1 release tracking label Oct 17, 2026

@hireview001 hireview001 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@hidb4ai hidb4ai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@hidb4ai
hidb4ai merged commit b388a18 into oceanbase:master Oct 19, 2026
58 of 59 checks passed
hidb4ai pushed a commit that referenced this pull request Oct 20, 2026
…2090)

#2043 added a __POWERCONTEXT_SCOPE_SCRIPT_JSON__ placeholder to the Kimi
Code skill that setup replaces with the installed scope.mjs path. The ON
arm's installer, added in #2038, only filled the Scope placeholder, so its
guidance kept the raw marker and no longer matched setup.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1.4.1 v1.4.1 release tracking

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants