Skip to content

Commit 90a607f

Browse files
authored
Merge branch 'main' into cte/roo-code-api
2 parents 0a03c88 + 13be66f commit 90a607f

File tree

21 files changed

+1909
-224
lines changed

21 files changed

+1909
-224
lines changed

README.md

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -115,37 +115,40 @@ Make Roo Code work your way with:
115115
## Local Setup & Development
116116

117117
1. **Clone** the repo:
118-
```bash
119-
git clone https://github.com/RooVetGit/Roo-Code.git
120-
```
118+
119+
```sh
120+
git clone https://github.com/RooVetGit/Roo-Code.git
121+
```
122+
121123
2. **Install dependencies**:
122-
```bash
123-
npm run install:all
124-
```
125-
126-
if that fails, try:
127-
```bash
128-
npm run install:ci
129-
```
130-
131-
3. **Build** the extension:
132-
```bash
133-
npm run build
134-
```
135-
- A `.vsix` file will appear in the `bin/` directory.
136-
4. **Install** the `.vsix` manually if desired:
137-
```bash
138-
code --install-extension bin/roo-code-4.0.0.vsix
139-
```
140-
5. **Start the webview (Vite/React app with HMR)**:
141-
```bash
142-
npm run dev
143-
```
144-
6. **Debug**:
145-
- Press `F5` (or **Run****Start Debugging**) in VSCode to open a new session with Roo Code loaded.
124+
125+
```sh
126+
npm run install:all
127+
```
128+
129+
3. **Start the webview (Vite/React app with HMR)**:
130+
131+
```sh
132+
npm run dev
133+
```
134+
135+
4. **Debug**:
136+
Press `F5` (or **Run****Start Debugging**) in VSCode to open a new session with Roo Code loaded.
146137

147138
Changes to the webview will appear immediately. Changes to the core extension will require a restart of the extension host.
148139

140+
Alternatively you can build a .vsix and install it directly in VSCode:
141+
142+
```sh
143+
npm run build
144+
```
145+
146+
A `.vsix` file will appear in the `bin/` directory which can be installed with:
147+
148+
```sh
149+
code --install-extension bin/roo-cline-<version>.vsix
150+
```
151+
149152
We use [changesets](https://github.com/changesets/changesets) for versioning and publishing. Check our `CHANGELOG.md` for release notes.
150153

151154
---

src/activate/humanRelay.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Callback mapping of human relay response.
2+
const humanRelayCallbacks = new Map<string, (response: string | undefined) => void>()
3+
4+
/**
5+
* Register a callback function for human relay response.
6+
* @param requestId
7+
* @param callback
8+
*/
9+
export const registerHumanRelayCallback = (requestId: string, callback: (response: string | undefined) => void) =>
10+
humanRelayCallbacks.set(requestId, callback)
11+
12+
export const unregisterHumanRelayCallback = (requestId: string) => humanRelayCallbacks.delete(requestId)
13+
14+
export const handleHumanRelayResponse = (response: { requestId: string; text?: string; cancelled?: boolean }) => {
15+
const callback = humanRelayCallbacks.get(response.requestId)
16+
17+
if (callback) {
18+
if (response.cancelled) {
19+
callback(undefined)
20+
} else {
21+
callback(response.text)
22+
}
23+
24+
humanRelayCallbacks.delete(response.requestId)
25+
}
26+
}

src/activate/registerCommands.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import delay from "delay"
33

44
import { ClineProvider } from "../core/webview/ClineProvider"
55

6+
import { registerHumanRelayCallback, unregisterHumanRelayCallback, handleHumanRelayResponse } from "./humanRelay"
7+
68
// Store panel references in both modes
79
let sidebarPanel: vscode.WebviewView | undefined = undefined
810
let tabPanel: vscode.WebviewPanel | undefined = undefined
@@ -43,22 +45,6 @@ export const registerCommands = (options: RegisterCommandOptions) => {
4345
for (const [command, callback] of Object.entries(getCommandsMap(options))) {
4446
context.subscriptions.push(vscode.commands.registerCommand(command, callback))
4547
}
46-
47-
// Human Relay Dialog Command
48-
context.subscriptions.push(
49-
vscode.commands.registerCommand(
50-
"roo-cline.showHumanRelayDialog",
51-
(params: { requestId: string; promptText: string }) => {
52-
if (getPanel()) {
53-
getPanel()?.webview.postMessage({
54-
type: "showHumanRelayDialog",
55-
requestId: params.requestId,
56-
promptText: params.promptText,
57-
})
58-
}
59-
},
60-
),
61-
)
6248
}
6349

6450
const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOptions) => {
@@ -85,6 +71,20 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt
8571
"roo-cline.helpButtonClicked": () => {
8672
vscode.env.openExternal(vscode.Uri.parse("https://docs.roocode.com"))
8773
},
74+
"roo-cline.showHumanRelayDialog": (params: { requestId: string; promptText: string }) => {
75+
const panel = getPanel()
76+
77+
if (panel) {
78+
panel?.webview.postMessage({
79+
type: "showHumanRelayDialog",
80+
requestId: params.requestId,
81+
promptText: params.promptText,
82+
})
83+
}
84+
},
85+
"roo-cline.registerHumanRelayCallback": registerHumanRelayCallback,
86+
"roo-cline.unregisterHumanRelayCallback": unregisterHumanRelayCallback,
87+
"roo-cline.handleHumanRelayResponse": handleHumanRelayResponse,
8888
}
8989
}
9090

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { AwsBedrockHandler } from "../bedrock"
2+
import { ApiHandlerOptions } from "../../../shared/api"
3+
4+
// Mock the AWS SDK
5+
jest.mock("@aws-sdk/client-bedrock-runtime", () => {
6+
const mockSend = jest.fn().mockImplementation(() => {
7+
return Promise.resolve({
8+
output: new TextEncoder().encode(JSON.stringify({ content: "Test response" })),
9+
})
10+
})
11+
12+
return {
13+
BedrockRuntimeClient: jest.fn().mockImplementation(() => ({
14+
send: mockSend,
15+
config: {
16+
region: "us-east-1",
17+
},
18+
})),
19+
ConverseCommand: jest.fn(),
20+
ConverseStreamCommand: jest.fn(),
21+
}
22+
})
23+
24+
describe("AwsBedrockHandler with custom ARN", () => {
25+
const mockOptions: ApiHandlerOptions = {
26+
apiModelId: "custom-arn",
27+
awsCustomArn: "arn:aws:bedrock:us-east-1:123456789012:foundation-model/anthropic.claude-3-sonnet-20240229-v1:0",
28+
awsRegion: "us-east-1",
29+
}
30+
31+
it("should use the custom ARN as the model ID", async () => {
32+
const handler = new AwsBedrockHandler(mockOptions)
33+
const model = handler.getModel()
34+
35+
expect(model.id).toBe(mockOptions.awsCustomArn)
36+
expect(model.info).toHaveProperty("maxTokens")
37+
expect(model.info).toHaveProperty("contextWindow")
38+
expect(model.info).toHaveProperty("supportsPromptCache")
39+
})
40+
41+
it("should extract region from ARN and use it for client configuration", () => {
42+
// Test with matching region
43+
const handler1 = new AwsBedrockHandler(mockOptions)
44+
expect((handler1 as any).client.config.region).toBe("us-east-1")
45+
46+
// Test with mismatched region
47+
const mismatchOptions = {
48+
...mockOptions,
49+
awsRegion: "us-west-2",
50+
}
51+
const handler2 = new AwsBedrockHandler(mismatchOptions)
52+
// Should use the ARN region, not the provided region
53+
expect((handler2 as any).client.config.region).toBe("us-east-1")
54+
})
55+
56+
it("should validate ARN format", async () => {
57+
// Invalid ARN format
58+
const invalidOptions = {
59+
...mockOptions,
60+
awsCustomArn: "invalid-arn-format",
61+
}
62+
63+
const handler = new AwsBedrockHandler(invalidOptions)
64+
65+
// completePrompt should throw an error for invalid ARN
66+
await expect(handler.completePrompt("test")).rejects.toThrow("Invalid ARN format")
67+
})
68+
69+
it("should complete a prompt successfully with valid ARN", async () => {
70+
const handler = new AwsBedrockHandler(mockOptions)
71+
const response = await handler.completePrompt("test prompt")
72+
73+
expect(response).toBe("Test response")
74+
})
75+
})

src/api/providers/__tests__/bedrock.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,5 +315,34 @@ describe("AwsBedrockHandler", () => {
315315
expect(modelInfo.info.maxTokens).toBe(5000)
316316
expect(modelInfo.info.contextWindow).toBe(128_000)
317317
})
318+
319+
it("should use custom ARN when provided", () => {
320+
const customArnHandler = new AwsBedrockHandler({
321+
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
322+
awsAccessKey: "test-access-key",
323+
awsSecretKey: "test-secret-key",
324+
awsRegion: "us-east-1",
325+
awsCustomArn: "arn:aws:bedrock:us-east-1::foundation-model/custom-model",
326+
})
327+
const modelInfo = customArnHandler.getModel()
328+
expect(modelInfo.id).toBe("arn:aws:bedrock:us-east-1::foundation-model/custom-model")
329+
expect(modelInfo.info.maxTokens).toBe(4096)
330+
expect(modelInfo.info.contextWindow).toBe(128_000)
331+
expect(modelInfo.info.supportsPromptCache).toBe(false)
332+
})
333+
334+
it("should use default model when custom-arn is selected but no ARN is provided", () => {
335+
const customArnHandler = new AwsBedrockHandler({
336+
apiModelId: "custom-arn",
337+
awsAccessKey: "test-access-key",
338+
awsSecretKey: "test-secret-key",
339+
awsRegion: "us-east-1",
340+
// No awsCustomArn provided
341+
})
342+
const modelInfo = customArnHandler.getModel()
343+
// Should fall back to default model
344+
expect(modelInfo.id).not.toBe("custom-arn")
345+
expect(modelInfo.info).toBeDefined()
346+
})
318347
})
319348
})

0 commit comments

Comments
 (0)