# Kimi → OpenDesign routing fix for `t_9b61fb08`

## Verdict

Use Kimi through the `moying` Hermes profile config. Do not switch this path to GPT.

OpenDesign's current Hermes run surface does **not** expose `provider`, `model`, and `api_mode` as separate request fields. It exposes only `model`; provider and API mode must be resolved by the Hermes profile started inside OpenDesign.

## Required Hermes profile config

Verified target profile: `/root/.hermes/profiles/moying/config.yaml`

```yaml
model:
  default: kimi-k2.7
  provider: custom:kimi-code
  base_url: https://api.kimi.com/coding

custom_providers:
  - name: kimi-code
    base_url: https://api.kimi.com/coding
    model: kimi-k2.7
    key_env: KIMI_CODING_API_KEY
    api_mode: anthropic_messages
    api_key: ''
```

Credential source:

```text
/root/.hermes/profiles/moying/.env
KIMI_CODING_API_KEY=***
```

## Exact OpenDesign invocation contract

Start the native OpenDesign daemon with the `moying` Hermes profile visible:

```bash
export PATH=/root/.local/bin:/root/.local/node/node-v24.16.0-linux-x64/bin:$PATH
export HERMES_PROFILE=moying
cd /root/projects/open-design-native/open-design
pnpm exec od --host 127.0.0.1 --port 7466 --no-open
```

Then start the run with Hermes as the inner agent and only the Kimi model id:

```bash
export PATH=/root/.local/bin:/root/.local/node/node-v24.16.0-linux-x64/bin:$PATH
export HERMES_PROFILE=moying
cd /root/projects/open-design-native/open-design
pnpm exec od run start \
  --daemon-url http://127.0.0.1:7466 \
  --project <opendesign-project-id> \
  --agent hermes \
  --model kimi-k2.7 \
  --skill frontend-design \
  --plugin example-web-prototype \
  --prompt-file /path/to/brief.md \
  --json
```

Equivalent raw API body:

```json
{
  "projectId": "<opendesign-project-id>",
  "agentId": "hermes",
  "model": "kimi-k2.7",
  "skillId": "frontend-design",
  "pluginId": "example-web-prototype",
  "message": "<brief text>",
  "pluginInputs": {
    "artifactKind": "responsive web prototype",
    "fidelity": "high-fidelity",
    "designSystem": "Warm Editorial"
  }
}
```

Important: `--model kimi-k2.7` is safe only because `HERMES_PROFILE=moying` resolves the provider to `custom:kimi-code` and `api_mode` to `anthropic_messages`.

## Does OpenDesign support provider/model as separate fields?

No, not in the current checked source.

Evidence:

- `apps/daemon/src/mcp.ts:startRun()` copies only `args.model` to `body.model`; there is no `provider` or `api_mode` field.
- `apps/daemon/src/cli.ts:od run start` copies only `--model` to `body.model`; there is no `--provider` or `--api-mode` flag.
- `apps/daemon/src/server.ts:/api/runs` receives and stores `model`, then starts the selected agent; provider resolution is delegated to the agent runtime.
- Hermes ACP can resolve model/provider internally, but OpenDesign only has one `model` string to send through ACP.

## Minimal wrapper/task-body workaround

Preferred minimal workaround:

1. Keep `/root/.hermes/profiles/moying/config.yaml` as above.
2. Ensure the OpenDesign daemon is started with `HERMES_PROFILE=moying`.
3. In the OpenDesign task/run body, pass:

```json
{
  "agentId": "hermes",
  "model": "kimi-k2.7"
}
```

Do **not** pass GPT models. Do **not** use `openai-codex:gpt-5.5` for this task.

Avoid this fragile selector in OpenDesign task bodies:

```text
custom:kimi-code:kimi-k2.7
```

Hermes' own parser can understand that triple, but OpenDesign currently treats the run model as a single opaque model field. In this failure path the safer contract is: provider/api_mode from the profile, model id from the run.

If the daemon may be started from a different environment, add a local OpenDesign agent profile instead of changing every task body:

```json
{
  "agents": [
    {
      "id": "hermes-kimi",
      "name": "Hermes Kimi via moying",
      "baseAgent": "hermes",
      "args": ["--profile", "moying"],
      "env": { "HERMES_PROFILE": "moying" },
      "models": [{ "id": "kimi-k2.7", "label": "kimi-k2.7" }],
      "defaultModel": "kimi-k2.7"
    }
  ]
}
```

Save as:

```text
/root/.open-design/agents.local.json
```

Then run OpenDesign with:

```bash
pnpm exec od run start \
  --daemon-url http://127.0.0.1:7466 \
  --project <opendesign-project-id> \
  --agent hermes-kimi \
  --model kimi-k2.7 \
  --prompt-file /path/to/brief.md \
  --json
```

## Smoke test result — Kimi, not GPT

Direct Kimi For Coding Messages API smoke:

```text
endpoint: POST https://api.kimi.com/coding/v1/messages
model: kimi-k2.7
user-agent: KimiCLI/1.30.0
key: KIMI_CODING_API_KEY from /root/.hermes/profiles/moying/.env
result: HTTP 200
response_model: kimi-k2.7
content_text: OK
```

Hermes runtime evidence from the `moying` profile:

```text
/root/.hermes/profiles/moying/logs/agent.log
API call entries show: model=kimi-k2.7 provider=custom
```

Note: a nested `hermes --profile moying chat ...` CLI smoke was not used as the final success signal because this Kanban worker environment leaked the current Kanban task context into the nested Hermes process, causing the nested process to start working the board instead of returning a one-line CLI answer. The provider routing itself was still Kimi/custom in the logs; the clean smoke above is the direct Kimi API result.

## Exact instruction to unblock `t_9b61fb08`

Unblock `t_9b61fb08` with this instruction:

```text
UNBLOCK: rerun OpenDesign with Kimi only. Start/use native OpenDesign daemon with HERMES_PROFILE=moying. Run agentId=hermes, model=kimi-k2.7. Do not use GPT and do not pass openai-codex:gpt-5.5. Do not use custom:kimi-code:kimi-k2.7 in the OpenDesign task body unless the wrapper has been upgraded to split provider/model/api_mode fields. Provider/api_mode must come from moying config: provider=custom:kimi-code, api_mode=anthropic_messages, base_url=https://api.kimi.com/coding, key_env=KIMI_CODING_API_KEY. If Kimi fails again, block with the exact HTTP/status/log path instead of falling back to GPT.
```

## Durable doc fix applied

Updated the `site-design` skill reference `references/open-design-hermes-mcp-poc.md` to remove the stale `custom:kimi-code:kimi-k2.7` recommendation and replace it with the profile-backed `model=kimi-k2.7` contract above.
