Skip to content

feat: support for Moonshot LLMs (Kimi 2.5 etc)#6962

Closed
stebbins wants to merge 1 commit intoblock:mainfrom
stebbins:feat/moonshot
Closed

feat: support for Moonshot LLMs (Kimi 2.5 etc)#6962
stebbins wants to merge 1 commit intoblock:mainfrom
stebbins:feat/moonshot

Conversation

@stebbins
Copy link
Contributor

@stebbins stebbins commented Feb 4, 2026

Summary

Type of Change

  • Feature
  • Bug fix
  • Refactor / Code quality
  • Performance improvement
  • Documentation
  • Tests
  • Security fix
  • Build / Release
  • Other (specify below)

AI Assistance

  • This PR was created or reviewed with AI assistance

Testing

  • CI tests
  • manual build and testing with Moonshot providers
  • NOTE: I do not have OpenAI access, so cannot directly manually "regression" test OpenAI

Related Issues

Closes #6902

Screenshots/Demos (for UX changes)

Before:

image

After:

image

@Tyler-Hardin
Copy link
Contributor

Have you tested a longer session? I rebased your PR onto main and it seems to fail with the same error after multiple turns.

$ ./target/release/goose
starting session | provider: custom_kimi model: kimi-k2.5
    session id: 20260210_7
    working directory: /x/qscratch/tyler/goose

goose is running! Enter your instructions, or try asking what goose can do.

Context: ○○○○○○○○○○ 0% (0/131072 tokens)
( O)> Write me an install.sh script that runs cargo build --release and, if it succeeds, copies ./target/release/goose to /export/mana/bin, but first creates a hardlink of the existing copy to a file in the same dir called goose.bk.$(date %Y%m%d.%H%M%S). not sure if my directions will actually achieve what i want -- i want to backup the original without modifying the timestamps. i kinda prefer this hardlink method because it seems more atomic. if we mv the original file first, for a split second there will be no goose installed. but if hardlink causes the backup to accidentally be overwritten, then use mv instead.

you attempted this previously. look at what's currently there in install.sh and tell me if you think it's good to use

─── text_editor | developer ──────────────────────────
path: /x/qscratch/tyler/goose/install.sh
command: view

Looking at the current `install.sh`, here's my assessment:

## What's Good

The script is **well-designed and safe to use**. It actually implements a **better** approach than your original description:

| Your Request | What the Script Does | Assessment |
|-------------|---------------------|------------|
| Hardlink existing, then copy new | Copy new to temp → hardlink existing → atomic mv | ✅ **Better** - The `mv` is truly atomic; your approach would have a window where the file is being copied |
| `goose.bk.$(date %Y%m%d.%H%M%S)` | `goose.bk.$(date +%Y%m%d.%H%M%S)` | ✅ Correct (the `+` is required for `date` command) |
| Fallback to mv if hardlink fails | Catches `ln` failure with `2>/dev/null` and falls back | ✅ Implemented |
| Atomic operation | Uses temp file + atomic `mv` | ✅ Yes - at no point is there no `goose` binary |

## Potential Issue

The backup could be overwritten if you run multiple installs within the same second (same timestamp). To fix this:
─── text_editor | developer ──────────────────────────
path: /x/qscratch/tyler/goose/install.sh
command: str_replace
old_str:     BACKUP="$DEST_DIR/goose.bk.$(date +%Y%m%d.%H%M%S)"
new_str:     BACKUP="$DEST_DIR/goose.bk.$(date +%Y%m%d.%H%M%S).$$"

Ran into this error: Request failed: Bad request (400): thinking is enabled but reasoning_content is missing in assistant tool call message at index 5.

Please retry if you think this is a transient or recoverable error.

⏱️  Elapsed time: 34.95s
Context: ●○○○○○○○○○ 5% (7171/131072 tokens)

@Tyler-Hardin
Copy link
Contributor

My guess is that moonshot might not be echoing back the full reasoning chain. They may only send you back the most recent one. Would be hypocritical of them, but would also explain the error. Idk tho, didn't look deeply.

@stebbins
Copy link
Contributor Author

@Tyler-Hardin thank you for testing, i will take a look

@stebbins stebbins marked this pull request as draft February 11, 2026 02:42
@Tyler-Hardin
Copy link
Contributor

Thanks for all your work on this. It was already working well for me before your last commit. (Not to suggest the last commit was unneeded, just that the last edge case you fixed wasn't something I had encountered yet.)

@Tyler-Hardin
Copy link
Contributor

By the way, fun fact, there's a bug introduced by 2bc3689 that causes text_editor view to return nothing. I thought it might be a bug in your patch but it's actually in main, predating your changes.

@stebbins stebbins force-pushed the feat/moonshot branch 2 times, most recently from 9674e79 to 919d9ca Compare February 12, 2026 01:48
@stebbins
Copy link
Contributor Author

@Tyler-Hardin cheers and thanks for the heads up. I've been running into more "edge cases" where the reasoning context is lost so trying a few different approaches

… models

Add declarative Moonshot AI provider (moonshot.json) for direct API access
to Kimi models via MOONSHOT_API_KEY.

Fix reasoning_content handling for thinking models (Kimi, DeepSeek, etc.):
- Preserve reasoning content on split tool-call messages in agent.rs
  (Goose splits parallel tool calls into separate messages, which was
  dropping reasoning_content that providers like Kimi require)
- Only include reasoning_content field when non-empty (Kimi rejects
  empty string "")
- Accumulate reasoning_content during streaming tool call processing
- Concatenate multiple reasoning blocks instead of overwriting
- Wire request_params into create_request() for thinking mode activation

Update Kimi model context limits to 262K (131K for older k2-0711).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Harrison <hcstebbins@gmail.com>
@stebbins stebbins marked this pull request as ready for review February 14, 2026 01:49
@stebbins
Copy link
Contributor Author

@Tyler-Hardin I think we're good!

Copy link
Collaborator

@DOsinga DOsinga left a comment

Choose a reason for hiding this comment

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

I think this looks good, but would be good to make sure it still works with like deepseek

// Include reasoning_content only when non-empty.
// Kimi rejects empty reasoning_content (""), so we must omit it entirely
// when there's no reasoning to send.
if !reasoning_text.is_empty() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

you are removing the existing comment here, which makes me slightly worried - is this now compatible with both Kimi & Deepseek?

DOsinga pushed a commit that referenced this pull request Feb 18, 2026
Add support for Moonshot AI (Kimi) models:
- moonshot.json: kimi-latest, kimi-thinking-preview, kimi-k2-0711, kimi-k2, moonshot-v1-8k, moonshot-v1-32k
- kimi.json: kimi-for-coding, kimi-code (coding-optimized models)

Both providers use the Moonshot API (api.moonshot.cn) with MOONSHOT_API_KEY.

Combines work from PRs #6962 and #7222.
@DOsinga
Copy link
Collaborator

DOsinga commented Feb 18, 2026

ok, I merged the other one, I think we can close this now. let me know if not. and thanks for the contribution @stebbins

@DOsinga DOsinga closed this Feb 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Kimi k2.5 API Error: "thinking is enabled but reasoning_content is missing" in tool calls

3 participants

Comments