Skip to content

Commit 35eeb54

Browse files
authored
Merge branch 'main' into beatlevic/fetch-openrouter-models-for-org
2 parents d5a5bab + af6d0a0 commit 35eeb54

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1033
-209
lines changed

.changeset/angry-fans-mix.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/giant-eyes-approve.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/good-chicken-yell.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/shaggy-mails-study.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/unlucky-knives-cheer.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
# kilo-code
22

3+
## [v4.84.0]
4+
5+
- [#1961](https://github.com/Kilo-Org/kilocode/pull/1961) [`d4a7cb6`](https://github.com/Kilo-Org/kilocode/commit/d4a7cb6300d8e00d5889e1079057e43de19ff95e) Thanks [@chrarnoldus](https://github.com/chrarnoldus)! - Updates to the experimental Morph FastApply support
6+
7+
- A visual indication is now included in the task view whenever Morph is used.
8+
- The traditional file editing tools are now disabled to ensure Morph is used to edit files.
9+
- Morph is now automatically disabled when the API provider does not support it and no Morph API key is configured.
10+
- The Morph API key is no longer lost when switching provider profiles.
11+
12+
- [#1886](https://github.com/Kilo-Org/kilocode/pull/1886) [`0221aaa`](https://github.com/Kilo-Org/kilocode/commit/0221aaa4febea9dfeea8cfbb26fa355204e75d1b) Thanks [@mcowger](https://github.com/mcowger)! - Add collapsible MCP tool calls with memory management
13+
14+
### Patch Changes
15+
16+
- [#2095](https://github.com/Kilo-Org/kilocode/pull/2095) [`8623bb8`](https://github.com/Kilo-Org/kilocode/commit/8623bb8516a7453d299512bd11c5000f43ecb952) Thanks [@chrarnoldus](https://github.com/chrarnoldus)! - Kilo Code provider now falls back to the default model when the selected model no longer exists
17+
18+
- [#2090](https://github.com/Kilo-Org/kilocode/pull/2090) [`fd147b8`](https://github.com/Kilo-Org/kilocode/commit/fd147b8ed35c8963ec66c5fae89f37829529574f) Thanks [@Mats4k](https://github.com/Mats4k)! - Improvements to German language translation
19+
20+
- [#2030](https://github.com/Kilo-Org/kilocode/pull/2030) [`11e8c7d`](https://github.com/Kilo-Org/kilocode/commit/11e8c7dda9f03b769e22f233b5ea487c9a12bd66) Thanks [@ivanarifin](https://github.com/ivanarifin)! - Show message when Virtual Quota Fallback Provider switches profiles
21+
22+
- [#2100](https://github.com/Kilo-Org/kilocode/pull/2100) [`5ed3d7b`](https://github.com/Kilo-Org/kilocode/commit/5ed3d7be3273fef7ff0eeede8db064fc9bdb4fe0) Thanks [@RSO](https://github.com/RSO)! - Changed the API domain for the Kilo Code provider
23+
24+
- [#1964](https://github.com/Kilo-Org/kilocode/pull/1964) [`6b0dfbf`](https://github.com/Kilo-Org/kilocode/commit/6b0dfbf10a397063f02e0dd6964d1fb1b773cf12) Thanks [@chrarnoldus](https://github.com/chrarnoldus)! - The Kilo Code API Provider settings now also shows the average cost per request in addition to the average cost per million tokens for a particular model.
25+
326
## [v4.83.1]
427

528
- [#2073](https://github.com/Kilo-Org/kilocode/pull/2073) [`a4b8770`](https://github.com/Kilo-Org/kilocode/commit/a4b8770ba82cbb366bb986a36026b6860129f799) Thanks [@chrarnoldus](https://github.com/chrarnoldus)! - Ensured free model usage is reported as free
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import type { Meta, StoryObj } from "@storybook/react-vite"
2+
import { fn } from "storybook/test"
3+
4+
import { McpExecution } from "../../../webview-ui/src/components/chat/McpExecution"
5+
import { withTooltipProvider } from "../src/decorators/withTooltipProvider"
6+
7+
const meta = {
8+
title: "Chat/Row/McpExecution",
9+
component: McpExecution,
10+
parameters: { layout: "padded" },
11+
} satisfies Meta<typeof McpExecution>
12+
13+
export default meta
14+
type Story = StoryObj<typeof meta>
15+
16+
// Mock server configuration
17+
const mockServer = {
18+
tools: [
19+
{
20+
name: "get_weather",
21+
description: "Get current weather information for a location",
22+
alwaysAllow: false,
23+
},
24+
{
25+
name: "search_files",
26+
description: "Search for files in the project directory",
27+
alwaysAllow: true,
28+
},
29+
],
30+
source: "global" as const,
31+
}
32+
33+
// Sample JSON arguments
34+
const jsonArguments = JSON.stringify(
35+
{
36+
location: "San Francisco, CA",
37+
units: "metric",
38+
include_forecast: true,
39+
},
40+
null,
41+
2,
42+
)
43+
44+
// Sample JSON response
45+
const jsonResponse = JSON.stringify(
46+
{
47+
location: "San Francisco, CA",
48+
temperature: 18,
49+
humidity: 65,
50+
conditions: "Partly cloudy",
51+
forecast: [
52+
{ day: "Tomorrow", high: 20, low: 15, conditions: "Sunny" },
53+
{ day: "Tuesday", high: 19, low: 14, conditions: "Cloudy" },
54+
],
55+
},
56+
null,
57+
2,
58+
)
59+
60+
export const CompletedWithJsonResponse: Story = {
61+
name: "Completed - JSON Response",
62+
args: {
63+
executionId: "exec-003",
64+
text: jsonArguments,
65+
serverName: "weather-server",
66+
useMcpServer: {
67+
type: "use_mcp_tool",
68+
serverName: "weather-server",
69+
toolName: "get_weather",
70+
arguments: jsonArguments,
71+
response: jsonResponse,
72+
},
73+
server: mockServer,
74+
alwaysAllowMcp: false,
75+
initiallyExpanded: true,
76+
},
77+
}
78+
79+
export const CompletedWithMarkdownResponse: Story = {
80+
name: "Completed - Markdown Response",
81+
args: {
82+
executionId: "exec-004",
83+
text: jsonArguments,
84+
serverName: "weather-server",
85+
useMcpServer: {
86+
type: "use_mcp_tool",
87+
serverName: "weather-server",
88+
toolName: "get_weather",
89+
arguments: jsonArguments,
90+
response: `# Weather Report
91+
92+
**Location:** San Francisco, CA
93+
**Temperature:** 18°C
94+
**Humidity:** 65%
95+
**Conditions:** Partly cloudy
96+
97+
## 3-Day Forecast
98+
99+
- **Tomorrow:** Sunny, High: 20°C, Low: 15°C
100+
- **Tuesday:** Cloudy, High: 19°C, Low: 14°C
101+
- **Wednesday:** Rain, High: 17°C, Low: 12°C`,
102+
},
103+
server: mockServer,
104+
alwaysAllowMcp: false,
105+
initiallyExpanded: true,
106+
},
107+
}
108+
109+
export const RunningState: Story = {
110+
name: "Running State",
111+
args: {
112+
executionId: "exec-005",
113+
text: jsonArguments,
114+
serverName: "weather-server",
115+
useMcpServer: {
116+
type: "use_mcp_tool",
117+
serverName: "weather-server",
118+
toolName: "get_weather",
119+
arguments: jsonArguments,
120+
},
121+
server: mockServer,
122+
alwaysAllowMcp: false,
123+
},
124+
play: async ({ canvasElement }) => {
125+
// Simulate a running execution by dispatching a status message
126+
window.dispatchEvent(
127+
new MessageEvent("message", {
128+
data: {
129+
type: "mcpExecutionStatus",
130+
text: JSON.stringify({
131+
executionId: "exec-005",
132+
status: "started",
133+
serverName: "weather-server",
134+
toolName: "get_weather",
135+
}),
136+
},
137+
}),
138+
)
139+
},
140+
}
141+
142+
export const ErrorState: Story = {
143+
name: "Error State",
144+
args: {
145+
executionId: "exec-006",
146+
text: jsonArguments,
147+
serverName: "weather-server",
148+
useMcpServer: {
149+
type: "use_mcp_tool",
150+
serverName: "weather-server",
151+
toolName: "get_weather",
152+
arguments: jsonArguments,
153+
},
154+
server: mockServer,
155+
alwaysAllowMcp: false,
156+
},
157+
play: async ({ canvasElement }) => {
158+
// Simulate an error state
159+
window.dispatchEvent(
160+
new MessageEvent("message", {
161+
data: {
162+
type: "mcpExecutionStatus",
163+
text: JSON.stringify({
164+
executionId: "exec-006",
165+
status: "error",
166+
error: "Connection timeout to weather service",
167+
}),
168+
},
169+
}),
170+
)
171+
},
172+
}

packages/types/src/global-settings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ export const globalSettingsSchema = z.object({
133133
fuzzyMatchThreshold: z.number().optional(),
134134
experiments: experimentsSchema.optional(),
135135

136+
morphApiKey: z.string().optional(), // kilocode_change: Morph fast apply
137+
136138
codebaseIndexModels: codebaseIndexModelsSchema.optional(),
137139
codebaseIndexConfig: codebaseIndexConfigSchema.optional(),
138140

packages/types/src/provider-settings.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ const baseProviderSettingsSchema = z.object({
9595
modelMaxTokens: z.number().optional(),
9696
modelMaxThinkingTokens: z.number().optional(),
9797

98-
morphApiKey: z.string().optional(), // kilocode_change: Morph fast apply
99-
10098
// Model verbosity.
10199
verbosity: verbosityLevelsSchema.optional(),
102100
})
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// npx vitest run api/providers/__tests__/fetch-with-timeout.spec.ts
2+
3+
import { vi, describe, it, expect, beforeEach } from "vitest"
4+
5+
// Declare hoisted mocks to be safely referenced inside vi.mock factory
6+
const hoisted = vi.hoisted(() => {
7+
return {
8+
mockFetch: vi.fn(),
9+
mockAgentConstructor: vi.fn(),
10+
agentInstances: [] as any[],
11+
}
12+
})
13+
14+
// Mock the undici module used by the implementation
15+
vi.mock("undici", () => {
16+
return {
17+
Agent: vi.fn().mockImplementation((opts: any) => {
18+
hoisted.mockAgentConstructor(opts)
19+
const instance = { __mock: "Agent" }
20+
hoisted.agentInstances.push(instance)
21+
return instance
22+
}),
23+
fetch: hoisted.mockFetch,
24+
}
25+
})
26+
27+
// Import after mocking so the implementation picks up our mocks
28+
import { fetchWithTimeout } from "../kilocode/fetchWithTimeout"
29+
30+
describe("fetchWithTimeout - header precedence and timeout wiring", () => {
31+
beforeEach(() => {
32+
vi.clearAllMocks()
33+
hoisted.agentInstances.length = 0
34+
})
35+
36+
it("should prefer persistent headers over request-specific headers (application/json overrides text/plain)", async () => {
37+
hoisted.mockFetch.mockResolvedValueOnce({ ok: true } as any)
38+
39+
const timeoutMs = 5_000
40+
const f = fetchWithTimeout(timeoutMs, {
41+
"Content-Type": "application/json",
42+
"X-Test": "A",
43+
})
44+
45+
await f("http://example.com", {
46+
method: "POST",
47+
headers: {
48+
"Content-Type": "text/plain",
49+
"X-Test": "B",
50+
},
51+
body: '{"x":1}',
52+
})
53+
54+
// Agent constructed with correct timeouts
55+
expect(hoisted.mockAgentConstructor).toHaveBeenCalledWith({
56+
headersTimeout: timeoutMs,
57+
bodyTimeout: timeoutMs,
58+
})
59+
60+
// Fetch called with merged headers where persistent wins
61+
expect(hoisted.mockFetch).toHaveBeenCalledTimes(1)
62+
const [url, init] = hoisted.mockFetch.mock.calls[0]
63+
expect(url).toBe("http://example.com")
64+
65+
// Dispatcher is the agent instance we created
66+
expect(init.dispatcher).toBe(hoisted.agentInstances[0])
67+
68+
// Persistent headers must override request-specific ones
69+
expect(init.headers).toEqual(
70+
expect.objectContaining({
71+
"Content-Type": "application/json",
72+
"X-Test": "A",
73+
}),
74+
)
75+
})
76+
77+
it("should apply persistent application/json when request-specific Content-Type is omitted (prevents defaulting to text/plain)", async () => {
78+
hoisted.mockFetch.mockResolvedValueOnce({ ok: true } as any)
79+
80+
const f = fetchWithTimeout(10_000, {
81+
"Content-Type": "application/json",
82+
})
83+
84+
await f("http://example.com", {
85+
method: "POST",
86+
body: '{"x":1}',
87+
})
88+
89+
expect(hoisted.mockFetch).toHaveBeenCalledTimes(1)
90+
const [, init] = hoisted.mockFetch.mock.calls[0]
91+
92+
// Ensure Content-Type remains application/json
93+
expect(init.headers).toEqual(
94+
expect.objectContaining({
95+
"Content-Type": "application/json",
96+
}),
97+
)
98+
})
99+
})

0 commit comments

Comments
 (0)