feat: remove the responsibility of running install and start script from agentapi module
This commit is contained in:
parent
80f47d09dd
commit
4459d39529
@ -16,41 +16,21 @@ The AgentAPI module is a building block for modules that need to run an AgentAPI
|
|||||||
```tf
|
```tf
|
||||||
module "agentapi" {
|
module "agentapi" {
|
||||||
source = "registry.coder.com/coder/agentapi/coder"
|
source = "registry.coder.com/coder/agentapi/coder"
|
||||||
version = "3.0.0"
|
version = "4.0.0"
|
||||||
|
|
||||||
agent_id = var.agent_id
|
agent_id = var.agent_id
|
||||||
web_app_slug = local.app_slug
|
web_app_slug = local.app_slug
|
||||||
web_app_order = var.order
|
web_app_order = var.order
|
||||||
web_app_group = var.group
|
web_app_group = var.group
|
||||||
web_app_icon = var.icon
|
web_app_icon = var.icon
|
||||||
web_app_display_name = "Goose"
|
web_app_display_name = "ClaudeCode"
|
||||||
cli_app_slug = "goose-cli"
|
cli_app_slug = "claude-cli"
|
||||||
cli_app_display_name = "Goose CLI"
|
cli_app_display_name = "Claude CLI"
|
||||||
module_dir_name = local.module_dir_name
|
module_dir_name = local.module_dir_name
|
||||||
agentapi_server_type = "claude"
|
|
||||||
install_agentapi = var.install_agentapi
|
install_agentapi = var.install_agentapi
|
||||||
pre_install_script = var.pre_install_script
|
agentapi_server_type = "claude"
|
||||||
post_install_script = var.post_install_script
|
agentapi_term_width = 67
|
||||||
start_script = local.start_script
|
agentapi_term_height = 1190
|
||||||
agentapi_server_type = "claude" # required
|
|
||||||
agentapi_term_width = 67 # default: 67
|
|
||||||
agentapi_term_height = 1190 # default: 1190
|
|
||||||
agentapi_initial_prompt = "You are a helpful assistant." # optional
|
|
||||||
install_script = <<-EOT
|
|
||||||
#!/bin/bash
|
|
||||||
set -o errexit
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
echo -n '${base64encode(local.install_script)}' | base64 -d > /tmp/install.sh
|
|
||||||
chmod +x /tmp/install.sh
|
|
||||||
|
|
||||||
ARG_PROVIDER='${var.goose_provider}' \
|
|
||||||
ARG_MODEL='${var.goose_model}' \
|
|
||||||
ARG_GOOSE_CONFIG="$(echo -n '${base64encode(local.combined_extensions)}' | base64 -d)" \
|
|
||||||
ARG_INSTALL='${var.install_goose}' \
|
|
||||||
ARG_GOOSE_VERSION='${var.goose_version}' \
|
|
||||||
/tmp/install.sh
|
|
||||||
EOT
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -71,11 +51,11 @@ module "agentapi" {
|
|||||||
|
|
||||||
For a complete example of how to use this module, see the [Goose module](https://github.com/coder/registry/blob/main/registry/coder/modules/goose/main.tf).
|
For a complete example of how to use this module, see the [Goose module](https://github.com/coder/registry/blob/main/registry/coder/modules/goose/main.tf).
|
||||||
|
|
||||||
### Start script behavior
|
### agent-command.sh
|
||||||
|
|
||||||
The `start_script` should write the agent command to `$module_path/agent-command.sh` instead of starting the AgentAPI server directly.
|
The calling module must create an executable script at `$HOME/{module_dir_name}/agent-command.sh` before this module's script runs. This script should contain the command to start your AI agent.
|
||||||
|
|
||||||
Example start script:
|
Example:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
@ -85,6 +65,6 @@ cat > "$module_path/agent-command.sh" << EOF
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
my-agent-command --my-agent-flags
|
my-agent-command --my-agent-flags
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
chmod +x "$module_path/agent-command.sh"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The AgentAPI module will run this script with the agentapi server.
|
||||||
|
|||||||
@ -60,7 +60,6 @@ const setup = async (props?: SetupProps): Promise<{ id: string }> => {
|
|||||||
agentapi_version: "latest",
|
agentapi_version: "latest",
|
||||||
agentapi_server_type: "claude",
|
agentapi_server_type: "claude",
|
||||||
module_dir_name: moduleDirName,
|
module_dir_name: moduleDirName,
|
||||||
start_script: await loadTestFile(import.meta.dir, "agentapi-start.sh"),
|
|
||||||
folder: projectDir,
|
folder: projectDir,
|
||||||
...props?.moduleVariables,
|
...props?.moduleVariables,
|
||||||
},
|
},
|
||||||
@ -69,11 +68,23 @@ const setup = async (props?: SetupProps): Promise<{ id: string }> => {
|
|||||||
skipAgentAPIMock: props?.skipAgentAPIMock,
|
skipAgentAPIMock: props?.skipAgentAPIMock,
|
||||||
moduleDir: import.meta.dir,
|
moduleDir: import.meta.dir,
|
||||||
});
|
});
|
||||||
|
// Create the ai agent mock binary
|
||||||
await writeExecutable({
|
await writeExecutable({
|
||||||
containerId: id,
|
containerId: id,
|
||||||
filePath: "/usr/bin/aiagent",
|
filePath: "/usr/bin/aiagent",
|
||||||
content: await loadTestFile(import.meta.dir, "ai-agent-mock.js"),
|
content: await loadTestFile(import.meta.dir, "ai-agent-mock.js"),
|
||||||
});
|
});
|
||||||
|
// Create the agent-command.sh script that the module expects
|
||||||
|
await execContainer(id, [
|
||||||
|
"bash",
|
||||||
|
"-c",
|
||||||
|
`mkdir -p /home/coder/${moduleDirName}`,
|
||||||
|
]);
|
||||||
|
await writeExecutable({
|
||||||
|
containerId: id,
|
||||||
|
filePath: `/home/coder/${moduleDirName}/agent-command.sh`,
|
||||||
|
content: "#!/bin/bash\nexec aiagent",
|
||||||
|
});
|
||||||
return { id };
|
return { id };
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -105,36 +116,6 @@ describe("agentapi", async () => {
|
|||||||
await expectAgentAPIStarted(id, 3827);
|
await expectAgentAPIStarted(id, 3827);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("pre-post-install-scripts", async () => {
|
|
||||||
const { id } = await setup({
|
|
||||||
moduleVariables: {
|
|
||||||
pre_install_script: `#!/bin/bash\necho "pre-install"`,
|
|
||||||
install_script: `#!/bin/bash\necho "install"`,
|
|
||||||
post_install_script: `#!/bin/bash\necho "post-install"`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await execModuleScript(id);
|
|
||||||
await expectAgentAPIStarted(id);
|
|
||||||
|
|
||||||
const preInstallLog = await readFileContainer(
|
|
||||||
id,
|
|
||||||
`/home/coder/${moduleDirName}/pre_install.log`,
|
|
||||||
);
|
|
||||||
const installLog = await readFileContainer(
|
|
||||||
id,
|
|
||||||
`/home/coder/${moduleDirName}/install.log`,
|
|
||||||
);
|
|
||||||
const postInstallLog = await readFileContainer(
|
|
||||||
id,
|
|
||||||
`/home/coder/${moduleDirName}/post_install.log`,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(preInstallLog).toContain("pre-install");
|
|
||||||
expect(installLog).toContain("install");
|
|
||||||
expect(postInstallLog).toContain("post-install");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("install-agentapi", async () => {
|
test("install-agentapi", async () => {
|
||||||
const { id } = await setup({ skipAgentAPIMock: true });
|
const { id } = await setup({ skipAgentAPIMock: true });
|
||||||
|
|
||||||
@ -161,12 +142,12 @@ describe("agentapi", async () => {
|
|||||||
expect(respModuleScript.exitCode).toBe(0);
|
expect(respModuleScript.exitCode).toBe(0);
|
||||||
|
|
||||||
await expectAgentAPIStarted(id);
|
await expectAgentAPIStarted(id);
|
||||||
const agentApiStartLog = await readFileContainer(
|
const agentApiMockLog = await readFileContainer(
|
||||||
id,
|
id,
|
||||||
"/home/coder/test-agentapi-start.log",
|
"/home/coder/agentapi-mock.log",
|
||||||
);
|
);
|
||||||
expect(agentApiStartLog).toContain(
|
expect(agentApiMockLog).toContain(
|
||||||
"Using AGENTAPI_CHAT_BASE_PATH: /@default/default.foo/apps/agentapi-web/chat",
|
"AGENTAPI_CHAT_BASE_PATH: /@default/default.foo/apps/agentapi-web/chat",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -87,29 +87,6 @@ variable "cli_app_slug" {
|
|||||||
description = "The slug of the CLI workspace app."
|
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 "install_agentapi" {
|
variable "install_agentapi" {
|
||||||
type = bool
|
type = bool
|
||||||
description = "Whether to install AgentAPI."
|
description = "Whether to install AgentAPI."
|
||||||
@ -191,11 +168,7 @@ variable "module_dir_name" {
|
|||||||
locals {
|
locals {
|
||||||
# we always trim the slash for consistency
|
# we always trim the slash for consistency
|
||||||
workdir = trimsuffix(var.folder, "/")
|
workdir = trimsuffix(var.folder, "/")
|
||||||
encoded_pre_install_script = var.pre_install_script != null ? base64encode(var.pre_install_script) : ""
|
|
||||||
encoded_install_script = var.install_script != null ? base64encode(var.install_script) : ""
|
|
||||||
encoded_post_install_script = var.post_install_script != null ? base64encode(var.post_install_script) : ""
|
|
||||||
encoded_initial_prompt = var.agentapi_initial_prompt != null ? base64encode(var.agentapi_initial_prompt) : ""
|
encoded_initial_prompt = var.agentapi_initial_prompt != null ? base64encode(var.agentapi_initial_prompt) : ""
|
||||||
agentapi_start_script_b64 = base64encode(var.start_script)
|
|
||||||
agentapi_wait_for_start_script_b64 = base64encode(file("${path.module}/scripts/agentapi-wait-for-start.sh"))
|
agentapi_wait_for_start_script_b64 = base64encode(file("${path.module}/scripts/agentapi-wait-for-start.sh"))
|
||||||
// Chat base path is only set if not using a subdomain.
|
// Chat base path is only set if not using a subdomain.
|
||||||
// NOTE:
|
// NOTE:
|
||||||
@ -210,7 +183,7 @@ locals {
|
|||||||
|
|
||||||
resource "coder_script" "agentapi" {
|
resource "coder_script" "agentapi" {
|
||||||
agent_id = var.agent_id
|
agent_id = var.agent_id
|
||||||
display_name = "Install and start AgentAPI"
|
display_name = "Start AgentAPI"
|
||||||
icon = var.web_app_icon
|
icon = var.web_app_icon
|
||||||
script = <<-EOT
|
script = <<-EOT
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
@ -222,13 +195,9 @@ resource "coder_script" "agentapi" {
|
|||||||
|
|
||||||
ARG_MODULE_DIR_NAME='${var.module_dir_name}' \
|
ARG_MODULE_DIR_NAME='${var.module_dir_name}' \
|
||||||
ARG_WORKDIR="$(echo -n '${base64encode(local.workdir)}' | base64 -d)" \
|
ARG_WORKDIR="$(echo -n '${base64encode(local.workdir)}' | base64 -d)" \
|
||||||
ARG_PRE_INSTALL_SCRIPT="$(echo -n '${local.encoded_pre_install_script}' | base64 -d)" \
|
|
||||||
ARG_INSTALL_SCRIPT="$(echo -n '${local.encoded_install_script}' | base64 -d)" \
|
|
||||||
ARG_INSTALL_AGENTAPI='${var.install_agentapi}' \
|
ARG_INSTALL_AGENTAPI='${var.install_agentapi}' \
|
||||||
ARG_AGENTAPI_VERSION='${var.agentapi_version}' \
|
ARG_AGENTAPI_VERSION='${var.agentapi_version}' \
|
||||||
ARG_START_SCRIPT="$(echo -n '${local.agentapi_start_script_b64}' | base64 -d)" \
|
|
||||||
ARG_WAIT_FOR_START_SCRIPT="$(echo -n '${local.agentapi_wait_for_start_script_b64}' | base64 -d)" \
|
ARG_WAIT_FOR_START_SCRIPT="$(echo -n '${local.agentapi_wait_for_start_script_b64}' | base64 -d)" \
|
||||||
ARG_POST_INSTALL_SCRIPT="$(echo -n '${local.encoded_post_install_script}' | base64 -d)" \
|
|
||||||
ARG_AGENTAPI_PORT='${var.agentapi_port}' \
|
ARG_AGENTAPI_PORT='${var.agentapi_port}' \
|
||||||
ARG_AGENTAPI_SERVER_TYPE='${var.agentapi_server_type}' \
|
ARG_AGENTAPI_SERVER_TYPE='${var.agentapi_server_type}' \
|
||||||
ARG_AGENTAPI_TERM_WIDTH='${var.agentapi_term_width}' \
|
ARG_AGENTAPI_TERM_WIDTH='${var.agentapi_term_width}' \
|
||||||
|
|||||||
@ -5,13 +5,9 @@ set -x
|
|||||||
set -o nounset
|
set -o nounset
|
||||||
MODULE_DIR_NAME="$ARG_MODULE_DIR_NAME"
|
MODULE_DIR_NAME="$ARG_MODULE_DIR_NAME"
|
||||||
WORKDIR="$ARG_WORKDIR"
|
WORKDIR="$ARG_WORKDIR"
|
||||||
PRE_INSTALL_SCRIPT="$ARG_PRE_INSTALL_SCRIPT"
|
|
||||||
INSTALL_SCRIPT="$ARG_INSTALL_SCRIPT"
|
|
||||||
INSTALL_AGENTAPI="$ARG_INSTALL_AGENTAPI"
|
INSTALL_AGENTAPI="$ARG_INSTALL_AGENTAPI"
|
||||||
AGENTAPI_VERSION="$ARG_AGENTAPI_VERSION"
|
AGENTAPI_VERSION="$ARG_AGENTAPI_VERSION"
|
||||||
START_SCRIPT="$ARG_START_SCRIPT"
|
|
||||||
WAIT_FOR_START_SCRIPT="$ARG_WAIT_FOR_START_SCRIPT"
|
WAIT_FOR_START_SCRIPT="$ARG_WAIT_FOR_START_SCRIPT"
|
||||||
POST_INSTALL_SCRIPT="$ARG_POST_INSTALL_SCRIPT"
|
|
||||||
AGENTAPI_PORT="$ARG_AGENTAPI_PORT"
|
AGENTAPI_PORT="$ARG_AGENTAPI_PORT"
|
||||||
AGENTAPI_SERVER_TYPE="$ARG_AGENTAPI_SERVER_TYPE"
|
AGENTAPI_SERVER_TYPE="$ARG_AGENTAPI_SERVER_TYPE"
|
||||||
AGENTAPI_TERM_WIDTH="$ARG_AGENTAPI_TERM_WIDTH"
|
AGENTAPI_TERM_WIDTH="$ARG_AGENTAPI_TERM_WIDTH"
|
||||||
@ -42,17 +38,6 @@ if [ ! -d "${WORKDIR}" ]; then
|
|||||||
mkdir -p "${WORKDIR}"
|
mkdir -p "${WORKDIR}"
|
||||||
echo "Folder created successfully."
|
echo "Folder created successfully."
|
||||||
fi
|
fi
|
||||||
if [ -n "${PRE_INSTALL_SCRIPT}" ]; then
|
|
||||||
echo "Running pre-install script..."
|
|
||||||
echo -n "${PRE_INSTALL_SCRIPT}" > "$module_path/pre_install.sh"
|
|
||||||
chmod +x "$module_path/pre_install.sh"
|
|
||||||
"$module_path/pre_install.sh" 2>&1 | tee "$module_path/pre_install.log"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Running install script..."
|
|
||||||
echo -n "${INSTALL_SCRIPT}" > "$module_path/install.sh"
|
|
||||||
chmod +x "$module_path/install.sh"
|
|
||||||
"$module_path/install.sh" 2>&1 | tee "$module_path/install.log"
|
|
||||||
|
|
||||||
# Install AgentAPI if enabled
|
# Install AgentAPI if enabled
|
||||||
if [ "${INSTALL_AGENTAPI}" = "true" ]; then
|
if [ "${INSTALL_AGENTAPI}" = "true" ]; then
|
||||||
@ -90,18 +75,9 @@ if ! command_exists agentapi; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -n "${START_SCRIPT}" > "$module_path/scripts/agentapi-start.sh"
|
|
||||||
echo -n "${WAIT_FOR_START_SCRIPT}" > "$module_path/scripts/agentapi-wait-for-start.sh"
|
echo -n "${WAIT_FOR_START_SCRIPT}" > "$module_path/scripts/agentapi-wait-for-start.sh"
|
||||||
chmod +x "$module_path/scripts/agentapi-start.sh"
|
|
||||||
chmod +x "$module_path/scripts/agentapi-wait-for-start.sh"
|
chmod +x "$module_path/scripts/agentapi-wait-for-start.sh"
|
||||||
|
|
||||||
if [ -n "${POST_INSTALL_SCRIPT}" ]; then
|
|
||||||
echo "Running post-install script..."
|
|
||||||
echo -n "${POST_INSTALL_SCRIPT}" > "$module_path/post_install.sh"
|
|
||||||
chmod +x "$module_path/post_install.sh"
|
|
||||||
"$module_path/post_install.sh" 2>&1 | tee "$module_path/post_install.log"
|
|
||||||
fi
|
|
||||||
|
|
||||||
export LANG=en_US.UTF-8
|
export LANG=en_US.UTF-8
|
||||||
export LC_ALL=en_US.UTF-8
|
export LC_ALL=en_US.UTF-8
|
||||||
|
|
||||||
@ -111,9 +87,6 @@ export AGENTAPI_CHAT_BASE_PATH="${AGENTAPI_CHAT_BASE_PATH:-}"
|
|||||||
# Disable host header check since AgentAPI is proxied by Coder (which does its own validation)
|
# Disable host header check since AgentAPI is proxied by Coder (which does its own validation)
|
||||||
export AGENTAPI_ALLOWED_HOSTS="*"
|
export AGENTAPI_ALLOWED_HOSTS="*"
|
||||||
|
|
||||||
# Call agentapi-start.sh to write agent-command.sh
|
|
||||||
"$module_path/scripts/agentapi-start.sh" &> "$module_path/agentapi-start.log"
|
|
||||||
|
|
||||||
# Build agentapi server command arguments
|
# Build agentapi server command arguments
|
||||||
ARGS=(
|
ARGS=(
|
||||||
"server"
|
"server"
|
||||||
|
|||||||
@ -9,7 +9,7 @@ const port = portIdx ? args[portIdx] : 3284;
|
|||||||
console.log(`starting server on port ${port}`);
|
console.log(`starting server on port ${port}`);
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
"/home/coder/agentapi-mock.log",
|
"/home/coder/agentapi-mock.log",
|
||||||
`AGENTAPI_ALLOWED_HOSTS: ${process.env.AGENTAPI_ALLOWED_HOSTS}`,
|
`AGENTAPI_ALLOWED_HOSTS: ${process.env.AGENTAPI_ALLOWED_HOSTS}\nAGENTAPI_CHAT_BASE_PATH: ${process.env.AGENTAPI_CHAT_BASE_PATH || "not set"}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
http
|
http
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -o errexit
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
module_path="$HOME/.agentapi-module"
|
|
||||||
|
|
||||||
# Write the agent command to agent-command.sh
|
|
||||||
cat > "$module_path/agent-command.sh" << 'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
exec bash -c aiagent
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x "$module_path/agent-command.sh"
|
|
||||||
|
|
||||||
echo "Agent command written to $module_path/agent-command.sh"
|
|
||||||
|
|
||||||
echo "Using AGENTAPI_CHAT_BASE_PATH: ${AGENTAPI_CHAT_BASE_PATH:-not set}" >> /home/coder/test-agentapi-start.log
|
|
||||||
Loading…
x
Reference in New Issue
Block a user