From 4bbc6d929e0a8090771750838d1eedea3e4fe222 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Fri, 6 Feb 2026 23:37:59 +0530 Subject: [PATCH] feat: move install and start script logic to agentapi via agent-helper --- registry/coder/modules/agentapi/main.test.ts | 69 +++++++++++++++++++- registry/coder/modules/agentapi/main.tf | 53 ++++++++++++++- 2 files changed, 119 insertions(+), 3 deletions(-) diff --git a/registry/coder/modules/agentapi/main.test.ts b/registry/coder/modules/agentapi/main.test.ts index b3db1687..e1efbbfb 100644 --- a/registry/coder/modules/agentapi/main.test.ts +++ b/registry/coder/modules/agentapi/main.test.ts @@ -6,7 +6,12 @@ import { setDefaultTimeout, beforeAll, } from "bun:test"; -import { execContainer, readFileContainer, runTerraformInit } from "~test"; +import { + execContainer, + readFileContainer, + runTerraformInit, + runTerraformApply, +} from "~test"; import { loadTestFile, writeExecutable, @@ -61,6 +66,10 @@ const setup = async (props?: SetupProps): Promise<{ id: string }> => { agent_name: "claude", module_dir_name: moduleDirName, folder: projectDir, + pre_install_script: "echo 'Pre-install'", + install_script: "echo 'Install'", + post_install_script: "echo 'Post-install'", + start_script: "echo 'Start'", ...props?.moduleVariables, }, registerCleanup, @@ -240,6 +249,64 @@ describe("agentapi", async () => { expect(agentApiStartLog).toContain("AGENTAPI_ALLOWED_HOSTS: *"); }); + test("enable-agentapi-false", async () => { + // Test that when enable_agentapi is false: + // 1. AgentAPI web app is not created + // 2. AgentAPI is not started + // 3. CLI app still works and uses agent-command.sh + const { id } = await setup({ + moduleVariables: { + enable_agentapi: "false", + cli_app: "true", + }, + }); + + const respModuleScript = await execModuleScript(id); + expect(respModuleScript.exitCode).toBe(0); + + // Verify agentapi is not running on the default port + const respCheck = await execContainer(id, [ + "bash", + "-c", + "curl -fs -o /dev/null http://localhost:3284/status || echo 'not running'", + ]); + expect(respCheck.stdout).toContain("not running"); + + // Verify agent-command.sh script exists and is executable + const respAgentCommand = await execContainer(id, [ + "bash", + "-c", + `test -x /home/coder/${moduleDirName}/agent-command.sh && echo 'exists'`, + ]); + expect(respAgentCommand.stdout).toContain("exists"); + }); + + test("task-app-id-output", async () => { + // Test that task_app_id output is null when enable_agentapi is false + const projectDir = "/home/coder/project"; + const state = await runTerraformApply(import.meta.dir, { + agent_id: "test-agent", + experiment_report_tasks: "true", + install_agentapi: "false", + web_app_display_name: "AgentAPI Web", + web_app_slug: "agentapi-web", + web_app_icon: "/icon/coder.svg", + cli_app_display_name: "AgentAPI CLI", + cli_app_slug: "agentapi-cli", + agentapi_version: "latest", + agent_name: "claude", + module_dir_name: moduleDirName, + folder: projectDir, + pre_install_script: "echo 'Pre-install'", + install_script: "echo 'Install'", + post_install_script: "echo 'Post-install'", + start_script: "echo 'Start'", + enable_agentapi: "false", + }); + + expect(state.outputs.task_app_id.value).toBeNull(); + }); + describe("shutdown script", async () => { const setupMocks = async ( containerId: string, diff --git a/registry/coder/modules/agentapi/main.tf b/registry/coder/modules/agentapi/main.tf index 877de2a2..e587a581 100644 --- a/registry/coder/modules/agentapi/main.tf +++ b/registry/coder/modules/agentapi/main.tf @@ -87,6 +87,35 @@ variable "cli_app_slug" { description = "The slug of the CLI workspace app." } +variable "pre_install_script" { + type = string + description = "Custom script to run before installing the agent used by AgentAPI." + default = null +} + +variable "install_script" { + type = string + description = "Script to install the agent used by AgentAPI." + default = "" +} + +variable "post_install_script" { + type = string + description = "Custom script to run after installing the agent used by AgentAPI." + default = null +} + +variable "start_script" { + type = string + description = "Script that starts AgentAPI." +} + +variable "enable_agentapi" { + type = bool + description = "Whether to enable AgentAPI. If false, AgentAPI will not be installed or started, and the web app will not be created." + default = true +} + variable "install_agentapi" { type = bool description = "Whether to install AgentAPI." @@ -182,9 +211,23 @@ locals { start_script_name = "${var.agent_name}-start_script" agentapi_main_script_name = "${var.agent_name}-main_script" + + module_dir_path = "$HOME/${var.module_dir_name}" +} + +module "agent-helper" { + source = "git::https://github.com/coder/registry.git//registry/coder/modules/agent-helper?ref=35C4n0r/feat-agent-helper-module" + agent_id = var.agent_id + agent_name = var.agent_name + module_dir_name = var.module_dir_name + pre_install_script = var.pre_install_script + install_script = var.install_script + post_install_script = var.post_install_script + start_script = var.start_script } resource "coder_script" "agentapi" { + count = var.enable_agentapi ? 1 : 0 agent_id = var.agent_id display_name = "Start AgentAPI" icon = var.web_app_icon @@ -219,6 +262,7 @@ resource "coder_script" "agentapi" { } resource "coder_script" "agentapi_shutdown" { + count = var.enable_agentapi ? 1 : 0 agent_id = var.agent_id display_name = "AgentAPI Shutdown" icon = var.web_app_icon @@ -238,6 +282,7 @@ resource "coder_script" "agentapi_shutdown" { } resource "coder_app" "agentapi_web" { + count = var.enable_agentapi ? 1 : 0 slug = var.web_app_slug display_name = var.web_app_display_name agent_id = var.agent_id @@ -253,7 +298,7 @@ resource "coder_app" "agentapi_web" { } } -resource "coder_app" "agentapi_cli" { +resource "coder_app" "agent_cli" { count = var.cli_app ? 1 : 0 slug = var.cli_app_slug @@ -266,7 +311,11 @@ resource "coder_app" "agentapi_cli" { export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8 + %{if var.enable_agentapi~} agentapi attach + %{else} + ${local.module_dir_path}/agent-command.sh + %{endif} EOT icon = var.cli_app_icon order = var.cli_app_order @@ -274,5 +323,5 @@ resource "coder_app" "agentapi_cli" { } output "task_app_id" { - value = coder_app.agentapi_web.id + value = var.enable_agentapi ? coder_app.agentapi_web[0].id : null }