Skip to content

Commit 545a245

Browse files
Harsh9485matifaliDevelopmentCats
authored
feat: Sourcegraph Amp module (#257)
Closes #238 /claim #238 ## Description Video - https://www.loom.com/share/59e80a7fa3e54973bb0318132bc849a7?sid=4900077a-6fdb-4760-978c-9ad2e2daa9d8 <img width="1365" height="599" alt="Screenshot 2025-08-02 164234" src="https://github.com/user-attachments/assets/56ec7dc3-bc41-4976-9b78-3d6c011d80fe" /> <!-- Briefly describe what this PR does and why --> ## Type of Change - [x] New module - [ ] Bug fix - [ ] Feature/enhancement - [ ] Documentation - [ ] Other ## Module Information <!-- Delete this section if not applicable --> **Path:** `registry/harsh9485]/modules/sourcegraph_amp` **New version:** `v1.0.0` **Breaking change:** [ ] Yes [x] No ## Testing & Validation - [x] Tests pass (`bun test`) - [x] Code formatted (`bun run fmt`) - [x] Changes tested locally ## Related Issues <!-- Link related issues or write "None" if not applicable --> --------- Co-authored-by: Atif Ali <[email protected]> Co-authored-by: DevCats <[email protected]>
1 parent c554463 commit 545a245

File tree

7 files changed

+606
-0
lines changed

7 files changed

+606
-0
lines changed

.icons/sourcegraph-amp.svg

Lines changed: 5 additions & 0 deletions
Loading
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
display_name: Sourcegraph AMP
3+
icon: ../../../../.icons/sourcegraph-amp.svg
4+
description: Run Sourcegraph AMP CLI in your workspace with AgentAPI integration
5+
verified: false
6+
tags: [agent, sourcegraph, amp, ai, tasks]
7+
---
8+
9+
# Sourcegraph AMP CLI
10+
11+
Run [Sourcegraph AMP CLI](https://sourcegraph.com/amp) in your workspace to access Sourcegraph's AI-powered code search and analysis tools, with AgentAPI integration for seamless Coder Tasks support.
12+
13+
```tf
14+
module "sourcegraph_amp" {
15+
source = "registry.coder.com/coder-labs/sourcegraph_amp/coder"
16+
version = "1.0.0"
17+
agent_id = coder_agent.example.id
18+
sourcegraph_amp_api_key = var.sourcegraph_amp_api_key
19+
install_sourcegraph_amp = true
20+
agentapi_version = "latest"
21+
}
22+
```
23+
24+
## Prerequisites
25+
26+
- Include the [Coder Login](https://registry.coder.com/modules/coder-login/coder) module in your template
27+
- Node.js and npm are automatically installed (via NVM) if not already available
28+
29+
## Usage Example
30+
31+
```tf
32+
data "coder_parameter" "ai_prompt" {
33+
name = "AI Prompt"
34+
description = "Write an initial prompt for AMP to work on."
35+
type = "string"
36+
default = ""
37+
mutable = true
38+
39+
}
40+
41+
# Set system prompt for Sourcegraph Amp via environment variables
42+
resource "coder_agent" "main" {
43+
# ...
44+
env = {
45+
SOURCEGRAPH_AMP_SYSTEM_PROMPT = <<-EOT
46+
You are an AMP assistant that helps developers debug and write code efficiently.
47+
48+
Always log task status to Coder.
49+
EOT
50+
SOURCEGRAPH_AMP_TASK_PROMPT = data.coder_parameter.ai_prompt.value
51+
}
52+
}
53+
54+
variable "sourcegraph_amp_api_key" {
55+
type = string
56+
description = "Sourcegraph AMP API key"
57+
sensitive = true
58+
}
59+
60+
module "sourcegraph_amp" {
61+
count = data.coder_workspace.me.start_count
62+
source = "registry.coder.com/coder-labs/sourcegraph_amp/coder"
63+
version = "1.0.0"
64+
agent_id = coder_agent.example.id
65+
sourcegraph_amp_api_key = var.sourcegraph_amp_api_key # recommended for authenticated usage
66+
install_sourcegraph_amp = true
67+
}
68+
```
69+
70+
## How it Works
71+
72+
- **Install**: Installs Sourcegraph AMP CLI using npm (installs Node.js via NVM if required)
73+
- **Start**: Launches AMP CLI in the specified directory, wrapped with AgentAPI to enable tasks and AI interactions
74+
- **Environment Variables**: Sets `SOURCEGRAPH_AMP_API_KEY` and `SOURCEGRAPH_AMP_START_DIRECTORY` for the CLI execution
75+
76+
## Troubleshooting
77+
78+
- If `amp` is not found, ensure `install_sourcegraph_amp = true` and your API key is valid
79+
- Logs are written under `/home/coder/.sourcegraph-amp-module/` (`install.log`, `agentapi-start.log`) for debugging
80+
- If AgentAPI fails to start, verify that your container has network access and executable permissions for the scripts
81+
82+
> [!IMPORTANT]
83+
> For using **Coder Tasks** with Sourcegraph AMP, make sure to pass the `AI Prompt` parameter and set `sourcegraph_amp_api_key`.
84+
> This ensures task reporting and status updates work seamlessly.
85+
86+
## References
87+
88+
- [Sourcegraph AMP Documentation](https://ampcode.com/manual)
89+
- [AgentAPI Documentation](https://github.com/coder/agentapi)
90+
- [Coder AI Agents Guide](https://coder.com/docs/tutorials/ai-agents)
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import {
2+
test,
3+
afterEach,
4+
describe,
5+
setDefaultTimeout,
6+
beforeAll,
7+
expect,
8+
} from "bun:test";
9+
import { execContainer, readFileContainer, runTerraformInit } from "~test";
10+
import {
11+
loadTestFile,
12+
writeExecutable,
13+
setup as setupUtil,
14+
execModuleScript,
15+
expectAgentAPIStarted,
16+
} from "../../../coder/modules/agentapi/test-util";
17+
18+
let cleanupFunctions: (() => Promise<void>)[] = [];
19+
const registerCleanup = (cleanup: () => Promise<void>) => {
20+
cleanupFunctions.push(cleanup);
21+
};
22+
afterEach(async () => {
23+
const cleanupFnsCopy = cleanupFunctions.slice().reverse();
24+
cleanupFunctions = [];
25+
for (const cleanup of cleanupFnsCopy) {
26+
try {
27+
await cleanup();
28+
} catch (error) {
29+
console.error("Error during cleanup:", error);
30+
}
31+
}
32+
});
33+
34+
interface SetupProps {
35+
skipAgentAPIMock?: boolean;
36+
skipAmpMock?: boolean;
37+
moduleVariables?: Record<string, string>;
38+
agentapiMockScript?: string;
39+
}
40+
41+
const setup = async (props?: SetupProps): Promise<{ id: string }> => {
42+
const projectDir = "/home/coder/project";
43+
const { id } = await setupUtil({
44+
moduleDir: import.meta.dir,
45+
moduleVariables: {
46+
install_sourcegraph_amp: props?.skipAmpMock ? "true" : "false",
47+
install_agentapi: props?.skipAgentAPIMock ? "true" : "false",
48+
sourcegraph_amp_model: "test-model",
49+
...props?.moduleVariables,
50+
},
51+
registerCleanup,
52+
projectDir,
53+
skipAgentAPIMock: props?.skipAgentAPIMock,
54+
agentapiMockScript: props?.agentapiMockScript,
55+
});
56+
57+
// Place the AMP mock CLI binary inside the container
58+
if (!props?.skipAmpMock) {
59+
await writeExecutable({
60+
containerId: id,
61+
filePath: "/usr/bin/amp",
62+
content: await loadTestFile(`${import.meta.dir}`, "amp-mock.sh"),
63+
});
64+
}
65+
66+
return { id };
67+
};
68+
69+
setDefaultTimeout(60 * 1000);
70+
71+
describe("sourcegraph-amp", async () => {
72+
beforeAll(async () => {
73+
await runTerraformInit(import.meta.dir);
74+
});
75+
76+
test("happy-path", async () => {
77+
const { id } = await setup();
78+
await execModuleScript(id);
79+
await expectAgentAPIStarted(id);
80+
});
81+
82+
test("api-key", async () => {
83+
const apiKey = "test-api-key-123";
84+
const { id } = await setup({
85+
moduleVariables: {
86+
sourcegraph_amp_api_key: apiKey,
87+
},
88+
});
89+
await execModuleScript(id);
90+
const resp = await readFileContainer(
91+
id,
92+
"/home/coder/.sourcegraph-amp-module/agentapi-start.log",
93+
);
94+
expect(resp).toContain("sourcegraph_amp_api_key provided !");
95+
});
96+
97+
test("custom-folder", async () => {
98+
const folder = "/tmp/sourcegraph-amp-test";
99+
const { id } = await setup({
100+
moduleVariables: {
101+
folder,
102+
},
103+
});
104+
await execModuleScript(id);
105+
const resp = await readFileContainer(
106+
id,
107+
"/home/coder/.sourcegraph-amp-module/install.log",
108+
);
109+
expect(resp).toContain(folder);
110+
});
111+
112+
test("pre-post-install-scripts", async () => {
113+
const { id } = await setup({
114+
moduleVariables: {
115+
pre_install_script: "#!/bin/bash\necho 'pre-install-script'",
116+
post_install_script: "#!/bin/bash\necho 'post-install-script'",
117+
},
118+
});
119+
await execModuleScript(id);
120+
const preLog = await readFileContainer(
121+
id,
122+
"/home/coder/.sourcegraph-amp-module/pre_install.log",
123+
);
124+
expect(preLog).toContain("pre-install-script");
125+
const postLog = await readFileContainer(
126+
id,
127+
"/home/coder/.sourcegraph-amp-module/post_install.log",
128+
);
129+
expect(postLog).toContain("post-install-script");
130+
});
131+
132+
test("system-prompt", async () => {
133+
const prompt = "this is a system prompt for AMP";
134+
const { id } = await setup();
135+
await execModuleScript(id, {
136+
SOURCEGRAPH_AMP_SYSTEM_PROMPT: prompt,
137+
});
138+
const resp = await readFileContainer(
139+
id,
140+
"/home/coder/.sourcegraph-amp-module/SYSTEM_PROMPT.md",
141+
);
142+
expect(resp).toContain(prompt);
143+
});
144+
145+
test("task-prompt", async () => {
146+
const prompt = "this is a task prompt for AMP";
147+
const { id } = await setup();
148+
await execModuleScript(id, {
149+
SOURCEGRAPH_AMP_TASK_PROMPT: prompt,
150+
});
151+
const resp = await readFileContainer(
152+
id,
153+
"/home/coder/.sourcegraph-amp-module/agentapi-start.log",
154+
);
155+
expect(resp).toContain(`sourcegraph amp task prompt provided : ${prompt}`);
156+
});
157+
});

0 commit comments

Comments
 (0)