Merge origin/master (v0.5.75) into gitea/new_feature

Resolve conflicts:
- package.json / cli/package.json: take 0.5.75
- .gitignore: union both sides (upstream 9router-*/temp files + local state dirs)
- CHANGELOG.md: keep both blocks, v0.5.75 above v0.5.70
- nonStreamingHandler.js: merge imports (unwrapClineEnvelope +
  tokensForDetail/shouldPersistRequestDetail); drop dead appendRequestLog
- providers/[id]/page.js: union useState blocks (compatible-model states
  + importingClineModels)

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
2026-09-17 14:14:43 +07:00
113 changed files with 6634 additions and 482 deletions

View File

@@ -0,0 +1,33 @@
// Regression for #3905: defaultClaudeToolType() (type:"custom") must only run for
// gateways that declare the requireClaudeToolType quirk (MiniMax). Claude-format
// endpoints that only accept the legacy typeless tool shape — e.g. DeepSeek's
// Anthropic-compatible endpoint, which answers HTTP 400 "unknown variant `custom`" —
// must never receive tools[].type = "custom".
import { describe, it, expect } from "vitest";
import { PROVIDERS } from "../../open-sse/providers/index.js";
import { FORMATS } from "../../open-sse/translator/formats.js";
import { shouldDefaultClaudeToolType } from "../../open-sse/translator/concerns/toolCall.js";
const tools = [{ name: "get_weather", description: "weather", input_schema: { type: "object" } }];
describe("Claude tool `type` defaulting is provider-scoped (#3905)", () => {
it("runs only for providers declaring requireClaudeToolType", () => {
expect(shouldDefaultClaudeToolType("minimax", FORMATS.CLAUDE, tools, PROVIDERS)).toBe(true);
expect(shouldDefaultClaudeToolType("minimax-cn", FORMATS.CLAUDE, tools, PROVIDERS)).toBe(true);
// Endpoints accepting only the legacy typeless shape must NOT get type:"custom".
expect(shouldDefaultClaudeToolType("deepseek", FORMATS.CLAUDE, tools, PROVIDERS)).toBe(false);
expect(shouldDefaultClaudeToolType("claude", FORMATS.CLAUDE, tools, PROVIDERS)).toBe(false);
});
it("never applies outside Claude-format requests or without tools", () => {
expect(shouldDefaultClaudeToolType("minimax", FORMATS.OPENAI, tools, PROVIDERS)).toBe(false);
expect(shouldDefaultClaudeToolType("minimax", FORMATS.CLAUDE, undefined, PROVIDERS)).toBe(false);
expect(shouldDefaultClaudeToolType("minimax", FORMATS.CLAUDE, null, PROVIDERS)).toBe(false);
});
it("declares the quirk only on the MiniMax providers (registry tripwire)", () => {
expect(PROVIDERS.minimax?.quirks?.requireClaudeToolType).toBe(true);
expect(PROVIDERS["minimax-cn"]?.quirks?.requireClaudeToolType).toBe(true);
expect(PROVIDERS.deepseek?.quirks?.requireClaudeToolType).toBeUndefined();
});
});

View File

@@ -26,9 +26,8 @@ describe("Claude → Kiro (direct route)", () => {
expect(first.conversationState.conversationId).toBe("hermes-session-123-claude-replay");
expect(second.conversationState.conversationId).toBe("hermes-session-123-claude-replay");
expect(first.conversationState.agentContinuationId).toBeTruthy();
expect(second.conversationState.agentContinuationId).toBe(first.conversationState.agentContinuationId);
expect(first.conversationState.agentTaskType).toBe("vibe");
expect(first.conversationState).not.toHaveProperty("agentContinuationId");
expect(second.conversationState).not.toHaveProperty("agentTaskType");
expect(second.conversationState.history[0].userInputMessage.content).toBe(
first.conversationState.currentMessage.userInputMessage.content
);
@@ -84,7 +83,7 @@ describe("Claude → Kiro (direct route)", () => {
expect(out.systemPrompt).toContain(
"<thinking_mode>enabled</thinking_mode>"
);
expect(out.agentMode).toBe("vibe");
expect(out).not.toHaveProperty("agentMode");
});
it("does not send additionalModelRequestFields for Kiro models without effort support", () => {